@parall/daemon 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.
@@ -1,6 +1,6 @@
1
1
  {
2
- "version": "1.55.4",
3
- "built_at": "2026-08-15T12:55:26.423Z",
2
+ "version": "1.55.5",
3
+ "built_at": "2026-08-19T09:00:25.731Z",
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": "6480baf1924cccec2cfe8e93fecb5251f238de2c52b2b067e29875fa2b6f7db8",
20
- "size": 2948318
19
+ "sha256": "d8e29aebf550cf44b7c8f88b78ce87e9a65ed278e0c54226d99e84ea5646e430",
20
+ "size": 2957682
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": "a340c800280fd7522f1ae9b5082776b6bc23e4e2d7cbab21077e209753b015bc",
28
- "size": 2823377
27
+ "sha256": "f0ddfbcf097f1e337c1441f92c267b054fa1742cc8712d387ba71beb5748241f",
28
+ "size": 2833131
29
29
  },
30
30
  "parall-codex-agent.js": {
31
- "sha256": "3f9ceb215129568c250b0687739a55f8cf4643259d47654dcb2ed2288b29ad89",
32
- "size": 2855324
31
+ "sha256": "3cabe812d9db0d281b9962e1c086b377bb1d8fbd063f962450d0b0f1b1f4c56e",
32
+ "size": 2865078
33
33
  },
34
34
  "parall-daemon.js": {
35
- "sha256": "571b05da902ead03fb76f6b634a0850d50776bd0c8f1cbc3482c88356256865e",
36
- "size": 3014129
35
+ "sha256": "f808002af2072ee6e148e6c66145ee593a403e195d36501f6334c7a62e99083a",
36
+ "size": 3024616
37
37
  },
38
38
  "parall-openclaw-agent.js": {
39
39
  "sha256": "856a1c3a9ae0ffef8efe2481fa1171dbeb1d67cccb88616aa9bf16da96a69355",
40
40
  "size": 9923
41
41
  }
42
42
  },
43
- "signature": "NzZ4HzOlAb7a8+sumoAejzCnXub6F3oQO684Q5Mnsw+LyQs92GsrvHUy0GmcH8/Ft+ZQOiZX7BPpPnATAz/FDg=="
43
+ "signature": "z3Biqj/B7cQM1ouwkrPkezIlKPIoOCzqmHBhf9eXdB2nPGpZWFPumTFI0i845pHcg6MH398RHxHq9SIrHX6JCQ=="
44
44
  }
@@ -63533,6 +63533,16 @@ function browserViewerRequestOptions(command, opts) {
63533
63533
  };
63534
63534
  }
63535
63535
 
63536
+ // ts/sdk/dist/attachment-endpoints.js
63537
+ function attachmentEndpoints(apiBase) {
63538
+ return {
63539
+ UPLOAD_PRESIGN: (orgId) => `${apiBase}/orgs/${orgId}/upload/presign`,
63540
+ UPLOAD_COMPLETE: (orgId) => `${apiBase}/orgs/${orgId}/upload/complete`,
63541
+ UPLOAD_ABORT: (orgId) => `${apiBase}/orgs/${orgId}/upload/abort`,
63542
+ FILE: (id) => `${apiBase}/files/${id}`
63543
+ };
63544
+ }
63545
+
63536
63546
  // ts/sdk/dist/constants.js
63537
63547
  var API_BASE = "/api/v1";
63538
63548
  var WIKI_BASE = "/wiki/v1";
@@ -63605,9 +63615,7 @@ var ENDPOINTS = {
63605
63615
  MESSAGE_REACTIONS: (id) => `${API_BASE}/messages/${id}/reactions`,
63606
63616
  MESSAGE_REACTION: (id, emoji) => `${API_BASE}/messages/${id}/reactions/${encodeURIComponent(emoji)}`,
63607
63617
  // Upload (org-scoped)
63608
- UPLOAD_PRESIGN: (orgId) => `${API_BASE}/orgs/${orgId}/upload/presign`,
63609
- UPLOAD_COMPLETE: (orgId) => `${API_BASE}/orgs/${orgId}/upload/complete`,
63610
- FILE: (id) => `${API_BASE}/files/${id}`,
63618
+ ...attachmentEndpoints(API_BASE),
63611
63619
  // Approval requests (org-scoped)
63612
63620
  APPROVAL_REQUESTS: (orgId) => `${API_BASE}/orgs/${orgId}/approval-requests`,
63613
63621
  // Approvals (global)
@@ -63788,6 +63796,8 @@ var ENDPOINTS = {
63788
63796
  // backend router so `deleted` isn't captured as a {wikiId}; the SDK builder
63789
63797
  // is just a string.
63790
63798
  WIKIS_DELETED: (orgId) => `${WIKI_BASE}/orgs/${orgId}/wikis/deleted`,
63799
+ // Org-wide changeset listing across readable wikis (Working on tab).
63800
+ WIKI_ORG_CHANGESETS: (orgId) => `${WIKI_BASE}/orgs/${orgId}/wiki-changesets`,
63791
63801
  // Detail URL — also reused for DELETE (soft-delete) and `${WIKI}/restore`.
63792
63802
  WIKI: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}`,
63793
63803
  WIKI_RESTORE: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/restore`,
@@ -63817,6 +63827,10 @@ var ENDPOINTS = {
63817
63827
  // Wiki Path Restrictions (AFCS narrowing ACL — private subtrees)
63818
63828
  WIKI_RESTRICTIONS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/restrictions`,
63819
63829
  WIKI_RESTRICTION: (orgId, wikiId, restrictionId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/restrictions/${restrictionId}`,
63830
+ WIKI_ACCESS_POLICY: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/access-policy`,
63831
+ WIKI_ACCESS_POLICY_MEMBERS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/access-policy/members`,
63832
+ WIKI_MEMBERSHIP_SELF: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/membership/self`,
63833
+ WIKI_MEMBERS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/members`,
63820
63834
  WIKI_ACCESS_STATUS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/access-status`,
63821
63835
  WIKI_ACCESS_REQUESTS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/access-requests`,
63822
63836
  // Wiki History (commits, file commits, blame)
@@ -63937,6 +63951,19 @@ var ENDPOINTS = {
63937
63951
  ORG_EDGE_DEVICE_UNREGISTER: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/unregister`,
63938
63952
  ORG_EDGE_ONBOARDING: (orgId) => `/api/v1/orgs/${orgId}/edge/onboarding`,
63939
63953
  ORG_EDGE_PROFILES: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profiles`,
63954
+ ORG_EDGE_PROFILE_OPERATIONS: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profile-operations`,
63955
+ ORG_EDGE_PROFILE_OPERATION: (orgId, edgeId, operationId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profile-operations/${operationId}`,
63956
+ ORG_EDGE_PROFILE_OPERATION_CONFIRM: (orgId, edgeId, operationId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profile-operations/${operationId}/confirm`,
63957
+ ORG_BROWSER_ALIASES: (orgId) => `/api/v1/orgs/${orgId}/browser-aliases`,
63958
+ ORG_BROWSER_ALIAS: (orgId, aliasId) => `/api/v1/orgs/${orgId}/browser-aliases/${aliasId}`,
63959
+ ORG_BROWSER_ALIAS_READINESS_CHECKS: (orgId, aliasId) => `/api/v1/orgs/${orgId}/browser-aliases/${aliasId}/readiness-checks`,
63960
+ ORG_BROWSER_ALIAS_READINESS_CHECK: (orgId, aliasId, checkId) => `/api/v1/orgs/${orgId}/browser-aliases/${aliasId}/readiness-checks/${checkId}`,
63961
+ ORG_API_KEY_BROWSER_ALIAS_GRANTS: (orgId, keyId) => `/api/v1/orgs/${orgId}/api-keys/${keyId}/browser-alias-grants`,
63962
+ ORG_API_KEY_BROWSER_ALIAS_GRANT: (orgId, keyId, aliasId) => `/api/v1/orgs/${orgId}/api-keys/${keyId}/browser-alias-grants/${aliasId}`,
63963
+ ORG_MANAGED_ALIASES: (orgId) => `/api/v1/orgs/${orgId}/aliases`,
63964
+ ORG_MANAGED_ALIAS: (orgId, aliasName) => `/api/v1/orgs/${orgId}/aliases/${encodeURIComponent(aliasName)}`,
63965
+ ORG_BROWSER_ALIAS_EXECUTIONS: (orgId) => `/api/v1/orgs/${orgId}/executions`,
63966
+ ORG_BROWSER_ALIAS_EXECUTION: (orgId, requestId) => `/api/v1/orgs/${orgId}/executions/${encodeURIComponent(requestId)}`,
63940
63967
  // Per-profile egress proxy (hosted Cloud Profiles; manager-only, human-only).
63941
63968
  ORG_EDGE_PROFILE_PROXY: (orgId, edgeId, profileName) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profiles/${encodeURIComponent(profileName)}/proxy`,
63942
63969
  // Per-profile one-shot cookie seed (hosted Cloud Profiles; manager-only,
@@ -64196,8 +64223,44 @@ var WechatClient = class extends TaskLabelClient {
64196
64223
  }
64197
64224
  };
64198
64225
 
64226
+ // ts/sdk/dist/attachment-client.js
64227
+ var COMPLETION_RETRY_DELAYS_MS = [250, 750];
64228
+ function isRetryableCompletionError(error2) {
64229
+ if (!error2 || typeof error2 !== "object" || !("status" in error2))
64230
+ return false;
64231
+ const status = error2.status;
64232
+ return status === 0 || typeof status === "number" && status >= 500;
64233
+ }
64234
+ var AttachmentClient = class extends WechatClient {
64235
+ async getUploadPresignUrl(orgId, req) {
64236
+ return this.request("POST", ENDPOINTS.UPLOAD_PRESIGN(orgId), req);
64237
+ }
64238
+ async completeUpload(orgId, attachmentId, parts) {
64239
+ const body = {
64240
+ attachment_id: attachmentId,
64241
+ parts
64242
+ };
64243
+ for (let attempt = 0; ; attempt += 1) {
64244
+ try {
64245
+ return await this.request("POST", ENDPOINTS.UPLOAD_COMPLETE(orgId), body);
64246
+ } catch (error2) {
64247
+ const delay = COMPLETION_RETRY_DELAYS_MS[attempt];
64248
+ if (delay === void 0 || !isRetryableCompletionError(error2))
64249
+ throw error2;
64250
+ await new Promise((resolve2) => setTimeout(resolve2, delay));
64251
+ }
64252
+ }
64253
+ }
64254
+ async abortUpload(orgId, attachmentId) {
64255
+ return this.request("POST", ENDPOINTS.UPLOAD_ABORT(orgId), { attachment_id: attachmentId });
64256
+ }
64257
+ async getFileUrl(id, opts) {
64258
+ return this.request("GET", ENDPOINTS.FILE(id), void 0, opts?.download ? { download: true } : void 0);
64259
+ }
64260
+ };
64261
+
64199
64262
  // ts/sdk/dist/client.js
64200
- var ParallClient = class _ParallClient extends WechatClient {
64263
+ var ParallClient = class _ParallClient extends AttachmentClient {
64201
64264
  baseUrl;
64202
64265
  wikiBaseUrl;
64203
64266
  token;
@@ -64844,16 +64907,6 @@ var ParallClient = class _ParallClient extends WechatClient {
64844
64907
  const res = await this.request("GET", ENDPOINTS.MESSAGE_REACTIONS(messageId));
64845
64908
  return res.reactions;
64846
64909
  }
64847
- // ---- File Upload ----
64848
- async getUploadPresignUrl(orgId, req) {
64849
- return this.request("POST", ENDPOINTS.UPLOAD_PRESIGN(orgId), req);
64850
- }
64851
- async completeUpload(orgId, attachmentId) {
64852
- return this.request("POST", ENDPOINTS.UPLOAD_COMPLETE(orgId), { attachment_id: attachmentId });
64853
- }
64854
- async getFileUrl(id, opts) {
64855
- return this.request("GET", ENDPOINTS.FILE(id), void 0, opts?.download ? { download: true } : void 0);
64856
- }
64857
64910
  // ---- Approvals ----
64858
64911
  async getApproval(id) {
64859
64912
  return this.request("GET", ENDPOINTS.APPROVAL(id));
@@ -64861,8 +64914,14 @@ var ParallClient = class _ParallClient extends WechatClient {
64861
64914
  async requestApproval(orgId, req) {
64862
64915
  return this.request("POST", ENDPOINTS.APPROVAL_REQUESTS(orgId), req);
64863
64916
  }
64864
- async decideApproval(id, decision) {
64865
- return this.request("POST", ENDPOINTS.APPROVAL_DECIDE(id), { decision });
64917
+ async decideApproval(id, decision, reason) {
64918
+ if (decision === "approve" && reason?.trim()) {
64919
+ throw new ApiError(400, "Approval reason is only allowed for rejection decisions", "INVALID_DECISION_REASON");
64920
+ }
64921
+ return this.request("POST", ENDPOINTS.APPROVAL_DECIDE(id), {
64922
+ decision,
64923
+ ...decision === "reject" && reason !== void 0 ? { reason } : {}
64924
+ });
64866
64925
  }
64867
64926
  async cancelApproval(id) {
64868
64927
  return this.request("POST", ENDPOINTS.APPROVAL_CANCEL(id));
@@ -65695,6 +65754,17 @@ var ParallClient = class _ParallClient extends WechatClient {
65695
65754
  const res = await this.request("GET", ENDPOINTS.WIKI_CHANGESETS(orgId, wikiId));
65696
65755
  return res.data.map(normalizeWikiChangeset);
65697
65756
  }
65757
+ /** Org-wide changeset listing across every wiki the caller can read.
65758
+ * Server default (no `status`) is the pending set: proposed,
65759
+ * approval_pending, approved. */
65760
+ async getOrgWikiChangesets(orgId, opts) {
65761
+ const params = new URLSearchParams();
65762
+ for (const s of opts?.status ?? [])
65763
+ params.append("status", s);
65764
+ const qs = params.toString();
65765
+ const res = await this.request("GET", `${ENDPOINTS.WIKI_ORG_CHANGESETS(orgId)}${qs ? `?${qs}` : ""}`);
65766
+ return (res.data ?? []).map(normalizeWikiChangeset);
65767
+ }
65698
65768
  async getWikiChangeset(orgId, wikiId, changesetId) {
65699
65769
  return normalizeWikiChangeset(await this.request("GET", ENDPOINTS.WIKI_CHANGESET(orgId, wikiId, changesetId)));
65700
65770
  }
@@ -65783,6 +65853,35 @@ var ParallClient = class _ParallClient extends WechatClient {
65783
65853
  async getWikiAccessStatus(orgId, wikiId, path7) {
65784
65854
  return this.request("GET", ENDPOINTS.WIKI_ACCESS_STATUS(orgId, wikiId), void 0, path7 ? { path: path7 } : void 0);
65785
65855
  }
65856
+ // ---- Wiki membership projection (who-can-access, invites, join/leave) ----
65857
+ async getWikiAccessPolicy(orgId, wikiId, path7 = "") {
65858
+ return this.request("GET", ENDPOINTS.WIKI_ACCESS_POLICY(orgId, wikiId), void 0, path7 ? { path: path7 } : void 0);
65859
+ }
65860
+ async putWikiAccessPolicy(orgId, wikiId, policy) {
65861
+ return this.request("PUT", ENDPOINTS.WIKI_ACCESS_POLICY(orgId, wikiId), policy);
65862
+ }
65863
+ /** Add-only invite (viewer/editor); allowed for managers, and for editors
65864
+ * when the library enables editors_can_invite. */
65865
+ async addWikiMember(orgId, wikiId, subject, role) {
65866
+ await this.request("POST", ENDPOINTS.WIKI_ACCESS_POLICY_MEMBERS(orgId, wikiId), {
65867
+ subject,
65868
+ role
65869
+ });
65870
+ }
65871
+ /** Join a PUBLIC library as an explicit member (lands at the library's
65872
+ * default role). Restricted libraries answer 409 JOIN_REQUIRES_REQUEST —
65873
+ * go through createWikiAccessRequest instead. */
65874
+ async joinWiki(orgId, wikiId) {
65875
+ await this.request("POST", ENDPOINTS.WIKI_MEMBERSHIP_SELF(orgId, wikiId));
65876
+ }
65877
+ /** Remove the caller's explicit membership (team-granted membership stays). */
65878
+ async leaveWiki(orgId, wikiId) {
65879
+ await this.request("DELETE", ENDPOINTS.WIKI_MEMBERSHIP_SELF(orgId, wikiId));
65880
+ }
65881
+ async getWikiMembers(orgId, wikiId) {
65882
+ const res = await this.request("GET", ENDPOINTS.WIKI_MEMBERS(orgId, wikiId));
65883
+ return res.data ?? [];
65884
+ }
65786
65885
  async createWikiAccessRequest(orgId, wikiId, data2) {
65787
65886
  await this.request("POST", ENDPOINTS.WIKI_ACCESS_REQUESTS(orgId, wikiId), data2);
65788
65887
  }
@@ -66245,6 +66344,76 @@ var ParallClient = class _ParallClient extends WechatClient {
66245
66344
  async listEdgeProfiles(orgId, edgeId) {
66246
66345
  return this.request("GET", ENDPOINTS.ORG_EDGE_PROFILES(orgId, edgeId));
66247
66346
  }
66347
+ /** Start one durable Local BYOC Profile operation. Network-unknown callers
66348
+ * must retry with the same key or recover by operation id; a different body
66349
+ * under the same key is rejected. */
66350
+ async createEdgeProfileOperation(orgId, edgeId, request, idempotencyKey) {
66351
+ return this.request("POST", ENDPOINTS.ORG_EDGE_PROFILE_OPERATIONS(orgId, edgeId), request, void 0, false, { headers: { "Idempotency-Key": idempotencyKey } });
66352
+ }
66353
+ /** Strong-confirm the exact durable Delete impact. A changed impact returns
66354
+ * PROFILE_DELETE_IMPACT_CHANGED with a replacement receipt in
66355
+ * `ApiError.extras.details.operation`. */
66356
+ async confirmEdgeProfileOperation(orgId, edgeId, operationId, request) {
66357
+ return this.request("POST", ENDPOINTS.ORG_EDGE_PROFILE_OPERATION_CONFIRM(orgId, edgeId, operationId), request);
66358
+ }
66359
+ /** Sole read/recovery surface. The server may reconcile an already durable
66360
+ * dispatch/finalization while returning this receipt. */
66361
+ async getEdgeProfileOperation(orgId, edgeId, operationId) {
66362
+ return this.request("GET", ENDPOINTS.ORG_EDGE_PROFILE_OPERATION(orgId, edgeId, operationId));
66363
+ }
66364
+ /** Create and atomically materialize one Local BYOC Browser Alias. A replay
66365
+ * with the same idempotency key and body returns the original stable ccn_. */
66366
+ async createBrowserAlias(orgId, request) {
66367
+ return this.request("POST", ENDPOINTS.ORG_BROWSER_ALIASES(orgId), request);
66368
+ }
66369
+ async listBrowserAliases(orgId) {
66370
+ return this.request("GET", ENDPOINTS.ORG_BROWSER_ALIASES(orgId));
66371
+ }
66372
+ async getBrowserAlias(orgId, aliasId) {
66373
+ return this.request("GET", ENDPOINTS.ORG_BROWSER_ALIAS(orgId, aliasId));
66374
+ }
66375
+ async renameBrowserAlias(orgId, aliasId, request) {
66376
+ return this.request("PATCH", ENDPOINTS.ORG_BROWSER_ALIAS(orgId, aliasId), request);
66377
+ }
66378
+ async deleteBrowserAlias(orgId, aliasId, request) {
66379
+ return this.request("DELETE", ENDPOINTS.ORG_BROWSER_ALIAS(orgId, aliasId), request);
66380
+ }
66381
+ /** Start one durable readiness check. The key is carried as the standard
66382
+ * Idempotency-Key header; the request body is intentionally empty. */
66383
+ async createBrowserAliasReadinessCheck(orgId, aliasId, request) {
66384
+ return this.request("POST", ENDPOINTS.ORG_BROWSER_ALIAS_READINESS_CHECKS(orgId, aliasId), void 0, void 0, false, { headers: { "Idempotency-Key": request.idempotency_key } });
66385
+ }
66386
+ /** Sole durable recovery surface for one readiness request. */
66387
+ async getBrowserAliasReadinessCheck(orgId, aliasId, checkId) {
66388
+ return this.request("GET", ENDPOINTS.ORG_BROWSER_ALIAS_READINESS_CHECK(orgId, aliasId, checkId));
66389
+ }
66390
+ /** Organization Owner view. Hashes, reviewed snapshots and deltas are
66391
+ * intentionally available only on this human-JWT management surface. */
66392
+ async listBrowserAliasGrants(orgId, keyId) {
66393
+ return this.request("GET", ENDPOINTS.ORG_API_KEY_BROWSER_ALIAS_GRANTS(orgId, keyId));
66394
+ }
66395
+ async getBrowserAliasGrant(orgId, keyId, aliasId) {
66396
+ return this.request("GET", ENDPOINTS.ORG_API_KEY_BROWSER_ALIAS_GRANT(orgId, keyId, aliasId));
66397
+ }
66398
+ async replaceBrowserAliasGrant(orgId, keyId, aliasId, request) {
66399
+ return this.request("PUT", ENDPOINTS.ORG_API_KEY_BROWSER_ALIAS_GRANT(orgId, keyId, aliasId), request);
66400
+ }
66401
+ /** Managed-key discovery. The response is already grant-filtered and never
66402
+ * carries contract hashes, review snapshots, Edge IDs or Profile IDs. */
66403
+ async listManagedBrowserAliases(orgId) {
66404
+ return this.request("GET", ENDPOINTS.ORG_MANAGED_ALIASES(orgId));
66405
+ }
66406
+ async getManagedBrowserAlias(orgId, aliasName) {
66407
+ return this.request("GET", ENDPOINTS.ORG_MANAGED_ALIAS(orgId, aliasName));
66408
+ }
66409
+ /** Accept and dispatch one @alias command. request_id is generated by the
66410
+ * caller before local validation and is also the sole durable recovery key. */
66411
+ async createBrowserAliasExecution(orgId, request) {
66412
+ return this.request("POST", ENDPOINTS.ORG_BROWSER_ALIAS_EXECUTIONS(orgId), request);
66413
+ }
66414
+ async getBrowserAliasExecution(orgId, requestId) {
66415
+ return this.request("GET", ENDPOINTS.ORG_BROWSER_ALIAS_EXECUTION(orgId, requestId));
66416
+ }
66248
66417
  /**
66249
66418
  * Read a hosted Cloud Profile's egress-proxy status (manager-only: hosted
66250
66419
  * human maintainer or org admin). Sanitized — the password never comes back.
@@ -51481,6 +51481,12 @@ function isForwardedMessageBody(body) {
51481
51481
  function sanitizeMeta(value) {
51482
51482
  return value.replace(/[\r\n]+/g, " ").replace(/[[\]|]/g, " ").trim();
51483
51483
  }
51484
+ function formatApprovalDecisionReason(status, reason) {
51485
+ const normalized = reason?.trim();
51486
+ if (status !== "rejected" || !normalized)
51487
+ return "";
51488
+ return `Reason (JSON): ${JSON.stringify(normalized)}`;
51489
+ }
51484
51490
  function buildEventBody(event) {
51485
51491
  const lines = [];
51486
51492
  if (event.type === "message") {
@@ -51701,6 +51707,16 @@ function browserViewerRequestOptions(command, opts) {
51701
51707
  };
51702
51708
  }
51703
51709
 
51710
+ // ts/sdk/dist/attachment-endpoints.js
51711
+ function attachmentEndpoints(apiBase) {
51712
+ return {
51713
+ UPLOAD_PRESIGN: (orgId) => `${apiBase}/orgs/${orgId}/upload/presign`,
51714
+ UPLOAD_COMPLETE: (orgId) => `${apiBase}/orgs/${orgId}/upload/complete`,
51715
+ UPLOAD_ABORT: (orgId) => `${apiBase}/orgs/${orgId}/upload/abort`,
51716
+ FILE: (id) => `${apiBase}/files/${id}`
51717
+ };
51718
+ }
51719
+
51704
51720
  // ts/sdk/dist/constants.js
51705
51721
  var API_BASE = "/api/v1";
51706
51722
  var WIKI_BASE = "/wiki/v1";
@@ -51773,9 +51789,7 @@ var ENDPOINTS = {
51773
51789
  MESSAGE_REACTIONS: (id) => `${API_BASE}/messages/${id}/reactions`,
51774
51790
  MESSAGE_REACTION: (id, emoji) => `${API_BASE}/messages/${id}/reactions/${encodeURIComponent(emoji)}`,
51775
51791
  // Upload (org-scoped)
51776
- UPLOAD_PRESIGN: (orgId) => `${API_BASE}/orgs/${orgId}/upload/presign`,
51777
- UPLOAD_COMPLETE: (orgId) => `${API_BASE}/orgs/${orgId}/upload/complete`,
51778
- FILE: (id) => `${API_BASE}/files/${id}`,
51792
+ ...attachmentEndpoints(API_BASE),
51779
51793
  // Approval requests (org-scoped)
51780
51794
  APPROVAL_REQUESTS: (orgId) => `${API_BASE}/orgs/${orgId}/approval-requests`,
51781
51795
  // Approvals (global)
@@ -51956,6 +51970,8 @@ var ENDPOINTS = {
51956
51970
  // backend router so `deleted` isn't captured as a {wikiId}; the SDK builder
51957
51971
  // is just a string.
51958
51972
  WIKIS_DELETED: (orgId) => `${WIKI_BASE}/orgs/${orgId}/wikis/deleted`,
51973
+ // Org-wide changeset listing across readable wikis (Working on tab).
51974
+ WIKI_ORG_CHANGESETS: (orgId) => `${WIKI_BASE}/orgs/${orgId}/wiki-changesets`,
51959
51975
  // Detail URL — also reused for DELETE (soft-delete) and `${WIKI}/restore`.
51960
51976
  WIKI: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}`,
51961
51977
  WIKI_RESTORE: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/restore`,
@@ -51985,6 +52001,10 @@ var ENDPOINTS = {
51985
52001
  // Wiki Path Restrictions (AFCS narrowing ACL — private subtrees)
51986
52002
  WIKI_RESTRICTIONS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/restrictions`,
51987
52003
  WIKI_RESTRICTION: (orgId, wikiId, restrictionId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/restrictions/${restrictionId}`,
52004
+ WIKI_ACCESS_POLICY: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/access-policy`,
52005
+ WIKI_ACCESS_POLICY_MEMBERS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/access-policy/members`,
52006
+ WIKI_MEMBERSHIP_SELF: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/membership/self`,
52007
+ WIKI_MEMBERS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/members`,
51988
52008
  WIKI_ACCESS_STATUS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/access-status`,
51989
52009
  WIKI_ACCESS_REQUESTS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/access-requests`,
51990
52010
  // Wiki History (commits, file commits, blame)
@@ -52105,6 +52125,19 @@ var ENDPOINTS = {
52105
52125
  ORG_EDGE_DEVICE_UNREGISTER: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/unregister`,
52106
52126
  ORG_EDGE_ONBOARDING: (orgId) => `/api/v1/orgs/${orgId}/edge/onboarding`,
52107
52127
  ORG_EDGE_PROFILES: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profiles`,
52128
+ ORG_EDGE_PROFILE_OPERATIONS: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profile-operations`,
52129
+ ORG_EDGE_PROFILE_OPERATION: (orgId, edgeId, operationId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profile-operations/${operationId}`,
52130
+ ORG_EDGE_PROFILE_OPERATION_CONFIRM: (orgId, edgeId, operationId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profile-operations/${operationId}/confirm`,
52131
+ ORG_BROWSER_ALIASES: (orgId) => `/api/v1/orgs/${orgId}/browser-aliases`,
52132
+ ORG_BROWSER_ALIAS: (orgId, aliasId) => `/api/v1/orgs/${orgId}/browser-aliases/${aliasId}`,
52133
+ ORG_BROWSER_ALIAS_READINESS_CHECKS: (orgId, aliasId) => `/api/v1/orgs/${orgId}/browser-aliases/${aliasId}/readiness-checks`,
52134
+ ORG_BROWSER_ALIAS_READINESS_CHECK: (orgId, aliasId, checkId) => `/api/v1/orgs/${orgId}/browser-aliases/${aliasId}/readiness-checks/${checkId}`,
52135
+ ORG_API_KEY_BROWSER_ALIAS_GRANTS: (orgId, keyId) => `/api/v1/orgs/${orgId}/api-keys/${keyId}/browser-alias-grants`,
52136
+ ORG_API_KEY_BROWSER_ALIAS_GRANT: (orgId, keyId, aliasId) => `/api/v1/orgs/${orgId}/api-keys/${keyId}/browser-alias-grants/${aliasId}`,
52137
+ ORG_MANAGED_ALIASES: (orgId) => `/api/v1/orgs/${orgId}/aliases`,
52138
+ ORG_MANAGED_ALIAS: (orgId, aliasName) => `/api/v1/orgs/${orgId}/aliases/${encodeURIComponent(aliasName)}`,
52139
+ ORG_BROWSER_ALIAS_EXECUTIONS: (orgId) => `/api/v1/orgs/${orgId}/executions`,
52140
+ ORG_BROWSER_ALIAS_EXECUTION: (orgId, requestId) => `/api/v1/orgs/${orgId}/executions/${encodeURIComponent(requestId)}`,
52108
52141
  // Per-profile egress proxy (hosted Cloud Profiles; manager-only, human-only).
52109
52142
  ORG_EDGE_PROFILE_PROXY: (orgId, edgeId, profileName) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profiles/${encodeURIComponent(profileName)}/proxy`,
52110
52143
  // Per-profile one-shot cookie seed (hosted Cloud Profiles; manager-only,
@@ -52455,8 +52488,44 @@ var WechatClient = class extends TaskLabelClient {
52455
52488
  }
52456
52489
  };
52457
52490
 
52491
+ // ts/sdk/dist/attachment-client.js
52492
+ var COMPLETION_RETRY_DELAYS_MS = [250, 750];
52493
+ function isRetryableCompletionError(error) {
52494
+ if (!error || typeof error !== "object" || !("status" in error))
52495
+ return false;
52496
+ const status = error.status;
52497
+ return status === 0 || typeof status === "number" && status >= 500;
52498
+ }
52499
+ var AttachmentClient = class extends WechatClient {
52500
+ async getUploadPresignUrl(orgId, req) {
52501
+ return this.request("POST", ENDPOINTS.UPLOAD_PRESIGN(orgId), req);
52502
+ }
52503
+ async completeUpload(orgId, attachmentId, parts) {
52504
+ const body = {
52505
+ attachment_id: attachmentId,
52506
+ parts
52507
+ };
52508
+ for (let attempt = 0; ; attempt += 1) {
52509
+ try {
52510
+ return await this.request("POST", ENDPOINTS.UPLOAD_COMPLETE(orgId), body);
52511
+ } catch (error) {
52512
+ const delay = COMPLETION_RETRY_DELAYS_MS[attempt];
52513
+ if (delay === void 0 || !isRetryableCompletionError(error))
52514
+ throw error;
52515
+ await new Promise((resolve3) => setTimeout(resolve3, delay));
52516
+ }
52517
+ }
52518
+ }
52519
+ async abortUpload(orgId, attachmentId) {
52520
+ return this.request("POST", ENDPOINTS.UPLOAD_ABORT(orgId), { attachment_id: attachmentId });
52521
+ }
52522
+ async getFileUrl(id, opts) {
52523
+ return this.request("GET", ENDPOINTS.FILE(id), void 0, opts?.download ? { download: true } : void 0);
52524
+ }
52525
+ };
52526
+
52458
52527
  // ts/sdk/dist/client.js
52459
- var ParallClient = class _ParallClient extends WechatClient {
52528
+ var ParallClient = class _ParallClient extends AttachmentClient {
52460
52529
  baseUrl;
52461
52530
  wikiBaseUrl;
52462
52531
  token;
@@ -53103,16 +53172,6 @@ var ParallClient = class _ParallClient extends WechatClient {
53103
53172
  const res = await this.request("GET", ENDPOINTS.MESSAGE_REACTIONS(messageId));
53104
53173
  return res.reactions;
53105
53174
  }
53106
- // ---- File Upload ----
53107
- async getUploadPresignUrl(orgId, req) {
53108
- return this.request("POST", ENDPOINTS.UPLOAD_PRESIGN(orgId), req);
53109
- }
53110
- async completeUpload(orgId, attachmentId) {
53111
- return this.request("POST", ENDPOINTS.UPLOAD_COMPLETE(orgId), { attachment_id: attachmentId });
53112
- }
53113
- async getFileUrl(id, opts) {
53114
- return this.request("GET", ENDPOINTS.FILE(id), void 0, opts?.download ? { download: true } : void 0);
53115
- }
53116
53175
  // ---- Approvals ----
53117
53176
  async getApproval(id) {
53118
53177
  return this.request("GET", ENDPOINTS.APPROVAL(id));
@@ -53120,8 +53179,14 @@ var ParallClient = class _ParallClient extends WechatClient {
53120
53179
  async requestApproval(orgId, req) {
53121
53180
  return this.request("POST", ENDPOINTS.APPROVAL_REQUESTS(orgId), req);
53122
53181
  }
53123
- async decideApproval(id, decision) {
53124
- return this.request("POST", ENDPOINTS.APPROVAL_DECIDE(id), { decision });
53182
+ async decideApproval(id, decision, reason) {
53183
+ if (decision === "approve" && reason?.trim()) {
53184
+ throw new ApiError(400, "Approval reason is only allowed for rejection decisions", "INVALID_DECISION_REASON");
53185
+ }
53186
+ return this.request("POST", ENDPOINTS.APPROVAL_DECIDE(id), {
53187
+ decision,
53188
+ ...decision === "reject" && reason !== void 0 ? { reason } : {}
53189
+ });
53125
53190
  }
53126
53191
  async cancelApproval(id) {
53127
53192
  return this.request("POST", ENDPOINTS.APPROVAL_CANCEL(id));
@@ -53954,6 +54019,17 @@ var ParallClient = class _ParallClient extends WechatClient {
53954
54019
  const res = await this.request("GET", ENDPOINTS.WIKI_CHANGESETS(orgId, wikiId));
53955
54020
  return res.data.map(normalizeWikiChangeset);
53956
54021
  }
54022
+ /** Org-wide changeset listing across every wiki the caller can read.
54023
+ * Server default (no `status`) is the pending set: proposed,
54024
+ * approval_pending, approved. */
54025
+ async getOrgWikiChangesets(orgId, opts) {
54026
+ const params = new URLSearchParams();
54027
+ for (const s of opts?.status ?? [])
54028
+ params.append("status", s);
54029
+ const qs = params.toString();
54030
+ const res = await this.request("GET", `${ENDPOINTS.WIKI_ORG_CHANGESETS(orgId)}${qs ? `?${qs}` : ""}`);
54031
+ return (res.data ?? []).map(normalizeWikiChangeset);
54032
+ }
53957
54033
  async getWikiChangeset(orgId, wikiId, changesetId) {
53958
54034
  return normalizeWikiChangeset(await this.request("GET", ENDPOINTS.WIKI_CHANGESET(orgId, wikiId, changesetId)));
53959
54035
  }
@@ -54042,6 +54118,35 @@ var ParallClient = class _ParallClient extends WechatClient {
54042
54118
  async getWikiAccessStatus(orgId, wikiId, path11) {
54043
54119
  return this.request("GET", ENDPOINTS.WIKI_ACCESS_STATUS(orgId, wikiId), void 0, path11 ? { path: path11 } : void 0);
54044
54120
  }
54121
+ // ---- Wiki membership projection (who-can-access, invites, join/leave) ----
54122
+ async getWikiAccessPolicy(orgId, wikiId, path11 = "") {
54123
+ return this.request("GET", ENDPOINTS.WIKI_ACCESS_POLICY(orgId, wikiId), void 0, path11 ? { path: path11 } : void 0);
54124
+ }
54125
+ async putWikiAccessPolicy(orgId, wikiId, policy) {
54126
+ return this.request("PUT", ENDPOINTS.WIKI_ACCESS_POLICY(orgId, wikiId), policy);
54127
+ }
54128
+ /** Add-only invite (viewer/editor); allowed for managers, and for editors
54129
+ * when the library enables editors_can_invite. */
54130
+ async addWikiMember(orgId, wikiId, subject, role) {
54131
+ await this.request("POST", ENDPOINTS.WIKI_ACCESS_POLICY_MEMBERS(orgId, wikiId), {
54132
+ subject,
54133
+ role
54134
+ });
54135
+ }
54136
+ /** Join a PUBLIC library as an explicit member (lands at the library's
54137
+ * default role). Restricted libraries answer 409 JOIN_REQUIRES_REQUEST —
54138
+ * go through createWikiAccessRequest instead. */
54139
+ async joinWiki(orgId, wikiId) {
54140
+ await this.request("POST", ENDPOINTS.WIKI_MEMBERSHIP_SELF(orgId, wikiId));
54141
+ }
54142
+ /** Remove the caller's explicit membership (team-granted membership stays). */
54143
+ async leaveWiki(orgId, wikiId) {
54144
+ await this.request("DELETE", ENDPOINTS.WIKI_MEMBERSHIP_SELF(orgId, wikiId));
54145
+ }
54146
+ async getWikiMembers(orgId, wikiId) {
54147
+ const res = await this.request("GET", ENDPOINTS.WIKI_MEMBERS(orgId, wikiId));
54148
+ return res.data ?? [];
54149
+ }
54045
54150
  async createWikiAccessRequest(orgId, wikiId, data) {
54046
54151
  await this.request("POST", ENDPOINTS.WIKI_ACCESS_REQUESTS(orgId, wikiId), data);
54047
54152
  }
@@ -54504,6 +54609,76 @@ var ParallClient = class _ParallClient extends WechatClient {
54504
54609
  async listEdgeProfiles(orgId, edgeId) {
54505
54610
  return this.request("GET", ENDPOINTS.ORG_EDGE_PROFILES(orgId, edgeId));
54506
54611
  }
54612
+ /** Start one durable Local BYOC Profile operation. Network-unknown callers
54613
+ * must retry with the same key or recover by operation id; a different body
54614
+ * under the same key is rejected. */
54615
+ async createEdgeProfileOperation(orgId, edgeId, request3, idempotencyKey) {
54616
+ return this.request("POST", ENDPOINTS.ORG_EDGE_PROFILE_OPERATIONS(orgId, edgeId), request3, void 0, false, { headers: { "Idempotency-Key": idempotencyKey } });
54617
+ }
54618
+ /** Strong-confirm the exact durable Delete impact. A changed impact returns
54619
+ * PROFILE_DELETE_IMPACT_CHANGED with a replacement receipt in
54620
+ * `ApiError.extras.details.operation`. */
54621
+ async confirmEdgeProfileOperation(orgId, edgeId, operationId, request3) {
54622
+ return this.request("POST", ENDPOINTS.ORG_EDGE_PROFILE_OPERATION_CONFIRM(orgId, edgeId, operationId), request3);
54623
+ }
54624
+ /** Sole read/recovery surface. The server may reconcile an already durable
54625
+ * dispatch/finalization while returning this receipt. */
54626
+ async getEdgeProfileOperation(orgId, edgeId, operationId) {
54627
+ return this.request("GET", ENDPOINTS.ORG_EDGE_PROFILE_OPERATION(orgId, edgeId, operationId));
54628
+ }
54629
+ /** Create and atomically materialize one Local BYOC Browser Alias. A replay
54630
+ * with the same idempotency key and body returns the original stable ccn_. */
54631
+ async createBrowserAlias(orgId, request3) {
54632
+ return this.request("POST", ENDPOINTS.ORG_BROWSER_ALIASES(orgId), request3);
54633
+ }
54634
+ async listBrowserAliases(orgId) {
54635
+ return this.request("GET", ENDPOINTS.ORG_BROWSER_ALIASES(orgId));
54636
+ }
54637
+ async getBrowserAlias(orgId, aliasId) {
54638
+ return this.request("GET", ENDPOINTS.ORG_BROWSER_ALIAS(orgId, aliasId));
54639
+ }
54640
+ async renameBrowserAlias(orgId, aliasId, request3) {
54641
+ return this.request("PATCH", ENDPOINTS.ORG_BROWSER_ALIAS(orgId, aliasId), request3);
54642
+ }
54643
+ async deleteBrowserAlias(orgId, aliasId, request3) {
54644
+ return this.request("DELETE", ENDPOINTS.ORG_BROWSER_ALIAS(orgId, aliasId), request3);
54645
+ }
54646
+ /** Start one durable readiness check. The key is carried as the standard
54647
+ * Idempotency-Key header; the request body is intentionally empty. */
54648
+ async createBrowserAliasReadinessCheck(orgId, aliasId, request3) {
54649
+ return this.request("POST", ENDPOINTS.ORG_BROWSER_ALIAS_READINESS_CHECKS(orgId, aliasId), void 0, void 0, false, { headers: { "Idempotency-Key": request3.idempotency_key } });
54650
+ }
54651
+ /** Sole durable recovery surface for one readiness request. */
54652
+ async getBrowserAliasReadinessCheck(orgId, aliasId, checkId) {
54653
+ return this.request("GET", ENDPOINTS.ORG_BROWSER_ALIAS_READINESS_CHECK(orgId, aliasId, checkId));
54654
+ }
54655
+ /** Organization Owner view. Hashes, reviewed snapshots and deltas are
54656
+ * intentionally available only on this human-JWT management surface. */
54657
+ async listBrowserAliasGrants(orgId, keyId) {
54658
+ return this.request("GET", ENDPOINTS.ORG_API_KEY_BROWSER_ALIAS_GRANTS(orgId, keyId));
54659
+ }
54660
+ async getBrowserAliasGrant(orgId, keyId, aliasId) {
54661
+ return this.request("GET", ENDPOINTS.ORG_API_KEY_BROWSER_ALIAS_GRANT(orgId, keyId, aliasId));
54662
+ }
54663
+ async replaceBrowserAliasGrant(orgId, keyId, aliasId, request3) {
54664
+ return this.request("PUT", ENDPOINTS.ORG_API_KEY_BROWSER_ALIAS_GRANT(orgId, keyId, aliasId), request3);
54665
+ }
54666
+ /** Managed-key discovery. The response is already grant-filtered and never
54667
+ * carries contract hashes, review snapshots, Edge IDs or Profile IDs. */
54668
+ async listManagedBrowserAliases(orgId) {
54669
+ return this.request("GET", ENDPOINTS.ORG_MANAGED_ALIASES(orgId));
54670
+ }
54671
+ async getManagedBrowserAlias(orgId, aliasName) {
54672
+ return this.request("GET", ENDPOINTS.ORG_MANAGED_ALIAS(orgId, aliasName));
54673
+ }
54674
+ /** Accept and dispatch one @alias command. request_id is generated by the
54675
+ * caller before local validation and is also the sole durable recovery key. */
54676
+ async createBrowserAliasExecution(orgId, request3) {
54677
+ return this.request("POST", ENDPOINTS.ORG_BROWSER_ALIAS_EXECUTIONS(orgId), request3);
54678
+ }
54679
+ async getBrowserAliasExecution(orgId, requestId) {
54680
+ return this.request("GET", ENDPOINTS.ORG_BROWSER_ALIAS_EXECUTION(orgId, requestId));
54681
+ }
54507
54682
  /**
54508
54683
  * Read a hosted Cloud Profile's egress-proxy status (manager-only: hosted
54509
54684
  * human maintainer or org admin). Sanitized — the password never comes back.
@@ -59274,7 +59449,10 @@ var ParallAgentGateway = class {
59274
59449
  this.opts.log?.info(`approval decided: ${approval.id} (${approval.status})`);
59275
59450
  const statusLabel = approval.status === "approved" ? "Approved" : "Rejected";
59276
59451
  const execInfo = approval.execution_status ? ` | execution: ${approval.execution_status}` : "";
59277
- const body = `${statusLabel}: ${approval.title}${execInfo}`;
59452
+ const reasonLine = formatApprovalDecisionReason(approval.status, approval.decision_reason);
59453
+ const reasonInfo = reasonLine ? `
59454
+ ${reasonLine}` : "";
59455
+ const body = `${statusLabel}: ${approval.title}${execInfo}${reasonInfo}`;
59278
59456
  const event = {
59279
59457
  type: "approval",
59280
59458
  targetId: chatId ?? approval.chat_id,
@@ -51481,6 +51481,12 @@ function isForwardedMessageBody(body) {
51481
51481
  function sanitizeMeta(value) {
51482
51482
  return value.replace(/[\r\n]+/g, " ").replace(/[[\]|]/g, " ").trim();
51483
51483
  }
51484
+ function formatApprovalDecisionReason(status, reason) {
51485
+ const normalized = reason?.trim();
51486
+ if (status !== "rejected" || !normalized)
51487
+ return "";
51488
+ return `Reason (JSON): ${JSON.stringify(normalized)}`;
51489
+ }
51484
51490
  function buildEventBody(event) {
51485
51491
  const lines = [];
51486
51492
  if (event.type === "message") {
@@ -51701,6 +51707,16 @@ function browserViewerRequestOptions(command, opts) {
51701
51707
  };
51702
51708
  }
51703
51709
 
51710
+ // ts/sdk/dist/attachment-endpoints.js
51711
+ function attachmentEndpoints(apiBase) {
51712
+ return {
51713
+ UPLOAD_PRESIGN: (orgId) => `${apiBase}/orgs/${orgId}/upload/presign`,
51714
+ UPLOAD_COMPLETE: (orgId) => `${apiBase}/orgs/${orgId}/upload/complete`,
51715
+ UPLOAD_ABORT: (orgId) => `${apiBase}/orgs/${orgId}/upload/abort`,
51716
+ FILE: (id) => `${apiBase}/files/${id}`
51717
+ };
51718
+ }
51719
+
51704
51720
  // ts/sdk/dist/constants.js
51705
51721
  var API_BASE = "/api/v1";
51706
51722
  var WIKI_BASE = "/wiki/v1";
@@ -51773,9 +51789,7 @@ var ENDPOINTS = {
51773
51789
  MESSAGE_REACTIONS: (id) => `${API_BASE}/messages/${id}/reactions`,
51774
51790
  MESSAGE_REACTION: (id, emoji) => `${API_BASE}/messages/${id}/reactions/${encodeURIComponent(emoji)}`,
51775
51791
  // Upload (org-scoped)
51776
- UPLOAD_PRESIGN: (orgId) => `${API_BASE}/orgs/${orgId}/upload/presign`,
51777
- UPLOAD_COMPLETE: (orgId) => `${API_BASE}/orgs/${orgId}/upload/complete`,
51778
- FILE: (id) => `${API_BASE}/files/${id}`,
51792
+ ...attachmentEndpoints(API_BASE),
51779
51793
  // Approval requests (org-scoped)
51780
51794
  APPROVAL_REQUESTS: (orgId) => `${API_BASE}/orgs/${orgId}/approval-requests`,
51781
51795
  // Approvals (global)
@@ -51956,6 +51970,8 @@ var ENDPOINTS = {
51956
51970
  // backend router so `deleted` isn't captured as a {wikiId}; the SDK builder
51957
51971
  // is just a string.
51958
51972
  WIKIS_DELETED: (orgId) => `${WIKI_BASE}/orgs/${orgId}/wikis/deleted`,
51973
+ // Org-wide changeset listing across readable wikis (Working on tab).
51974
+ WIKI_ORG_CHANGESETS: (orgId) => `${WIKI_BASE}/orgs/${orgId}/wiki-changesets`,
51959
51975
  // Detail URL — also reused for DELETE (soft-delete) and `${WIKI}/restore`.
51960
51976
  WIKI: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}`,
51961
51977
  WIKI_RESTORE: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/restore`,
@@ -51985,6 +52001,10 @@ var ENDPOINTS = {
51985
52001
  // Wiki Path Restrictions (AFCS narrowing ACL — private subtrees)
51986
52002
  WIKI_RESTRICTIONS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/restrictions`,
51987
52003
  WIKI_RESTRICTION: (orgId, wikiId, restrictionId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/restrictions/${restrictionId}`,
52004
+ WIKI_ACCESS_POLICY: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/access-policy`,
52005
+ WIKI_ACCESS_POLICY_MEMBERS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/access-policy/members`,
52006
+ WIKI_MEMBERSHIP_SELF: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/membership/self`,
52007
+ WIKI_MEMBERS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/members`,
51988
52008
  WIKI_ACCESS_STATUS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/access-status`,
51989
52009
  WIKI_ACCESS_REQUESTS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/access-requests`,
51990
52010
  // Wiki History (commits, file commits, blame)
@@ -52105,6 +52125,19 @@ var ENDPOINTS = {
52105
52125
  ORG_EDGE_DEVICE_UNREGISTER: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/unregister`,
52106
52126
  ORG_EDGE_ONBOARDING: (orgId) => `/api/v1/orgs/${orgId}/edge/onboarding`,
52107
52127
  ORG_EDGE_PROFILES: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profiles`,
52128
+ ORG_EDGE_PROFILE_OPERATIONS: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profile-operations`,
52129
+ ORG_EDGE_PROFILE_OPERATION: (orgId, edgeId, operationId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profile-operations/${operationId}`,
52130
+ ORG_EDGE_PROFILE_OPERATION_CONFIRM: (orgId, edgeId, operationId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profile-operations/${operationId}/confirm`,
52131
+ ORG_BROWSER_ALIASES: (orgId) => `/api/v1/orgs/${orgId}/browser-aliases`,
52132
+ ORG_BROWSER_ALIAS: (orgId, aliasId) => `/api/v1/orgs/${orgId}/browser-aliases/${aliasId}`,
52133
+ ORG_BROWSER_ALIAS_READINESS_CHECKS: (orgId, aliasId) => `/api/v1/orgs/${orgId}/browser-aliases/${aliasId}/readiness-checks`,
52134
+ ORG_BROWSER_ALIAS_READINESS_CHECK: (orgId, aliasId, checkId) => `/api/v1/orgs/${orgId}/browser-aliases/${aliasId}/readiness-checks/${checkId}`,
52135
+ ORG_API_KEY_BROWSER_ALIAS_GRANTS: (orgId, keyId) => `/api/v1/orgs/${orgId}/api-keys/${keyId}/browser-alias-grants`,
52136
+ ORG_API_KEY_BROWSER_ALIAS_GRANT: (orgId, keyId, aliasId) => `/api/v1/orgs/${orgId}/api-keys/${keyId}/browser-alias-grants/${aliasId}`,
52137
+ ORG_MANAGED_ALIASES: (orgId) => `/api/v1/orgs/${orgId}/aliases`,
52138
+ ORG_MANAGED_ALIAS: (orgId, aliasName) => `/api/v1/orgs/${orgId}/aliases/${encodeURIComponent(aliasName)}`,
52139
+ ORG_BROWSER_ALIAS_EXECUTIONS: (orgId) => `/api/v1/orgs/${orgId}/executions`,
52140
+ ORG_BROWSER_ALIAS_EXECUTION: (orgId, requestId) => `/api/v1/orgs/${orgId}/executions/${encodeURIComponent(requestId)}`,
52108
52141
  // Per-profile egress proxy (hosted Cloud Profiles; manager-only, human-only).
52109
52142
  ORG_EDGE_PROFILE_PROXY: (orgId, edgeId, profileName) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profiles/${encodeURIComponent(profileName)}/proxy`,
52110
52143
  // Per-profile one-shot cookie seed (hosted Cloud Profiles; manager-only,
@@ -52455,8 +52488,44 @@ var WechatClient = class extends TaskLabelClient {
52455
52488
  }
52456
52489
  };
52457
52490
 
52491
+ // ts/sdk/dist/attachment-client.js
52492
+ var COMPLETION_RETRY_DELAYS_MS = [250, 750];
52493
+ function isRetryableCompletionError(error) {
52494
+ if (!error || typeof error !== "object" || !("status" in error))
52495
+ return false;
52496
+ const status = error.status;
52497
+ return status === 0 || typeof status === "number" && status >= 500;
52498
+ }
52499
+ var AttachmentClient = class extends WechatClient {
52500
+ async getUploadPresignUrl(orgId, req) {
52501
+ return this.request("POST", ENDPOINTS.UPLOAD_PRESIGN(orgId), req);
52502
+ }
52503
+ async completeUpload(orgId, attachmentId, parts) {
52504
+ const body = {
52505
+ attachment_id: attachmentId,
52506
+ parts
52507
+ };
52508
+ for (let attempt = 0; ; attempt += 1) {
52509
+ try {
52510
+ return await this.request("POST", ENDPOINTS.UPLOAD_COMPLETE(orgId), body);
52511
+ } catch (error) {
52512
+ const delay = COMPLETION_RETRY_DELAYS_MS[attempt];
52513
+ if (delay === void 0 || !isRetryableCompletionError(error))
52514
+ throw error;
52515
+ await new Promise((resolve4) => setTimeout(resolve4, delay));
52516
+ }
52517
+ }
52518
+ }
52519
+ async abortUpload(orgId, attachmentId) {
52520
+ return this.request("POST", ENDPOINTS.UPLOAD_ABORT(orgId), { attachment_id: attachmentId });
52521
+ }
52522
+ async getFileUrl(id, opts) {
52523
+ return this.request("GET", ENDPOINTS.FILE(id), void 0, opts?.download ? { download: true } : void 0);
52524
+ }
52525
+ };
52526
+
52458
52527
  // ts/sdk/dist/client.js
52459
- var ParallClient = class _ParallClient extends WechatClient {
52528
+ var ParallClient = class _ParallClient extends AttachmentClient {
52460
52529
  baseUrl;
52461
52530
  wikiBaseUrl;
52462
52531
  token;
@@ -53103,16 +53172,6 @@ var ParallClient = class _ParallClient extends WechatClient {
53103
53172
  const res = await this.request("GET", ENDPOINTS.MESSAGE_REACTIONS(messageId));
53104
53173
  return res.reactions;
53105
53174
  }
53106
- // ---- File Upload ----
53107
- async getUploadPresignUrl(orgId, req) {
53108
- return this.request("POST", ENDPOINTS.UPLOAD_PRESIGN(orgId), req);
53109
- }
53110
- async completeUpload(orgId, attachmentId) {
53111
- return this.request("POST", ENDPOINTS.UPLOAD_COMPLETE(orgId), { attachment_id: attachmentId });
53112
- }
53113
- async getFileUrl(id, opts) {
53114
- return this.request("GET", ENDPOINTS.FILE(id), void 0, opts?.download ? { download: true } : void 0);
53115
- }
53116
53175
  // ---- Approvals ----
53117
53176
  async getApproval(id) {
53118
53177
  return this.request("GET", ENDPOINTS.APPROVAL(id));
@@ -53120,8 +53179,14 @@ var ParallClient = class _ParallClient extends WechatClient {
53120
53179
  async requestApproval(orgId, req) {
53121
53180
  return this.request("POST", ENDPOINTS.APPROVAL_REQUESTS(orgId), req);
53122
53181
  }
53123
- async decideApproval(id, decision) {
53124
- return this.request("POST", ENDPOINTS.APPROVAL_DECIDE(id), { decision });
53182
+ async decideApproval(id, decision, reason) {
53183
+ if (decision === "approve" && reason?.trim()) {
53184
+ throw new ApiError(400, "Approval reason is only allowed for rejection decisions", "INVALID_DECISION_REASON");
53185
+ }
53186
+ return this.request("POST", ENDPOINTS.APPROVAL_DECIDE(id), {
53187
+ decision,
53188
+ ...decision === "reject" && reason !== void 0 ? { reason } : {}
53189
+ });
53125
53190
  }
53126
53191
  async cancelApproval(id) {
53127
53192
  return this.request("POST", ENDPOINTS.APPROVAL_CANCEL(id));
@@ -53954,6 +54019,17 @@ var ParallClient = class _ParallClient extends WechatClient {
53954
54019
  const res = await this.request("GET", ENDPOINTS.WIKI_CHANGESETS(orgId, wikiId));
53955
54020
  return res.data.map(normalizeWikiChangeset);
53956
54021
  }
54022
+ /** Org-wide changeset listing across every wiki the caller can read.
54023
+ * Server default (no `status`) is the pending set: proposed,
54024
+ * approval_pending, approved. */
54025
+ async getOrgWikiChangesets(orgId, opts) {
54026
+ const params = new URLSearchParams();
54027
+ for (const s of opts?.status ?? [])
54028
+ params.append("status", s);
54029
+ const qs = params.toString();
54030
+ const res = await this.request("GET", `${ENDPOINTS.WIKI_ORG_CHANGESETS(orgId)}${qs ? `?${qs}` : ""}`);
54031
+ return (res.data ?? []).map(normalizeWikiChangeset);
54032
+ }
53957
54033
  async getWikiChangeset(orgId, wikiId, changesetId) {
53958
54034
  return normalizeWikiChangeset(await this.request("GET", ENDPOINTS.WIKI_CHANGESET(orgId, wikiId, changesetId)));
53959
54035
  }
@@ -54042,6 +54118,35 @@ var ParallClient = class _ParallClient extends WechatClient {
54042
54118
  async getWikiAccessStatus(orgId, wikiId, path12) {
54043
54119
  return this.request("GET", ENDPOINTS.WIKI_ACCESS_STATUS(orgId, wikiId), void 0, path12 ? { path: path12 } : void 0);
54044
54120
  }
54121
+ // ---- Wiki membership projection (who-can-access, invites, join/leave) ----
54122
+ async getWikiAccessPolicy(orgId, wikiId, path12 = "") {
54123
+ return this.request("GET", ENDPOINTS.WIKI_ACCESS_POLICY(orgId, wikiId), void 0, path12 ? { path: path12 } : void 0);
54124
+ }
54125
+ async putWikiAccessPolicy(orgId, wikiId, policy) {
54126
+ return this.request("PUT", ENDPOINTS.WIKI_ACCESS_POLICY(orgId, wikiId), policy);
54127
+ }
54128
+ /** Add-only invite (viewer/editor); allowed for managers, and for editors
54129
+ * when the library enables editors_can_invite. */
54130
+ async addWikiMember(orgId, wikiId, subject, role) {
54131
+ await this.request("POST", ENDPOINTS.WIKI_ACCESS_POLICY_MEMBERS(orgId, wikiId), {
54132
+ subject,
54133
+ role
54134
+ });
54135
+ }
54136
+ /** Join a PUBLIC library as an explicit member (lands at the library's
54137
+ * default role). Restricted libraries answer 409 JOIN_REQUIRES_REQUEST —
54138
+ * go through createWikiAccessRequest instead. */
54139
+ async joinWiki(orgId, wikiId) {
54140
+ await this.request("POST", ENDPOINTS.WIKI_MEMBERSHIP_SELF(orgId, wikiId));
54141
+ }
54142
+ /** Remove the caller's explicit membership (team-granted membership stays). */
54143
+ async leaveWiki(orgId, wikiId) {
54144
+ await this.request("DELETE", ENDPOINTS.WIKI_MEMBERSHIP_SELF(orgId, wikiId));
54145
+ }
54146
+ async getWikiMembers(orgId, wikiId) {
54147
+ const res = await this.request("GET", ENDPOINTS.WIKI_MEMBERS(orgId, wikiId));
54148
+ return res.data ?? [];
54149
+ }
54045
54150
  async createWikiAccessRequest(orgId, wikiId, data) {
54046
54151
  await this.request("POST", ENDPOINTS.WIKI_ACCESS_REQUESTS(orgId, wikiId), data);
54047
54152
  }
@@ -54504,6 +54609,76 @@ var ParallClient = class _ParallClient extends WechatClient {
54504
54609
  async listEdgeProfiles(orgId, edgeId) {
54505
54610
  return this.request("GET", ENDPOINTS.ORG_EDGE_PROFILES(orgId, edgeId));
54506
54611
  }
54612
+ /** Start one durable Local BYOC Profile operation. Network-unknown callers
54613
+ * must retry with the same key or recover by operation id; a different body
54614
+ * under the same key is rejected. */
54615
+ async createEdgeProfileOperation(orgId, edgeId, request3, idempotencyKey) {
54616
+ return this.request("POST", ENDPOINTS.ORG_EDGE_PROFILE_OPERATIONS(orgId, edgeId), request3, void 0, false, { headers: { "Idempotency-Key": idempotencyKey } });
54617
+ }
54618
+ /** Strong-confirm the exact durable Delete impact. A changed impact returns
54619
+ * PROFILE_DELETE_IMPACT_CHANGED with a replacement receipt in
54620
+ * `ApiError.extras.details.operation`. */
54621
+ async confirmEdgeProfileOperation(orgId, edgeId, operationId, request3) {
54622
+ return this.request("POST", ENDPOINTS.ORG_EDGE_PROFILE_OPERATION_CONFIRM(orgId, edgeId, operationId), request3);
54623
+ }
54624
+ /** Sole read/recovery surface. The server may reconcile an already durable
54625
+ * dispatch/finalization while returning this receipt. */
54626
+ async getEdgeProfileOperation(orgId, edgeId, operationId) {
54627
+ return this.request("GET", ENDPOINTS.ORG_EDGE_PROFILE_OPERATION(orgId, edgeId, operationId));
54628
+ }
54629
+ /** Create and atomically materialize one Local BYOC Browser Alias. A replay
54630
+ * with the same idempotency key and body returns the original stable ccn_. */
54631
+ async createBrowserAlias(orgId, request3) {
54632
+ return this.request("POST", ENDPOINTS.ORG_BROWSER_ALIASES(orgId), request3);
54633
+ }
54634
+ async listBrowserAliases(orgId) {
54635
+ return this.request("GET", ENDPOINTS.ORG_BROWSER_ALIASES(orgId));
54636
+ }
54637
+ async getBrowserAlias(orgId, aliasId) {
54638
+ return this.request("GET", ENDPOINTS.ORG_BROWSER_ALIAS(orgId, aliasId));
54639
+ }
54640
+ async renameBrowserAlias(orgId, aliasId, request3) {
54641
+ return this.request("PATCH", ENDPOINTS.ORG_BROWSER_ALIAS(orgId, aliasId), request3);
54642
+ }
54643
+ async deleteBrowserAlias(orgId, aliasId, request3) {
54644
+ return this.request("DELETE", ENDPOINTS.ORG_BROWSER_ALIAS(orgId, aliasId), request3);
54645
+ }
54646
+ /** Start one durable readiness check. The key is carried as the standard
54647
+ * Idempotency-Key header; the request body is intentionally empty. */
54648
+ async createBrowserAliasReadinessCheck(orgId, aliasId, request3) {
54649
+ return this.request("POST", ENDPOINTS.ORG_BROWSER_ALIAS_READINESS_CHECKS(orgId, aliasId), void 0, void 0, false, { headers: { "Idempotency-Key": request3.idempotency_key } });
54650
+ }
54651
+ /** Sole durable recovery surface for one readiness request. */
54652
+ async getBrowserAliasReadinessCheck(orgId, aliasId, checkId) {
54653
+ return this.request("GET", ENDPOINTS.ORG_BROWSER_ALIAS_READINESS_CHECK(orgId, aliasId, checkId));
54654
+ }
54655
+ /** Organization Owner view. Hashes, reviewed snapshots and deltas are
54656
+ * intentionally available only on this human-JWT management surface. */
54657
+ async listBrowserAliasGrants(orgId, keyId) {
54658
+ return this.request("GET", ENDPOINTS.ORG_API_KEY_BROWSER_ALIAS_GRANTS(orgId, keyId));
54659
+ }
54660
+ async getBrowserAliasGrant(orgId, keyId, aliasId) {
54661
+ return this.request("GET", ENDPOINTS.ORG_API_KEY_BROWSER_ALIAS_GRANT(orgId, keyId, aliasId));
54662
+ }
54663
+ async replaceBrowserAliasGrant(orgId, keyId, aliasId, request3) {
54664
+ return this.request("PUT", ENDPOINTS.ORG_API_KEY_BROWSER_ALIAS_GRANT(orgId, keyId, aliasId), request3);
54665
+ }
54666
+ /** Managed-key discovery. The response is already grant-filtered and never
54667
+ * carries contract hashes, review snapshots, Edge IDs or Profile IDs. */
54668
+ async listManagedBrowserAliases(orgId) {
54669
+ return this.request("GET", ENDPOINTS.ORG_MANAGED_ALIASES(orgId));
54670
+ }
54671
+ async getManagedBrowserAlias(orgId, aliasName) {
54672
+ return this.request("GET", ENDPOINTS.ORG_MANAGED_ALIAS(orgId, aliasName));
54673
+ }
54674
+ /** Accept and dispatch one @alias command. request_id is generated by the
54675
+ * caller before local validation and is also the sole durable recovery key. */
54676
+ async createBrowserAliasExecution(orgId, request3) {
54677
+ return this.request("POST", ENDPOINTS.ORG_BROWSER_ALIAS_EXECUTIONS(orgId), request3);
54678
+ }
54679
+ async getBrowserAliasExecution(orgId, requestId) {
54680
+ return this.request("GET", ENDPOINTS.ORG_BROWSER_ALIAS_EXECUTION(orgId, requestId));
54681
+ }
54507
54682
  /**
54508
54683
  * Read a hosted Cloud Profile's egress-proxy status (manager-only: hosted
54509
54684
  * human maintainer or org admin). Sanitized — the password never comes back.
@@ -59274,7 +59449,10 @@ var ParallAgentGateway = class {
59274
59449
  this.opts.log?.info(`approval decided: ${approval.id} (${approval.status})`);
59275
59450
  const statusLabel = approval.status === "approved" ? "Approved" : "Rejected";
59276
59451
  const execInfo = approval.execution_status ? ` | execution: ${approval.execution_status}` : "";
59277
- const body = `${statusLabel}: ${approval.title}${execInfo}`;
59452
+ const reasonLine = formatApprovalDecisionReason(approval.status, approval.decision_reason);
59453
+ const reasonInfo = reasonLine ? `
59454
+ ${reasonLine}` : "";
59455
+ const body = `${statusLabel}: ${approval.title}${execInfo}${reasonInfo}`;
59278
59456
  const event = {
59279
59457
  type: "approval",
59280
59458
  targetId: chatId ?? approval.chat_id,
@@ -178,11 +178,34 @@ var init_browser_viewer = __esm({
178
178
  }
179
179
  });
180
180
 
181
+ // ts/sdk/dist/attachment-types.js
182
+ var init_attachment_types = __esm({
183
+ "ts/sdk/dist/attachment-types.js"() {
184
+ "use strict";
185
+ }
186
+ });
187
+
188
+ // ts/sdk/dist/attachment-endpoints.js
189
+ function attachmentEndpoints(apiBase) {
190
+ return {
191
+ UPLOAD_PRESIGN: (orgId) => `${apiBase}/orgs/${orgId}/upload/presign`,
192
+ UPLOAD_COMPLETE: (orgId) => `${apiBase}/orgs/${orgId}/upload/complete`,
193
+ UPLOAD_ABORT: (orgId) => `${apiBase}/orgs/${orgId}/upload/abort`,
194
+ FILE: (id) => `${apiBase}/files/${id}`
195
+ };
196
+ }
197
+ var init_attachment_endpoints = __esm({
198
+ "ts/sdk/dist/attachment-endpoints.js"() {
199
+ "use strict";
200
+ }
201
+ });
202
+
181
203
  // ts/sdk/dist/constants.js
182
204
  var API_BASE, WIKI_BASE, CLIP_BASE, ENDPOINTS, WS_EVENTS;
183
205
  var init_constants = __esm({
184
206
  "ts/sdk/dist/constants.js"() {
185
207
  "use strict";
208
+ init_attachment_endpoints();
186
209
  API_BASE = "/api/v1";
187
210
  WIKI_BASE = "/wiki/v1";
188
211
  CLIP_BASE = "/clip/v1";
@@ -254,9 +277,7 @@ var init_constants = __esm({
254
277
  MESSAGE_REACTIONS: (id) => `${API_BASE}/messages/${id}/reactions`,
255
278
  MESSAGE_REACTION: (id, emoji) => `${API_BASE}/messages/${id}/reactions/${encodeURIComponent(emoji)}`,
256
279
  // Upload (org-scoped)
257
- UPLOAD_PRESIGN: (orgId) => `${API_BASE}/orgs/${orgId}/upload/presign`,
258
- UPLOAD_COMPLETE: (orgId) => `${API_BASE}/orgs/${orgId}/upload/complete`,
259
- FILE: (id) => `${API_BASE}/files/${id}`,
280
+ ...attachmentEndpoints(API_BASE),
260
281
  // Approval requests (org-scoped)
261
282
  APPROVAL_REQUESTS: (orgId) => `${API_BASE}/orgs/${orgId}/approval-requests`,
262
283
  // Approvals (global)
@@ -437,6 +458,8 @@ var init_constants = __esm({
437
458
  // backend router so `deleted` isn't captured as a {wikiId}; the SDK builder
438
459
  // is just a string.
439
460
  WIKIS_DELETED: (orgId) => `${WIKI_BASE}/orgs/${orgId}/wikis/deleted`,
461
+ // Org-wide changeset listing across readable wikis (Working on tab).
462
+ WIKI_ORG_CHANGESETS: (orgId) => `${WIKI_BASE}/orgs/${orgId}/wiki-changesets`,
440
463
  // Detail URL — also reused for DELETE (soft-delete) and `${WIKI}/restore`.
441
464
  WIKI: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}`,
442
465
  WIKI_RESTORE: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/restore`,
@@ -466,6 +489,10 @@ var init_constants = __esm({
466
489
  // Wiki Path Restrictions (AFCS narrowing ACL — private subtrees)
467
490
  WIKI_RESTRICTIONS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/restrictions`,
468
491
  WIKI_RESTRICTION: (orgId, wikiId, restrictionId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/restrictions/${restrictionId}`,
492
+ WIKI_ACCESS_POLICY: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/access-policy`,
493
+ WIKI_ACCESS_POLICY_MEMBERS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/access-policy/members`,
494
+ WIKI_MEMBERSHIP_SELF: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/membership/self`,
495
+ WIKI_MEMBERS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/members`,
469
496
  WIKI_ACCESS_STATUS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/access-status`,
470
497
  WIKI_ACCESS_REQUESTS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/access-requests`,
471
498
  // Wiki History (commits, file commits, blame)
@@ -586,6 +613,19 @@ var init_constants = __esm({
586
613
  ORG_EDGE_DEVICE_UNREGISTER: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/unregister`,
587
614
  ORG_EDGE_ONBOARDING: (orgId) => `/api/v1/orgs/${orgId}/edge/onboarding`,
588
615
  ORG_EDGE_PROFILES: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profiles`,
616
+ ORG_EDGE_PROFILE_OPERATIONS: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profile-operations`,
617
+ ORG_EDGE_PROFILE_OPERATION: (orgId, edgeId, operationId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profile-operations/${operationId}`,
618
+ ORG_EDGE_PROFILE_OPERATION_CONFIRM: (orgId, edgeId, operationId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profile-operations/${operationId}/confirm`,
619
+ ORG_BROWSER_ALIASES: (orgId) => `/api/v1/orgs/${orgId}/browser-aliases`,
620
+ ORG_BROWSER_ALIAS: (orgId, aliasId) => `/api/v1/orgs/${orgId}/browser-aliases/${aliasId}`,
621
+ ORG_BROWSER_ALIAS_READINESS_CHECKS: (orgId, aliasId) => `/api/v1/orgs/${orgId}/browser-aliases/${aliasId}/readiness-checks`,
622
+ ORG_BROWSER_ALIAS_READINESS_CHECK: (orgId, aliasId, checkId) => `/api/v1/orgs/${orgId}/browser-aliases/${aliasId}/readiness-checks/${checkId}`,
623
+ ORG_API_KEY_BROWSER_ALIAS_GRANTS: (orgId, keyId) => `/api/v1/orgs/${orgId}/api-keys/${keyId}/browser-alias-grants`,
624
+ ORG_API_KEY_BROWSER_ALIAS_GRANT: (orgId, keyId, aliasId) => `/api/v1/orgs/${orgId}/api-keys/${keyId}/browser-alias-grants/${aliasId}`,
625
+ ORG_MANAGED_ALIASES: (orgId) => `/api/v1/orgs/${orgId}/aliases`,
626
+ ORG_MANAGED_ALIAS: (orgId, aliasName) => `/api/v1/orgs/${orgId}/aliases/${encodeURIComponent(aliasName)}`,
627
+ ORG_BROWSER_ALIAS_EXECUTIONS: (orgId) => `/api/v1/orgs/${orgId}/executions`,
628
+ ORG_BROWSER_ALIAS_EXECUTION: (orgId, requestId) => `/api/v1/orgs/${orgId}/executions/${encodeURIComponent(requestId)}`,
589
629
  // Per-profile egress proxy (hosted Cloud Profiles; manager-only, human-only).
590
630
  ORG_EDGE_PROFILE_PROXY: (orgId, edgeId, profileName) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profiles/${encodeURIComponent(profileName)}/proxy`,
591
631
  // Per-profile one-shot cookie seed (hosted Cloud Profiles; manager-only,
@@ -961,6 +1001,50 @@ var init_wechat_client = __esm({
961
1001
  }
962
1002
  });
963
1003
 
1004
+ // ts/sdk/dist/attachment-client.js
1005
+ function isRetryableCompletionError(error) {
1006
+ if (!error || typeof error !== "object" || !("status" in error))
1007
+ return false;
1008
+ const status = error.status;
1009
+ return status === 0 || typeof status === "number" && status >= 500;
1010
+ }
1011
+ var COMPLETION_RETRY_DELAYS_MS, AttachmentClient;
1012
+ var init_attachment_client = __esm({
1013
+ "ts/sdk/dist/attachment-client.js"() {
1014
+ "use strict";
1015
+ init_constants();
1016
+ init_wechat_client();
1017
+ COMPLETION_RETRY_DELAYS_MS = [250, 750];
1018
+ AttachmentClient = class extends WechatClient {
1019
+ async getUploadPresignUrl(orgId, req) {
1020
+ return this.request("POST", ENDPOINTS.UPLOAD_PRESIGN(orgId), req);
1021
+ }
1022
+ async completeUpload(orgId, attachmentId, parts) {
1023
+ const body = {
1024
+ attachment_id: attachmentId,
1025
+ parts
1026
+ };
1027
+ for (let attempt = 0; ; attempt += 1) {
1028
+ try {
1029
+ return await this.request("POST", ENDPOINTS.UPLOAD_COMPLETE(orgId), body);
1030
+ } catch (error) {
1031
+ const delay = COMPLETION_RETRY_DELAYS_MS[attempt];
1032
+ if (delay === void 0 || !isRetryableCompletionError(error))
1033
+ throw error;
1034
+ await new Promise((resolve9) => setTimeout(resolve9, delay));
1035
+ }
1036
+ }
1037
+ }
1038
+ async abortUpload(orgId, attachmentId) {
1039
+ return this.request("POST", ENDPOINTS.UPLOAD_ABORT(orgId), { attachment_id: attachmentId });
1040
+ }
1041
+ async getFileUrl(id, opts) {
1042
+ return this.request("GET", ENDPOINTS.FILE(id), void 0, opts?.download ? { download: true } : void 0);
1043
+ }
1044
+ };
1045
+ }
1046
+ });
1047
+
964
1048
  // ts/sdk/dist/client.js
965
1049
  function normalizeWikiChangeset(changeset) {
966
1050
  return {
@@ -1005,8 +1089,8 @@ var init_client = __esm({
1005
1089
  "use strict";
1006
1090
  init_browser_viewer();
1007
1091
  init_constants();
1008
- init_wechat_client();
1009
- ParallClient = class _ParallClient extends WechatClient {
1092
+ init_attachment_client();
1093
+ ParallClient = class _ParallClient extends AttachmentClient {
1010
1094
  baseUrl;
1011
1095
  wikiBaseUrl;
1012
1096
  token;
@@ -1653,16 +1737,6 @@ var init_client = __esm({
1653
1737
  const res = await this.request("GET", ENDPOINTS.MESSAGE_REACTIONS(messageId));
1654
1738
  return res.reactions;
1655
1739
  }
1656
- // ---- File Upload ----
1657
- async getUploadPresignUrl(orgId, req) {
1658
- return this.request("POST", ENDPOINTS.UPLOAD_PRESIGN(orgId), req);
1659
- }
1660
- async completeUpload(orgId, attachmentId) {
1661
- return this.request("POST", ENDPOINTS.UPLOAD_COMPLETE(orgId), { attachment_id: attachmentId });
1662
- }
1663
- async getFileUrl(id, opts) {
1664
- return this.request("GET", ENDPOINTS.FILE(id), void 0, opts?.download ? { download: true } : void 0);
1665
- }
1666
1740
  // ---- Approvals ----
1667
1741
  async getApproval(id) {
1668
1742
  return this.request("GET", ENDPOINTS.APPROVAL(id));
@@ -1670,8 +1744,14 @@ var init_client = __esm({
1670
1744
  async requestApproval(orgId, req) {
1671
1745
  return this.request("POST", ENDPOINTS.APPROVAL_REQUESTS(orgId), req);
1672
1746
  }
1673
- async decideApproval(id, decision) {
1674
- return this.request("POST", ENDPOINTS.APPROVAL_DECIDE(id), { decision });
1747
+ async decideApproval(id, decision, reason) {
1748
+ if (decision === "approve" && reason?.trim()) {
1749
+ throw new ApiError(400, "Approval reason is only allowed for rejection decisions", "INVALID_DECISION_REASON");
1750
+ }
1751
+ return this.request("POST", ENDPOINTS.APPROVAL_DECIDE(id), {
1752
+ decision,
1753
+ ...decision === "reject" && reason !== void 0 ? { reason } : {}
1754
+ });
1675
1755
  }
1676
1756
  async cancelApproval(id) {
1677
1757
  return this.request("POST", ENDPOINTS.APPROVAL_CANCEL(id));
@@ -2504,6 +2584,17 @@ var init_client = __esm({
2504
2584
  const res = await this.request("GET", ENDPOINTS.WIKI_CHANGESETS(orgId, wikiId));
2505
2585
  return res.data.map(normalizeWikiChangeset);
2506
2586
  }
2587
+ /** Org-wide changeset listing across every wiki the caller can read.
2588
+ * Server default (no `status`) is the pending set: proposed,
2589
+ * approval_pending, approved. */
2590
+ async getOrgWikiChangesets(orgId, opts) {
2591
+ const params = new URLSearchParams();
2592
+ for (const s of opts?.status ?? [])
2593
+ params.append("status", s);
2594
+ const qs = params.toString();
2595
+ const res = await this.request("GET", `${ENDPOINTS.WIKI_ORG_CHANGESETS(orgId)}${qs ? `?${qs}` : ""}`);
2596
+ return (res.data ?? []).map(normalizeWikiChangeset);
2597
+ }
2507
2598
  async getWikiChangeset(orgId, wikiId, changesetId) {
2508
2599
  return normalizeWikiChangeset(await this.request("GET", ENDPOINTS.WIKI_CHANGESET(orgId, wikiId, changesetId)));
2509
2600
  }
@@ -2592,6 +2683,35 @@ var init_client = __esm({
2592
2683
  async getWikiAccessStatus(orgId, wikiId, path23) {
2593
2684
  return this.request("GET", ENDPOINTS.WIKI_ACCESS_STATUS(orgId, wikiId), void 0, path23 ? { path: path23 } : void 0);
2594
2685
  }
2686
+ // ---- Wiki membership projection (who-can-access, invites, join/leave) ----
2687
+ async getWikiAccessPolicy(orgId, wikiId, path23 = "") {
2688
+ return this.request("GET", ENDPOINTS.WIKI_ACCESS_POLICY(orgId, wikiId), void 0, path23 ? { path: path23 } : void 0);
2689
+ }
2690
+ async putWikiAccessPolicy(orgId, wikiId, policy) {
2691
+ return this.request("PUT", ENDPOINTS.WIKI_ACCESS_POLICY(orgId, wikiId), policy);
2692
+ }
2693
+ /** Add-only invite (viewer/editor); allowed for managers, and for editors
2694
+ * when the library enables editors_can_invite. */
2695
+ async addWikiMember(orgId, wikiId, subject, role) {
2696
+ await this.request("POST", ENDPOINTS.WIKI_ACCESS_POLICY_MEMBERS(orgId, wikiId), {
2697
+ subject,
2698
+ role
2699
+ });
2700
+ }
2701
+ /** Join a PUBLIC library as an explicit member (lands at the library's
2702
+ * default role). Restricted libraries answer 409 JOIN_REQUIRES_REQUEST —
2703
+ * go through createWikiAccessRequest instead. */
2704
+ async joinWiki(orgId, wikiId) {
2705
+ await this.request("POST", ENDPOINTS.WIKI_MEMBERSHIP_SELF(orgId, wikiId));
2706
+ }
2707
+ /** Remove the caller's explicit membership (team-granted membership stays). */
2708
+ async leaveWiki(orgId, wikiId) {
2709
+ await this.request("DELETE", ENDPOINTS.WIKI_MEMBERSHIP_SELF(orgId, wikiId));
2710
+ }
2711
+ async getWikiMembers(orgId, wikiId) {
2712
+ const res = await this.request("GET", ENDPOINTS.WIKI_MEMBERS(orgId, wikiId));
2713
+ return res.data ?? [];
2714
+ }
2595
2715
  async createWikiAccessRequest(orgId, wikiId, data) {
2596
2716
  await this.request("POST", ENDPOINTS.WIKI_ACCESS_REQUESTS(orgId, wikiId), data);
2597
2717
  }
@@ -3054,6 +3174,76 @@ var init_client = __esm({
3054
3174
  async listEdgeProfiles(orgId, edgeId) {
3055
3175
  return this.request("GET", ENDPOINTS.ORG_EDGE_PROFILES(orgId, edgeId));
3056
3176
  }
3177
+ /** Start one durable Local BYOC Profile operation. Network-unknown callers
3178
+ * must retry with the same key or recover by operation id; a different body
3179
+ * under the same key is rejected. */
3180
+ async createEdgeProfileOperation(orgId, edgeId, request3, idempotencyKey) {
3181
+ return this.request("POST", ENDPOINTS.ORG_EDGE_PROFILE_OPERATIONS(orgId, edgeId), request3, void 0, false, { headers: { "Idempotency-Key": idempotencyKey } });
3182
+ }
3183
+ /** Strong-confirm the exact durable Delete impact. A changed impact returns
3184
+ * PROFILE_DELETE_IMPACT_CHANGED with a replacement receipt in
3185
+ * `ApiError.extras.details.operation`. */
3186
+ async confirmEdgeProfileOperation(orgId, edgeId, operationId, request3) {
3187
+ return this.request("POST", ENDPOINTS.ORG_EDGE_PROFILE_OPERATION_CONFIRM(orgId, edgeId, operationId), request3);
3188
+ }
3189
+ /** Sole read/recovery surface. The server may reconcile an already durable
3190
+ * dispatch/finalization while returning this receipt. */
3191
+ async getEdgeProfileOperation(orgId, edgeId, operationId) {
3192
+ return this.request("GET", ENDPOINTS.ORG_EDGE_PROFILE_OPERATION(orgId, edgeId, operationId));
3193
+ }
3194
+ /** Create and atomically materialize one Local BYOC Browser Alias. A replay
3195
+ * with the same idempotency key and body returns the original stable ccn_. */
3196
+ async createBrowserAlias(orgId, request3) {
3197
+ return this.request("POST", ENDPOINTS.ORG_BROWSER_ALIASES(orgId), request3);
3198
+ }
3199
+ async listBrowserAliases(orgId) {
3200
+ return this.request("GET", ENDPOINTS.ORG_BROWSER_ALIASES(orgId));
3201
+ }
3202
+ async getBrowserAlias(orgId, aliasId) {
3203
+ return this.request("GET", ENDPOINTS.ORG_BROWSER_ALIAS(orgId, aliasId));
3204
+ }
3205
+ async renameBrowserAlias(orgId, aliasId, request3) {
3206
+ return this.request("PATCH", ENDPOINTS.ORG_BROWSER_ALIAS(orgId, aliasId), request3);
3207
+ }
3208
+ async deleteBrowserAlias(orgId, aliasId, request3) {
3209
+ return this.request("DELETE", ENDPOINTS.ORG_BROWSER_ALIAS(orgId, aliasId), request3);
3210
+ }
3211
+ /** Start one durable readiness check. The key is carried as the standard
3212
+ * Idempotency-Key header; the request body is intentionally empty. */
3213
+ async createBrowserAliasReadinessCheck(orgId, aliasId, request3) {
3214
+ return this.request("POST", ENDPOINTS.ORG_BROWSER_ALIAS_READINESS_CHECKS(orgId, aliasId), void 0, void 0, false, { headers: { "Idempotency-Key": request3.idempotency_key } });
3215
+ }
3216
+ /** Sole durable recovery surface for one readiness request. */
3217
+ async getBrowserAliasReadinessCheck(orgId, aliasId, checkId) {
3218
+ return this.request("GET", ENDPOINTS.ORG_BROWSER_ALIAS_READINESS_CHECK(orgId, aliasId, checkId));
3219
+ }
3220
+ /** Organization Owner view. Hashes, reviewed snapshots and deltas are
3221
+ * intentionally available only on this human-JWT management surface. */
3222
+ async listBrowserAliasGrants(orgId, keyId) {
3223
+ return this.request("GET", ENDPOINTS.ORG_API_KEY_BROWSER_ALIAS_GRANTS(orgId, keyId));
3224
+ }
3225
+ async getBrowserAliasGrant(orgId, keyId, aliasId) {
3226
+ return this.request("GET", ENDPOINTS.ORG_API_KEY_BROWSER_ALIAS_GRANT(orgId, keyId, aliasId));
3227
+ }
3228
+ async replaceBrowserAliasGrant(orgId, keyId, aliasId, request3) {
3229
+ return this.request("PUT", ENDPOINTS.ORG_API_KEY_BROWSER_ALIAS_GRANT(orgId, keyId, aliasId), request3);
3230
+ }
3231
+ /** Managed-key discovery. The response is already grant-filtered and never
3232
+ * carries contract hashes, review snapshots, Edge IDs or Profile IDs. */
3233
+ async listManagedBrowserAliases(orgId) {
3234
+ return this.request("GET", ENDPOINTS.ORG_MANAGED_ALIASES(orgId));
3235
+ }
3236
+ async getManagedBrowserAlias(orgId, aliasName) {
3237
+ return this.request("GET", ENDPOINTS.ORG_MANAGED_ALIAS(orgId, aliasName));
3238
+ }
3239
+ /** Accept and dispatch one @alias command. request_id is generated by the
3240
+ * caller before local validation and is also the sole durable recovery key. */
3241
+ async createBrowserAliasExecution(orgId, request3) {
3242
+ return this.request("POST", ENDPOINTS.ORG_BROWSER_ALIAS_EXECUTIONS(orgId), request3);
3243
+ }
3244
+ async getBrowserAliasExecution(orgId, requestId) {
3245
+ return this.request("GET", ENDPOINTS.ORG_BROWSER_ALIAS_EXECUTION(orgId, requestId));
3246
+ }
3057
3247
  /**
3058
3248
  * Read a hosted Cloud Profile's egress-proxy status (manager-only: hosted
3059
3249
  * human maintainer or org admin). Sanitized — the password never comes back.
@@ -3663,6 +3853,7 @@ var init_dist = __esm({
3663
3853
  "ts/sdk/dist/index.js"() {
3664
3854
  "use strict";
3665
3855
  init_browser_viewer();
3856
+ init_attachment_types();
3666
3857
  init_client();
3667
3858
  init_constants();
3668
3859
  init_subject();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parall/daemon",
3
- "version": "1.55.4",
3
+ "version": "1.55.5",
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/agent-core": "1.55.4",
37
- "@parall/sdk": "1.55.4",
38
- "@parall/claude-agent": "1.55.4",
39
- "@parall/codex-agent": "1.55.4",
40
- "@parall/openclaw-agent": "1.55.4"
36
+ "@parall/agent-core": "1.55.5",
37
+ "@parall/sdk": "1.55.5",
38
+ "@parall/claude-agent": "1.55.5",
39
+ "@parall/codex-agent": "1.55.5",
40
+ "@parall/openclaw-agent": "1.55.5"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@types/node": "^22.0.0",