@parall/parall 1.55.4 → 1.56.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.bundle.mjs +281 -21
- package/package.json +3 -3
- package/skills/parall-platform/SKILL.md +23 -2
package/dist/index.bundle.mjs
CHANGED
|
@@ -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") {
|
|
@@ -51513,6 +51519,8 @@ function buildEventBody(event) {
|
|
|
51513
51519
|
].filter(Boolean).join(" | ");
|
|
51514
51520
|
lines.push(`[Thread: ${threadMeta}]`);
|
|
51515
51521
|
}
|
|
51522
|
+
if (event.deliveryReason)
|
|
51523
|
+
lines.push(`[Delivery: ${sanitizeMeta(event.deliveryReason)}]`);
|
|
51516
51524
|
if (event.unreadCount != null && event.unreadCount > 1) {
|
|
51517
51525
|
const countStr = event.unreadCount >= 1e3 ? "999+" : String(event.unreadCount);
|
|
51518
51526
|
const sinceStr = event.unreadSince ? ` | since: prll://${event.unreadSince}` : "";
|
|
@@ -51716,6 +51724,16 @@ function browserViewerRequestOptions(command, opts) {
|
|
|
51716
51724
|
};
|
|
51717
51725
|
}
|
|
51718
51726
|
|
|
51727
|
+
// ../sdk/dist/attachment-endpoints.js
|
|
51728
|
+
function attachmentEndpoints(apiBase) {
|
|
51729
|
+
return {
|
|
51730
|
+
UPLOAD_PRESIGN: (orgId) => `${apiBase}/orgs/${orgId}/upload/presign`,
|
|
51731
|
+
UPLOAD_COMPLETE: (orgId) => `${apiBase}/orgs/${orgId}/upload/complete`,
|
|
51732
|
+
UPLOAD_ABORT: (orgId) => `${apiBase}/orgs/${orgId}/upload/abort`,
|
|
51733
|
+
FILE: (id) => `${apiBase}/files/${id}`
|
|
51734
|
+
};
|
|
51735
|
+
}
|
|
51736
|
+
|
|
51719
51737
|
// ../sdk/dist/constants.js
|
|
51720
51738
|
var API_BASE = "/api/v1";
|
|
51721
51739
|
var WIKI_BASE = "/wiki/v1";
|
|
@@ -51788,9 +51806,7 @@ var ENDPOINTS = {
|
|
|
51788
51806
|
MESSAGE_REACTIONS: (id) => `${API_BASE}/messages/${id}/reactions`,
|
|
51789
51807
|
MESSAGE_REACTION: (id, emoji) => `${API_BASE}/messages/${id}/reactions/${encodeURIComponent(emoji)}`,
|
|
51790
51808
|
// Upload (org-scoped)
|
|
51791
|
-
|
|
51792
|
-
UPLOAD_COMPLETE: (orgId) => `${API_BASE}/orgs/${orgId}/upload/complete`,
|
|
51793
|
-
FILE: (id) => `${API_BASE}/files/${id}`,
|
|
51809
|
+
...attachmentEndpoints(API_BASE),
|
|
51794
51810
|
// Approval requests (org-scoped)
|
|
51795
51811
|
APPROVAL_REQUESTS: (orgId) => `${API_BASE}/orgs/${orgId}/approval-requests`,
|
|
51796
51812
|
// Approvals (global)
|
|
@@ -51876,6 +51892,7 @@ var ENDPOINTS = {
|
|
|
51876
51892
|
TASKS: (orgId) => `${API_BASE}/orgs/${orgId}/tasks`,
|
|
51877
51893
|
TASK_SUBTASK_SUMMARY: (orgId) => `${API_BASE}/orgs/${orgId}/tasks/subtask-summary`,
|
|
51878
51894
|
TASK: (orgId, taskId) => `${API_BASE}/orgs/${orgId}/tasks/${taskId}`,
|
|
51895
|
+
TASK_MOVE: (orgId, taskId) => `${API_BASE}/orgs/${orgId}/tasks/${taskId}/move`,
|
|
51879
51896
|
TASK_ARCHIVE: (orgId, taskId) => `${API_BASE}/orgs/${orgId}/tasks/${taskId}/archive`,
|
|
51880
51897
|
TASK_RESTORE: (orgId, taskId) => `${API_BASE}/orgs/${orgId}/tasks/${taskId}/restore`,
|
|
51881
51898
|
TASK_WATCH: (orgId, taskId) => `${API_BASE}/orgs/${orgId}/tasks/${taskId}/watch`,
|
|
@@ -51971,6 +51988,8 @@ var ENDPOINTS = {
|
|
|
51971
51988
|
// backend router so `deleted` isn't captured as a {wikiId}; the SDK builder
|
|
51972
51989
|
// is just a string.
|
|
51973
51990
|
WIKIS_DELETED: (orgId) => `${WIKI_BASE}/orgs/${orgId}/wikis/deleted`,
|
|
51991
|
+
// Org-wide changeset listing across readable wikis (Working on tab).
|
|
51992
|
+
WIKI_ORG_CHANGESETS: (orgId) => `${WIKI_BASE}/orgs/${orgId}/wiki-changesets`,
|
|
51974
51993
|
// Detail URL — also reused for DELETE (soft-delete) and `${WIKI}/restore`.
|
|
51975
51994
|
WIKI: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}`,
|
|
51976
51995
|
WIKI_RESTORE: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/restore`,
|
|
@@ -52000,6 +52019,12 @@ var ENDPOINTS = {
|
|
|
52000
52019
|
// Wiki Path Restrictions (AFCS narrowing ACL — private subtrees)
|
|
52001
52020
|
WIKI_RESTRICTIONS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/restrictions`,
|
|
52002
52021
|
WIKI_RESTRICTION: (orgId, wikiId, restrictionId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/restrictions/${restrictionId}`,
|
|
52022
|
+
WIKI_ACCESS_POLICY: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/access-policy`,
|
|
52023
|
+
WIKI_ACCESS_POLICY_MEMBERS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/access-policy/members`,
|
|
52024
|
+
WIKI_MEMBERSHIP_SELF: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/membership/self`,
|
|
52025
|
+
// Library-level star (self-scoped bookmark; POST = star, DELETE = unstar).
|
|
52026
|
+
WIKI_STARS_SELF: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/stars/self`,
|
|
52027
|
+
WIKI_MEMBERS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/members`,
|
|
52003
52028
|
WIKI_ACCESS_STATUS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/access-status`,
|
|
52004
52029
|
WIKI_ACCESS_REQUESTS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/access-requests`,
|
|
52005
52030
|
// Wiki History (commits, file commits, blame)
|
|
@@ -52120,6 +52145,21 @@ var ENDPOINTS = {
|
|
|
52120
52145
|
ORG_EDGE_DEVICE_UNREGISTER: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/unregister`,
|
|
52121
52146
|
ORG_EDGE_ONBOARDING: (orgId) => `/api/v1/orgs/${orgId}/edge/onboarding`,
|
|
52122
52147
|
ORG_EDGE_PROFILES: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profiles`,
|
|
52148
|
+
ORG_EDGE_PROFILE_OPERATIONS: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profile-operations`,
|
|
52149
|
+
ORG_EDGE_PROFILE_OPERATION: (orgId, edgeId, operationId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profile-operations/${operationId}`,
|
|
52150
|
+
ORG_EDGE_PROFILE_OPERATION_CONFIRM: (orgId, edgeId, operationId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profile-operations/${operationId}/confirm`,
|
|
52151
|
+
ORG_BROWSER_ALIASES: (orgId) => `/api/v1/orgs/${orgId}/browser-aliases`,
|
|
52152
|
+
ORG_BROWSER_ALIAS: (orgId, aliasId) => `/api/v1/orgs/${orgId}/browser-aliases/${aliasId}`,
|
|
52153
|
+
ORG_BROWSER_ALIAS_READINESS_CHECKS: (orgId, aliasId) => `/api/v1/orgs/${orgId}/browser-aliases/${aliasId}/readiness-checks`,
|
|
52154
|
+
ORG_BROWSER_ALIAS_READINESS_CHECK: (orgId, aliasId, checkId) => `/api/v1/orgs/${orgId}/browser-aliases/${aliasId}/readiness-checks/${checkId}`,
|
|
52155
|
+
ORG_API_KEY_BROWSER_ALIAS_GRANTS: (orgId, keyId) => `/api/v1/orgs/${orgId}/api-keys/${keyId}/browser-alias-grants`,
|
|
52156
|
+
ORG_API_KEY_BROWSER_ALIAS_GRANT: (orgId, keyId, aliasId) => `/api/v1/orgs/${orgId}/api-keys/${keyId}/browser-alias-grants/${aliasId}`,
|
|
52157
|
+
ORG_MANAGED_ALIASES: (orgId) => `/api/v1/orgs/${orgId}/aliases`,
|
|
52158
|
+
ORG_MANAGED_ALIAS: (orgId, aliasName) => `/api/v1/orgs/${orgId}/aliases/${encodeURIComponent(aliasName)}`,
|
|
52159
|
+
ORG_BROWSER_ALIAS_EXECUTIONS: (orgId) => `/api/v1/orgs/${orgId}/executions`,
|
|
52160
|
+
ORG_BROWSER_ALIAS_EXECUTION: (orgId, requestId) => `/api/v1/orgs/${orgId}/executions/${encodeURIComponent(requestId)}`,
|
|
52161
|
+
ORG_BROWSER_USE_OPERATIONS: (orgId) => `/api/v1/orgs/${orgId}/browser-use/operations`,
|
|
52162
|
+
ORG_BROWSER_USE_OPERATION: (orgId, operationId) => `/api/v1/orgs/${orgId}/browser-use/operations/${encodeURIComponent(operationId)}`,
|
|
52123
52163
|
// Per-profile egress proxy (hosted Cloud Profiles; manager-only, human-only).
|
|
52124
52164
|
ORG_EDGE_PROFILE_PROXY: (orgId, edgeId, profileName) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profiles/${encodeURIComponent(profileName)}/proxy`,
|
|
52125
52165
|
// Per-profile one-shot cookie seed (hosted Cloud Profiles; manager-only,
|
|
@@ -52134,6 +52174,8 @@ var ENDPOINTS = {
|
|
|
52134
52174
|
CLIP_CONNECTION: (orgId, connId) => `/api/v1/orgs/${orgId}/clip-connections/${connId}`,
|
|
52135
52175
|
// Clip registry (v3, org-scoped, served by api-server — `crg_` entries)
|
|
52136
52176
|
ORG_CLIP_REGISTRY: (orgId) => `/api/v1/orgs/${orgId}/clip-registry`,
|
|
52177
|
+
ORG_CLIP_REGISTRY_RESOLVE: (orgId) => `/api/v1/orgs/${orgId}/clip-registry/resolve`,
|
|
52178
|
+
ORG_CLIP_REGISTRY_SEARCH: (orgId) => `/api/v1/orgs/${orgId}/clip-registry/search`,
|
|
52137
52179
|
ORG_CLIP_REGISTRY_CLIP: (orgId, clipId) => `/api/v1/orgs/${orgId}/clip-registry/${clipId}`,
|
|
52138
52180
|
ORG_CLIP_REGISTRY_PUBLISH: (orgId) => `/api/v1/orgs/${orgId}/clip-registry/publish`,
|
|
52139
52181
|
ORG_CLIP_INSTALL: (orgId) => `/api/v1/orgs/${orgId}/clips/install`,
|
|
@@ -52267,6 +52309,15 @@ var ProjectTaskClient = class {
|
|
|
52267
52309
|
async deleteTask(orgId, taskId, opts) {
|
|
52268
52310
|
return this.request("DELETE", ENDPOINTS.TASK(orgId, taskId), void 0, opts?.force ? { force: "true" } : void 0);
|
|
52269
52311
|
}
|
|
52312
|
+
/**
|
|
52313
|
+
* Moves a task and its whole subtree into another project (renumbering it
|
|
52314
|
+
* there; old identifiers stay resolvable as aliases). The caller needs
|
|
52315
|
+
* update access on the task (source project membership) and read access to
|
|
52316
|
+
* the target project.
|
|
52317
|
+
*/
|
|
52318
|
+
async moveTask(orgId, taskId, data) {
|
|
52319
|
+
return this.request("POST", ENDPOINTS.TASK_MOVE(orgId, taskId), data);
|
|
52320
|
+
}
|
|
52270
52321
|
async archiveTask(orgId, taskId) {
|
|
52271
52322
|
return this.request("POST", ENDPOINTS.TASK_ARCHIVE(orgId, taskId));
|
|
52272
52323
|
}
|
|
@@ -52470,8 +52521,44 @@ var WechatClient = class extends TaskLabelClient {
|
|
|
52470
52521
|
}
|
|
52471
52522
|
};
|
|
52472
52523
|
|
|
52524
|
+
// ../sdk/dist/attachment-client.js
|
|
52525
|
+
var COMPLETION_RETRY_DELAYS_MS = [250, 750];
|
|
52526
|
+
function isRetryableCompletionError(error) {
|
|
52527
|
+
if (!error || typeof error !== "object" || !("status" in error))
|
|
52528
|
+
return false;
|
|
52529
|
+
const status = error.status;
|
|
52530
|
+
return status === 0 || typeof status === "number" && status >= 500;
|
|
52531
|
+
}
|
|
52532
|
+
var AttachmentClient = class extends WechatClient {
|
|
52533
|
+
async getUploadPresignUrl(orgId, req) {
|
|
52534
|
+
return this.request("POST", ENDPOINTS.UPLOAD_PRESIGN(orgId), req);
|
|
52535
|
+
}
|
|
52536
|
+
async completeUpload(orgId, attachmentId, parts) {
|
|
52537
|
+
const body = {
|
|
52538
|
+
attachment_id: attachmentId,
|
|
52539
|
+
parts
|
|
52540
|
+
};
|
|
52541
|
+
for (let attempt = 0; ; attempt += 1) {
|
|
52542
|
+
try {
|
|
52543
|
+
return await this.request("POST", ENDPOINTS.UPLOAD_COMPLETE(orgId), body);
|
|
52544
|
+
} catch (error) {
|
|
52545
|
+
const delay = COMPLETION_RETRY_DELAYS_MS[attempt];
|
|
52546
|
+
if (delay === void 0 || !isRetryableCompletionError(error))
|
|
52547
|
+
throw error;
|
|
52548
|
+
await new Promise((resolve3) => setTimeout(resolve3, delay));
|
|
52549
|
+
}
|
|
52550
|
+
}
|
|
52551
|
+
}
|
|
52552
|
+
async abortUpload(orgId, attachmentId) {
|
|
52553
|
+
return this.request("POST", ENDPOINTS.UPLOAD_ABORT(orgId), { attachment_id: attachmentId });
|
|
52554
|
+
}
|
|
52555
|
+
async getFileUrl(id, opts) {
|
|
52556
|
+
return this.request("GET", ENDPOINTS.FILE(id), void 0, opts?.download ? { download: true } : void 0);
|
|
52557
|
+
}
|
|
52558
|
+
};
|
|
52559
|
+
|
|
52473
52560
|
// ../sdk/dist/client.js
|
|
52474
|
-
var ParallClient = class _ParallClient extends
|
|
52561
|
+
var ParallClient = class _ParallClient extends AttachmentClient {
|
|
52475
52562
|
baseUrl;
|
|
52476
52563
|
wikiBaseUrl;
|
|
52477
52564
|
token;
|
|
@@ -53118,16 +53205,6 @@ var ParallClient = class _ParallClient extends WechatClient {
|
|
|
53118
53205
|
const res = await this.request("GET", ENDPOINTS.MESSAGE_REACTIONS(messageId));
|
|
53119
53206
|
return res.reactions;
|
|
53120
53207
|
}
|
|
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
53208
|
// ---- Approvals ----
|
|
53132
53209
|
async getApproval(id) {
|
|
53133
53210
|
return this.request("GET", ENDPOINTS.APPROVAL(id));
|
|
@@ -53135,8 +53212,14 @@ var ParallClient = class _ParallClient extends WechatClient {
|
|
|
53135
53212
|
async requestApproval(orgId, req) {
|
|
53136
53213
|
return this.request("POST", ENDPOINTS.APPROVAL_REQUESTS(orgId), req);
|
|
53137
53214
|
}
|
|
53138
|
-
async decideApproval(id, decision) {
|
|
53139
|
-
|
|
53215
|
+
async decideApproval(id, decision, reason) {
|
|
53216
|
+
if (decision === "approve" && reason?.trim()) {
|
|
53217
|
+
throw new ApiError(400, "Approval reason is only allowed for rejection decisions", "INVALID_DECISION_REASON");
|
|
53218
|
+
}
|
|
53219
|
+
return this.request("POST", ENDPOINTS.APPROVAL_DECIDE(id), {
|
|
53220
|
+
decision,
|
|
53221
|
+
...decision === "reject" && reason !== void 0 ? { reason } : {}
|
|
53222
|
+
});
|
|
53140
53223
|
}
|
|
53141
53224
|
async cancelApproval(id) {
|
|
53142
53225
|
return this.request("POST", ENDPOINTS.APPROVAL_CANCEL(id));
|
|
@@ -53969,6 +54052,17 @@ var ParallClient = class _ParallClient extends WechatClient {
|
|
|
53969
54052
|
const res = await this.request("GET", ENDPOINTS.WIKI_CHANGESETS(orgId, wikiId));
|
|
53970
54053
|
return res.data.map(normalizeWikiChangeset);
|
|
53971
54054
|
}
|
|
54055
|
+
/** Org-wide changeset listing across every wiki the caller can read.
|
|
54056
|
+
* Server default (no `status`) is the pending set: proposed,
|
|
54057
|
+
* approval_pending, approved. */
|
|
54058
|
+
async getOrgWikiChangesets(orgId, opts) {
|
|
54059
|
+
const params = new URLSearchParams();
|
|
54060
|
+
for (const s of opts?.status ?? [])
|
|
54061
|
+
params.append("status", s);
|
|
54062
|
+
const qs = params.toString();
|
|
54063
|
+
const res = await this.request("GET", `${ENDPOINTS.WIKI_ORG_CHANGESETS(orgId)}${qs ? `?${qs}` : ""}`);
|
|
54064
|
+
return (res.data ?? []).map(normalizeWikiChangeset);
|
|
54065
|
+
}
|
|
53972
54066
|
async getWikiChangeset(orgId, wikiId, changesetId) {
|
|
53973
54067
|
return normalizeWikiChangeset(await this.request("GET", ENDPOINTS.WIKI_CHANGESET(orgId, wikiId, changesetId)));
|
|
53974
54068
|
}
|
|
@@ -54057,6 +54151,46 @@ var ParallClient = class _ParallClient extends WechatClient {
|
|
|
54057
54151
|
async getWikiAccessStatus(orgId, wikiId, path9) {
|
|
54058
54152
|
return this.request("GET", ENDPOINTS.WIKI_ACCESS_STATUS(orgId, wikiId), void 0, path9 ? { path: path9 } : void 0);
|
|
54059
54153
|
}
|
|
54154
|
+
// ---- Wiki membership projection (who-can-access, invites, join/leave) ----
|
|
54155
|
+
async getWikiAccessPolicy(orgId, wikiId, path9 = "") {
|
|
54156
|
+
return this.request("GET", ENDPOINTS.WIKI_ACCESS_POLICY(orgId, wikiId), void 0, path9 ? { path: path9 } : void 0);
|
|
54157
|
+
}
|
|
54158
|
+
async putWikiAccessPolicy(orgId, wikiId, policy) {
|
|
54159
|
+
return this.request("PUT", ENDPOINTS.WIKI_ACCESS_POLICY(orgId, wikiId), policy);
|
|
54160
|
+
}
|
|
54161
|
+
/** Add-only invite (viewer/editor); allowed for managers, and for editors
|
|
54162
|
+
* when the library enables editors_can_invite. */
|
|
54163
|
+
async addWikiMember(orgId, wikiId, subject, role) {
|
|
54164
|
+
await this.request("POST", ENDPOINTS.WIKI_ACCESS_POLICY_MEMBERS(orgId, wikiId), {
|
|
54165
|
+
subject,
|
|
54166
|
+
role
|
|
54167
|
+
});
|
|
54168
|
+
}
|
|
54169
|
+
/** Join a PUBLIC library as an explicit member (lands at the library's
|
|
54170
|
+
* default role). Restricted libraries answer 409 JOIN_REQUIRES_REQUEST —
|
|
54171
|
+
* go through createWikiAccessRequest instead. */
|
|
54172
|
+
async joinWiki(orgId, wikiId) {
|
|
54173
|
+
await this.request("POST", ENDPOINTS.WIKI_MEMBERSHIP_SELF(orgId, wikiId));
|
|
54174
|
+
}
|
|
54175
|
+
/** Remove the caller's explicit membership (team-granted membership stays). */
|
|
54176
|
+
async leaveWiki(orgId, wikiId) {
|
|
54177
|
+
await this.request("DELETE", ENDPOINTS.WIKI_MEMBERSHIP_SELF(orgId, wikiId));
|
|
54178
|
+
}
|
|
54179
|
+
/** Star a library for the caller (sidebar Starred group). Idempotent —
|
|
54180
|
+
* re-starring is a 204 no-op. Requires read access; hidden private
|
|
54181
|
+
* libraries answer 404 like absent IDs. */
|
|
54182
|
+
async starWiki(orgId, wikiId) {
|
|
54183
|
+
await this.request("POST", ENDPOINTS.WIKI_STARS_SELF(orgId, wikiId));
|
|
54184
|
+
}
|
|
54185
|
+
/** Remove the caller's star. Idempotent — unstarring a never-starred
|
|
54186
|
+
* library is a 204 no-op. */
|
|
54187
|
+
async unstarWiki(orgId, wikiId) {
|
|
54188
|
+
await this.request("DELETE", ENDPOINTS.WIKI_STARS_SELF(orgId, wikiId));
|
|
54189
|
+
}
|
|
54190
|
+
async getWikiMembers(orgId, wikiId) {
|
|
54191
|
+
const res = await this.request("GET", ENDPOINTS.WIKI_MEMBERS(orgId, wikiId));
|
|
54192
|
+
return res.data ?? [];
|
|
54193
|
+
}
|
|
54060
54194
|
async createWikiAccessRequest(orgId, wikiId, data) {
|
|
54061
54195
|
await this.request("POST", ENDPOINTS.WIKI_ACCESS_REQUESTS(orgId, wikiId), data);
|
|
54062
54196
|
}
|
|
@@ -54406,6 +54540,31 @@ var ParallClient = class _ParallClient extends WechatClient {
|
|
|
54406
54540
|
const resp = await this.request("GET", `${ENDPOINTS.ORG_CLIP_REGISTRY(orgId)}?limit=100`);
|
|
54407
54541
|
return resp ?? [];
|
|
54408
54542
|
}
|
|
54543
|
+
/**
|
|
54544
|
+
* Resolve an exact `<publisher org, name>` reference to its registry entry —
|
|
54545
|
+
* the npm-style point read. Deliberately independent of catalog size: no
|
|
54546
|
+
* Search, no pagination, same read-visibility boundary as `getRegistryClip`
|
|
54547
|
+
* (cross-org requires public + approved). 404 `NOT_FOUND` when the publisher
|
|
54548
|
+
* org has no visible clip of that exact name.
|
|
54549
|
+
*/
|
|
54550
|
+
async resolveRegistryClip(orgId, publisherOrgId, name) {
|
|
54551
|
+
const params = new URLSearchParams({ org_id: publisherOrgId, name });
|
|
54552
|
+
return this.request("GET", `${ENDPOINTS.ORG_CLIP_REGISTRY_RESOLVE(orgId)}?${params}`);
|
|
54553
|
+
}
|
|
54554
|
+
/**
|
|
54555
|
+
* Server-side fuzzy discovery over the visible registry (name/description
|
|
54556
|
+
* substring match), paginated. The discovery verb: rows carry the `crg_` id
|
|
54557
|
+
* that {@link installRegistryClip} takes.
|
|
54558
|
+
*/
|
|
54559
|
+
async searchOrgRegistryClips(orgId, query, opts) {
|
|
54560
|
+
const params = new URLSearchParams({ q: query });
|
|
54561
|
+
if (opts?.limit !== void 0)
|
|
54562
|
+
params.set("limit", String(opts.limit));
|
|
54563
|
+
if (opts?.offset !== void 0)
|
|
54564
|
+
params.set("offset", String(opts.offset));
|
|
54565
|
+
const resp = await this.request("GET", `${ENDPOINTS.ORG_CLIP_REGISTRY_SEARCH(orgId)}?${params}`);
|
|
54566
|
+
return resp ?? [];
|
|
54567
|
+
}
|
|
54409
54568
|
/**
|
|
54410
54569
|
* Install a registry clip into the org (a reference in `clip_installs`, not a
|
|
54411
54570
|
* copy). Idempotent: installing an already-installed clip returns the same
|
|
@@ -54519,6 +54678,86 @@ var ParallClient = class _ParallClient extends WechatClient {
|
|
|
54519
54678
|
async listEdgeProfiles(orgId, edgeId) {
|
|
54520
54679
|
return this.request("GET", ENDPOINTS.ORG_EDGE_PROFILES(orgId, edgeId));
|
|
54521
54680
|
}
|
|
54681
|
+
/** Start one durable Local BYOC Profile operation. Network-unknown callers
|
|
54682
|
+
* must retry with the same key or recover by operation id; a different body
|
|
54683
|
+
* under the same key is rejected. */
|
|
54684
|
+
async createEdgeProfileOperation(orgId, edgeId, request3, idempotencyKey) {
|
|
54685
|
+
return this.request("POST", ENDPOINTS.ORG_EDGE_PROFILE_OPERATIONS(orgId, edgeId), request3, void 0, false, { headers: { "Idempotency-Key": idempotencyKey } });
|
|
54686
|
+
}
|
|
54687
|
+
/** Strong-confirm the exact durable Delete impact. A changed impact returns
|
|
54688
|
+
* PROFILE_DELETE_IMPACT_CHANGED with a replacement receipt in
|
|
54689
|
+
* `ApiError.extras.details.operation`. */
|
|
54690
|
+
async confirmEdgeProfileOperation(orgId, edgeId, operationId, request3) {
|
|
54691
|
+
return this.request("POST", ENDPOINTS.ORG_EDGE_PROFILE_OPERATION_CONFIRM(orgId, edgeId, operationId), request3);
|
|
54692
|
+
}
|
|
54693
|
+
/** Sole read/recovery surface. The server may reconcile an already durable
|
|
54694
|
+
* dispatch/finalization while returning this receipt. */
|
|
54695
|
+
async getEdgeProfileOperation(orgId, edgeId, operationId) {
|
|
54696
|
+
return this.request("GET", ENDPOINTS.ORG_EDGE_PROFILE_OPERATION(orgId, edgeId, operationId));
|
|
54697
|
+
}
|
|
54698
|
+
/** Create and atomically materialize one Local BYOC Browser Alias. A replay
|
|
54699
|
+
* with the same idempotency key and body returns the original stable ccn_. */
|
|
54700
|
+
async createBrowserAlias(orgId, request3) {
|
|
54701
|
+
return this.request("POST", ENDPOINTS.ORG_BROWSER_ALIASES(orgId), request3);
|
|
54702
|
+
}
|
|
54703
|
+
async listBrowserAliases(orgId) {
|
|
54704
|
+
return this.request("GET", ENDPOINTS.ORG_BROWSER_ALIASES(orgId));
|
|
54705
|
+
}
|
|
54706
|
+
async getBrowserAlias(orgId, aliasId) {
|
|
54707
|
+
return this.request("GET", ENDPOINTS.ORG_BROWSER_ALIAS(orgId, aliasId));
|
|
54708
|
+
}
|
|
54709
|
+
async renameBrowserAlias(orgId, aliasId, request3) {
|
|
54710
|
+
return this.request("PATCH", ENDPOINTS.ORG_BROWSER_ALIAS(orgId, aliasId), request3);
|
|
54711
|
+
}
|
|
54712
|
+
async deleteBrowserAlias(orgId, aliasId, request3) {
|
|
54713
|
+
return this.request("DELETE", ENDPOINTS.ORG_BROWSER_ALIAS(orgId, aliasId), request3);
|
|
54714
|
+
}
|
|
54715
|
+
/** Start one durable readiness check. The key is carried as the standard
|
|
54716
|
+
* Idempotency-Key header; the request body is intentionally empty. */
|
|
54717
|
+
async createBrowserAliasReadinessCheck(orgId, aliasId, request3) {
|
|
54718
|
+
return this.request("POST", ENDPOINTS.ORG_BROWSER_ALIAS_READINESS_CHECKS(orgId, aliasId), void 0, void 0, false, { headers: { "Idempotency-Key": request3.idempotency_key } });
|
|
54719
|
+
}
|
|
54720
|
+
/** Sole durable recovery surface for one readiness request. */
|
|
54721
|
+
async getBrowserAliasReadinessCheck(orgId, aliasId, checkId) {
|
|
54722
|
+
return this.request("GET", ENDPOINTS.ORG_BROWSER_ALIAS_READINESS_CHECK(orgId, aliasId, checkId));
|
|
54723
|
+
}
|
|
54724
|
+
/** Organization Owner view. Hashes, reviewed snapshots and deltas are
|
|
54725
|
+
* intentionally available only on this human-JWT management surface. */
|
|
54726
|
+
async listBrowserAliasGrants(orgId, keyId) {
|
|
54727
|
+
return this.request("GET", ENDPOINTS.ORG_API_KEY_BROWSER_ALIAS_GRANTS(orgId, keyId));
|
|
54728
|
+
}
|
|
54729
|
+
async getBrowserAliasGrant(orgId, keyId, aliasId) {
|
|
54730
|
+
return this.request("GET", ENDPOINTS.ORG_API_KEY_BROWSER_ALIAS_GRANT(orgId, keyId, aliasId));
|
|
54731
|
+
}
|
|
54732
|
+
async replaceBrowserAliasGrant(orgId, keyId, aliasId, request3) {
|
|
54733
|
+
return this.request("PUT", ENDPOINTS.ORG_API_KEY_BROWSER_ALIAS_GRANT(orgId, keyId, aliasId), request3);
|
|
54734
|
+
}
|
|
54735
|
+
/** Managed-key discovery. The response is already grant-filtered and never
|
|
54736
|
+
* carries contract hashes, review snapshots, Edge IDs or Profile IDs. */
|
|
54737
|
+
async listManagedBrowserAliases(orgId) {
|
|
54738
|
+
return this.request("GET", ENDPOINTS.ORG_MANAGED_ALIASES(orgId));
|
|
54739
|
+
}
|
|
54740
|
+
async getManagedBrowserAlias(orgId, aliasName) {
|
|
54741
|
+
return this.request("GET", ENDPOINTS.ORG_MANAGED_ALIAS(orgId, aliasName));
|
|
54742
|
+
}
|
|
54743
|
+
/** Accept and dispatch one @alias command. request_id is generated by the
|
|
54744
|
+
* caller before local validation and is also the sole durable recovery key. */
|
|
54745
|
+
async createBrowserAliasExecution(orgId, request3) {
|
|
54746
|
+
return this.request("POST", ENDPOINTS.ORG_BROWSER_ALIAS_EXECUTIONS(orgId), request3);
|
|
54747
|
+
}
|
|
54748
|
+
async getBrowserAliasExecution(orgId, requestId) {
|
|
54749
|
+
return this.request("GET", ENDPOINTS.ORG_BROWSER_ALIAS_EXECUTION(orgId, requestId));
|
|
54750
|
+
}
|
|
54751
|
+
/** Accept one idempotent Browser Use operation for an explicit Profile.
|
|
54752
|
+
* The Server resolves Profile→Edge; callers never select an Edge directly. */
|
|
54753
|
+
async createBrowserUseOperation(orgId, request3) {
|
|
54754
|
+
return this.request("POST", ENDPOINTS.ORG_BROWSER_USE_OPERATIONS(orgId), request3);
|
|
54755
|
+
}
|
|
54756
|
+
/** Recover the durable receipt. Successful data is present only inside the
|
|
54757
|
+
* Server's short encrypted result TTL; terminal proof remains afterwards. */
|
|
54758
|
+
async getBrowserUseOperation(orgId, operationId) {
|
|
54759
|
+
return this.request("GET", ENDPOINTS.ORG_BROWSER_USE_OPERATION(orgId, operationId));
|
|
54760
|
+
}
|
|
54522
54761
|
/**
|
|
54523
54762
|
* Read a hosted Cloud Profile's egress-proxy status (manager-only: hosted
|
|
54524
54763
|
* human maintainer or org admin). Sanitized — the password never comes back.
|
|
@@ -58783,11 +59022,28 @@ var ParallAgentGateway = class {
|
|
|
58783
59022
|
const hasAttachments = message.attachments?.length;
|
|
58784
59023
|
if (!body && !hasAttachments)
|
|
58785
59024
|
return { action: "skip" };
|
|
58786
|
-
|
|
58787
|
-
|
|
58788
|
-
|
|
58789
|
-
|
|
59025
|
+
const mentions = content.mentions ?? [];
|
|
59026
|
+
const isMentioned = mentions.some((mention) => mentionTargetsUser(mention.user_id, this.opts.agentUserId, "agent"));
|
|
59027
|
+
let deliveryReason;
|
|
59028
|
+
if (message.thread_root_id) {
|
|
59029
|
+
if (isMentioned) {
|
|
59030
|
+
deliveryReason = "mention";
|
|
59031
|
+
} else {
|
|
59032
|
+
let watching;
|
|
59033
|
+
try {
|
|
59034
|
+
watching = await this.opts.client.isWatchingThread(message.thread_root_id);
|
|
59035
|
+
} catch {
|
|
59036
|
+
return { action: "retry" };
|
|
59037
|
+
}
|
|
59038
|
+
if (!watching)
|
|
59039
|
+
return { action: "skip" };
|
|
59040
|
+
deliveryReason = "watcher";
|
|
59041
|
+
}
|
|
59042
|
+
} else if (chatInfo.type === "group") {
|
|
59043
|
+
if (chatInfo.agentRoutingMode !== "active" && !isMentioned)
|
|
58790
59044
|
return { action: "skip" };
|
|
59045
|
+
if (isMentioned)
|
|
59046
|
+
deliveryReason = "mention";
|
|
58791
59047
|
}
|
|
58792
59048
|
const attachments = (message.attachments ?? []).map((a) => ({
|
|
58793
59049
|
id: a.id,
|
|
@@ -58828,6 +59084,7 @@ var ParallAgentGateway = class {
|
|
|
58828
59084
|
messageId: message.id,
|
|
58829
59085
|
body: body || "[attachment]",
|
|
58830
59086
|
threadRootId: message.thread_root_id ?? void 0,
|
|
59087
|
+
deliveryReason,
|
|
58831
59088
|
noReply: message.hints?.no_reply ?? false,
|
|
58832
59089
|
attachments: attachments.length > 0 ? attachments : void 0,
|
|
58833
59090
|
sentAt: message.created_at,
|
|
@@ -59305,7 +59562,10 @@ var ParallAgentGateway = class {
|
|
|
59305
59562
|
this.opts.log?.info(`approval decided: ${approval.id} (${approval.status})`);
|
|
59306
59563
|
const statusLabel = approval.status === "approved" ? "Approved" : "Rejected";
|
|
59307
59564
|
const execInfo = approval.execution_status ? ` | execution: ${approval.execution_status}` : "";
|
|
59308
|
-
const
|
|
59565
|
+
const reasonLine = formatApprovalDecisionReason(approval.status, approval.decision_reason);
|
|
59566
|
+
const reasonInfo = reasonLine ? `
|
|
59567
|
+
${reasonLine}` : "";
|
|
59568
|
+
const body = `${statusLabel}: ${approval.title}${execInfo}${reasonInfo}`;
|
|
59309
59569
|
const event = {
|
|
59310
59570
|
type: "approval",
|
|
59311
59571
|
targetId: chatId ?? approval.chat_id,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parall/parall",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.56.0",
|
|
4
4
|
"description": "OpenClaw channel plugin for Parall IM",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
"openclaw.plugin.json"
|
|
17
17
|
],
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@parall/agent-core": "1.
|
|
20
|
-
"@parall/sdk": "1.
|
|
19
|
+
"@parall/agent-core": "1.56.0",
|
|
20
|
+
"@parall/sdk": "1.56.0"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
23
|
"@types/node": "^22.0.0",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: parall-platform
|
|
3
|
-
description: "Parall platform queries and lightweight agent provisioning: list org members, agents, chats, read message history, check identity, create another agent, or walk the prll:// reference graph (resolve URIs, backlinks, multi-hop graph). Use when: user asks about org members, who's online, chat history, agent list, creating an agent, identity/auth questions, or you need to find what an entity is connected to / who references it."
|
|
3
|
+
description: "Parall platform queries and lightweight agent provisioning: list org members, agents, chats, read message history, watch/unwatch threads, check identity, create another agent, or walk the prll:// reference graph (resolve URIs, backlinks, multi-hop graph). Use when: user asks about org members, who's online, chat history, agent list, creating an agent, identity/auth questions, you want to follow or mute a thread (e.g. after `[Delivery: watcher]` wake-ups), or you need to find what an entity is connected to / who references it."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Parall Platform
|
|
@@ -140,7 +140,7 @@ parall dm prll://usr_xxx --text-file /tmp/reply.md
|
|
|
140
140
|
parall dm "Alice" --text "Hello"
|
|
141
141
|
|
|
142
142
|
# Thread reply
|
|
143
|
-
parall messages send prll://cht_xxx --text-file /tmp/reply.md --thread-root-id
|
|
143
|
+
parall messages send prll://cht_xxx --text-file /tmp/reply.md --thread-root-id prll://msg_xxx
|
|
144
144
|
|
|
145
145
|
# FYI message (no response expected — the recipient sees `[Hint: no_reply]`)
|
|
146
146
|
parall messages send prll://cht_xxx --text "FYI: done" --no-reply
|
|
@@ -151,6 +151,27 @@ parall messages send prll://cht_xxx --text "FYI: done" --no-reply
|
|
|
151
151
|
parall no-reply --reason "ack only, nothing to add"
|
|
152
152
|
```
|
|
153
153
|
|
|
154
|
+
## Thread Subscriptions
|
|
155
|
+
|
|
156
|
+
Replying in a thread subscribes you to it: every later reply reaches you as
|
|
157
|
+
`[Event: message.new]` with a `[Thread: ...]` line, marked
|
|
158
|
+
`[Delivery: watcher]`. You are also auto-subscribed when a thread reply
|
|
159
|
+
@-mentions you personally, and when someone replies to a thread whose root
|
|
160
|
+
message you wrote. `[Delivery: mention]` means you were @-mentioned in that
|
|
161
|
+
message.
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
parall messages watch prll://msg_xxx # follow a thread without replying (ID = the thread's root message)
|
|
165
|
+
parall messages unwatch prll://msg_xxx # stop receiving a thread's replies
|
|
166
|
+
parall messages watchers prll://msg_xxx # list who is watching a thread
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Unwatch is sticky: no automatic source (including later @-mentions — you
|
|
170
|
+
still get the one-off mention, just no subscription) re-subscribes you.
|
|
171
|
+
Only replying in the thread yourself or an explicit `watch` does. Unwatch
|
|
172
|
+
threads you have nothing more to contribute to instead of ignoring their
|
|
173
|
+
wake-ups.
|
|
174
|
+
|
|
154
175
|
## Files & Attachments
|
|
155
176
|
|
|
156
177
|
Attachments appear in events as `[Attachment: prll://att_xxx | mime | size | name]`.
|