@parall/sdk 1.48.0 → 1.49.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client.d.ts +60 -2
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +81 -3
- package/dist/constants.d.ts +8 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +12 -0
- package/dist/types.d.ts +159 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +156 -4
- package/src/constants.ts +16 -0
- package/src/types.ts +164 -0
package/package.json
CHANGED
package/src/client.ts
CHANGED
|
@@ -167,6 +167,8 @@ import type {
|
|
|
167
167
|
DispatchExpireResult,
|
|
168
168
|
ResolveRefsResponse,
|
|
169
169
|
BacklinksResponse,
|
|
170
|
+
OutboundRefsRequest,
|
|
171
|
+
OutboundRefsResponse,
|
|
170
172
|
RefGraphResponse,
|
|
171
173
|
BrokenRefsResponse,
|
|
172
174
|
PushSubscribeRequest,
|
|
@@ -223,14 +225,20 @@ import type {
|
|
|
223
225
|
BrowserProfileLifecycleRequest,
|
|
224
226
|
BrowserViewerCommandRequest,
|
|
225
227
|
BrowserViewerCommandResponse,
|
|
228
|
+
EdgeViewerCommandRequest,
|
|
229
|
+
EdgeViewerCommandResponse,
|
|
226
230
|
GrantBrowserProfileConsentRequest,
|
|
227
231
|
EdgeDevice,
|
|
228
232
|
EdgePlacement,
|
|
229
233
|
EdgeBrowserProfile,
|
|
234
|
+
EdgeProfileProxyStatus,
|
|
235
|
+
SetEdgeProfileProxyRequest,
|
|
230
236
|
ClipConnection,
|
|
231
237
|
EdgeOnboardingStatus,
|
|
232
238
|
ExecEdgeClipRequest,
|
|
233
239
|
EdgeClipExecResult,
|
|
240
|
+
ReactionSummary,
|
|
241
|
+
ToggleReactionResponse,
|
|
234
242
|
} from './types.js';
|
|
235
243
|
|
|
236
244
|
export interface ParallClientOptions {
|
|
@@ -421,6 +429,8 @@ export class ParallClient {
|
|
|
421
429
|
timeoutMs?: number;
|
|
422
430
|
signal?: AbortSignal;
|
|
423
431
|
keepalive?: boolean;
|
|
432
|
+
/** Additional request preconditions such as If-Match. */
|
|
433
|
+
headers?: Record<string, string>;
|
|
424
434
|
/** Observes the final HTTP status of a successful request (e.g. 200-idempotent-replay vs 201-created). */
|
|
425
435
|
onStatus?: (status: number) => void;
|
|
426
436
|
},
|
|
@@ -443,7 +453,7 @@ export class ParallClient {
|
|
|
443
453
|
if (qs) url += `?${qs}`;
|
|
444
454
|
}
|
|
445
455
|
|
|
446
|
-
const headers = this.buildHeaders(path);
|
|
456
|
+
const headers = this.buildHeaders(path, opts?.headers);
|
|
447
457
|
|
|
448
458
|
// Cancellation: the caller's AbortSignal (e.g. a superseded search query)
|
|
449
459
|
// races the per-request timeout. AbortSignal.any aborts as soon as either
|
|
@@ -1095,6 +1105,20 @@ export class ParallClient {
|
|
|
1095
1105
|
return this.request('GET', ENDPOINTS.MESSAGE_REPLIES(id), undefined, params);
|
|
1096
1106
|
}
|
|
1097
1107
|
|
|
1108
|
+
// ---- Reactions ----
|
|
1109
|
+
|
|
1110
|
+
async toggleReaction(messageId: string, emoji: string): Promise<ToggleReactionResponse> {
|
|
1111
|
+
return this.request('PUT', ENDPOINTS.MESSAGE_REACTION(messageId, emoji));
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1114
|
+
async listReactions(messageId: string): Promise<ReactionSummary[]> {
|
|
1115
|
+
const res = await this.request<{ reactions: ReactionSummary[] }>(
|
|
1116
|
+
'GET',
|
|
1117
|
+
ENDPOINTS.MESSAGE_REACTIONS(messageId),
|
|
1118
|
+
);
|
|
1119
|
+
return res.reactions;
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1098
1122
|
// ---- File Upload ----
|
|
1099
1123
|
|
|
1100
1124
|
async getUploadPresignUrl(orgId: string, req: PresignUploadRequest): Promise<PresignResponse> {
|
|
@@ -1757,6 +1781,28 @@ export class ParallClient {
|
|
|
1757
1781
|
);
|
|
1758
1782
|
}
|
|
1759
1783
|
|
|
1784
|
+
/**
|
|
1785
|
+
* Drive the Cloud Edge live viewer (V1b, design §6): WebRTC signaling + input +
|
|
1786
|
+
* tab nav for a hosted browser (Cloud Profile). Same request/reply shape as
|
|
1787
|
+
* browserViewerCommand, on the v3 edge pipe; additive — the v2 browser-profile
|
|
1788
|
+
* viewer is unchanged.
|
|
1789
|
+
*/
|
|
1790
|
+
async edgeViewerCommand(
|
|
1791
|
+
orgId: string,
|
|
1792
|
+
edgeId: string,
|
|
1793
|
+
req: EdgeViewerCommandRequest,
|
|
1794
|
+
opts?: { timeoutMs?: number; keepalive?: boolean },
|
|
1795
|
+
): Promise<EdgeViewerCommandResponse> {
|
|
1796
|
+
return this.request(
|
|
1797
|
+
'POST',
|
|
1798
|
+
ENDPOINTS.ORG_EDGE_VIEWER_COMMAND(orgId, edgeId),
|
|
1799
|
+
req,
|
|
1800
|
+
undefined,
|
|
1801
|
+
false,
|
|
1802
|
+
opts,
|
|
1803
|
+
);
|
|
1804
|
+
}
|
|
1805
|
+
|
|
1760
1806
|
async resizeMachine(
|
|
1761
1807
|
orgId: string,
|
|
1762
1808
|
machineId: string,
|
|
@@ -1813,9 +1859,23 @@ export class ParallClient {
|
|
|
1813
1859
|
|
|
1814
1860
|
// ---- Unread ----
|
|
1815
1861
|
|
|
1816
|
-
async getUnreadCounts(
|
|
1862
|
+
async getUnreadCounts(
|
|
1863
|
+
orgId?: string,
|
|
1864
|
+
opts?: {
|
|
1865
|
+
/** Add unread thread replies (per-thread cursors) to count/mentions.
|
|
1866
|
+
* Opt-in: only clients that can clear thread cursors should pass it. */
|
|
1867
|
+
includeThreadReplies?: boolean;
|
|
1868
|
+
},
|
|
1869
|
+
): Promise<Record<string, UnreadEntry>> {
|
|
1817
1870
|
const endpoint = orgId ? ENDPOINTS.ORG_UNREAD(orgId) : ENDPOINTS.UNREAD;
|
|
1818
|
-
const res = await this.request<{ data: Record<string, UnreadEntry> }>(
|
|
1871
|
+
const res = await this.request<{ data: Record<string, UnreadEntry> }>(
|
|
1872
|
+
'GET',
|
|
1873
|
+
endpoint,
|
|
1874
|
+
undefined,
|
|
1875
|
+
{
|
|
1876
|
+
include_thread_replies: opts?.includeThreadReplies ? 'true' : undefined,
|
|
1877
|
+
},
|
|
1878
|
+
);
|
|
1819
1879
|
return res.data;
|
|
1820
1880
|
}
|
|
1821
1881
|
|
|
@@ -1823,6 +1883,14 @@ export class ParallClient {
|
|
|
1823
1883
|
return this.request('POST', ENDPOINTS.CHAT_READ(orgId, chatId), { message_id: messageId });
|
|
1824
1884
|
}
|
|
1825
1885
|
|
|
1886
|
+
/** Mark everything in a chat read: the channel cursor jumps to the latest
|
|
1887
|
+
* top-level message and every thread cursor to its latest reply, in one
|
|
1888
|
+
* idempotent call. The server echoes the same per-cursor WS events the
|
|
1889
|
+
* single-cursor routes emit and auto-clears covered inbox items. */
|
|
1890
|
+
async markAllRead(orgId: string, chatId: string): Promise<void> {
|
|
1891
|
+
return this.request('POST', ENDPOINTS.CHAT_READ_ALL(orgId, chatId));
|
|
1892
|
+
}
|
|
1893
|
+
|
|
1826
1894
|
async getThreadUnread(
|
|
1827
1895
|
orgId: string,
|
|
1828
1896
|
chatId: string,
|
|
@@ -3161,6 +3229,17 @@ export class ParallClient {
|
|
|
3161
3229
|
return this.request('GET', ENDPOINTS.REFS_BACKLINKS(orgId), undefined, params);
|
|
3162
3230
|
}
|
|
3163
3231
|
|
|
3232
|
+
/**
|
|
3233
|
+
* Outbound prll:// refs authored in a set of sources, as raw ref_links rows
|
|
3234
|
+
* (dedupe/group client-side). Pass `{ thread_root_id }` to list a whole
|
|
3235
|
+
* thread's refs (root + all replies, resolved server-side — the client's
|
|
3236
|
+
* reply window may be partial), or `{ source_type, source_ids }` for
|
|
3237
|
+
* explicit sources (max 500; v1 accepts only message sources).
|
|
3238
|
+
*/
|
|
3239
|
+
async listOutboundRefs(orgId: string, req: OutboundRefsRequest): Promise<OutboundRefsResponse> {
|
|
3240
|
+
return this.request('POST', ENDPOINTS.REFS_OUTBOUND(orgId), req);
|
|
3241
|
+
}
|
|
3242
|
+
|
|
3164
3243
|
/**
|
|
3165
3244
|
* Bounded multi-hop walk of the prll:// reference graph around `uri`. `uri`
|
|
3166
3245
|
* must be an entity-level prll:// URI — a refined URI (path/query/fragment) is
|
|
@@ -3567,6 +3646,75 @@ export class ParallClient {
|
|
|
3567
3646
|
return this.request('GET', ENDPOINTS.ORG_EDGE_PROFILES(orgId, edgeId));
|
|
3568
3647
|
}
|
|
3569
3648
|
|
|
3649
|
+
/**
|
|
3650
|
+
* Read a hosted Cloud Profile's egress-proxy status (manager-only: hosted
|
|
3651
|
+
* human maintainer or org admin). Sanitized — the password never comes back.
|
|
3652
|
+
* Typed errors: `EDGE_NOT_HOSTED` (BYOC device), `PROXY_CONFIG_CORRUPT` /
|
|
3653
|
+
* validation codes as 422 when a stored config no longer passes current rules.
|
|
3654
|
+
* `can_mutate` and `lease_status` are the authoritative idle gate; device
|
|
3655
|
+
* list status is not a substitute.
|
|
3656
|
+
*/
|
|
3657
|
+
async getEdgeProfileProxy(
|
|
3658
|
+
orgId: string,
|
|
3659
|
+
edgeId: string,
|
|
3660
|
+
profileName: string,
|
|
3661
|
+
): Promise<EdgeProfileProxyStatus> {
|
|
3662
|
+
return this.request('GET', ENDPOINTS.ORG_EDGE_PROFILE_PROXY(orgId, edgeId, profileName));
|
|
3663
|
+
}
|
|
3664
|
+
|
|
3665
|
+
/**
|
|
3666
|
+
* Set/replace the profile's egress proxy (full triple every time) — IDLE
|
|
3667
|
+
* ONLY: while the profile's hosted browser is running (a viewer session is
|
|
3668
|
+
* open or a pod is otherwise live) the server answers 409
|
|
3669
|
+
* `EDGE_PROFILE_IN_USE`; close the viewer, wait for idle scale-to-zero, and
|
|
3670
|
+
* retry. The next cold start uses the new egress; browser login state is
|
|
3671
|
+
* preserved across it. Other typed errors: the validation vocabulary
|
|
3672
|
+
* (`INVALID_PROXY_SERVER`, `PROXY_AUTH_INCOMPLETE`,
|
|
3673
|
+
* `PROXY_SERVER_FORBIDDEN_TARGET`, …), `EDGE_DELETING` (409), and
|
|
3674
|
+
* `SECRETBOX_UNCONFIGURED` (503 — server cannot store credentials safely),
|
|
3675
|
+
* and `EDGE_PROFILE_PROXY_STALE` (409 — expectedVersion lost a tab race).
|
|
3676
|
+
*/
|
|
3677
|
+
async setEdgeProfileProxy(
|
|
3678
|
+
orgId: string,
|
|
3679
|
+
edgeId: string,
|
|
3680
|
+
profileName: string,
|
|
3681
|
+
req: SetEdgeProfileProxyRequest,
|
|
3682
|
+
expectedVersion?: string,
|
|
3683
|
+
): Promise<EdgeProfileProxyStatus> {
|
|
3684
|
+
return this.request(
|
|
3685
|
+
'PUT',
|
|
3686
|
+
ENDPOINTS.ORG_EDGE_PROFILE_PROXY(orgId, edgeId, profileName),
|
|
3687
|
+
req,
|
|
3688
|
+
undefined,
|
|
3689
|
+
false,
|
|
3690
|
+
{
|
|
3691
|
+
headers: expectedVersion ? { 'If-Match': `"proxy-${expectedVersion}"` } : undefined,
|
|
3692
|
+
},
|
|
3693
|
+
);
|
|
3694
|
+
}
|
|
3695
|
+
|
|
3696
|
+
/**
|
|
3697
|
+
* Clear the profile's egress proxy; the next pod start egresses directly.
|
|
3698
|
+
* Idle-only like set — 409 `EDGE_PROFILE_IN_USE` while the browser is live.
|
|
3699
|
+
*/
|
|
3700
|
+
async clearEdgeProfileProxy(
|
|
3701
|
+
orgId: string,
|
|
3702
|
+
edgeId: string,
|
|
3703
|
+
profileName: string,
|
|
3704
|
+
expectedVersion?: string,
|
|
3705
|
+
): Promise<EdgeProfileProxyStatus> {
|
|
3706
|
+
return this.request(
|
|
3707
|
+
'DELETE',
|
|
3708
|
+
ENDPOINTS.ORG_EDGE_PROFILE_PROXY(orgId, edgeId, profileName),
|
|
3709
|
+
undefined,
|
|
3710
|
+
undefined,
|
|
3711
|
+
false,
|
|
3712
|
+
{
|
|
3713
|
+
headers: expectedVersion ? { 'If-Match': `"proxy-${expectedVersion}"` } : undefined,
|
|
3714
|
+
},
|
|
3715
|
+
);
|
|
3716
|
+
}
|
|
3717
|
+
|
|
3570
3718
|
/**
|
|
3571
3719
|
* Execute a registry clip command on an Edge device.
|
|
3572
3720
|
*
|
|
@@ -3664,6 +3812,8 @@ function normalizeWikiChangeset(changeset: WikiChangeset): WikiChangeset {
|
|
|
3664
3812
|
|
|
3665
3813
|
export class ApiError extends Error {
|
|
3666
3814
|
extras?: Record<string, unknown>;
|
|
3815
|
+
/** Retry-After delta seconds when the server supplies one. */
|
|
3816
|
+
retryAfterSeconds?: number;
|
|
3667
3817
|
/** Attempted action (authorization denials) — e.g. "chat.add_member". */
|
|
3668
3818
|
action?: string;
|
|
3669
3819
|
/** Target resource URI that was evaluated — e.g. "prll://cht_…". */
|
|
@@ -3691,7 +3841,7 @@ export class ApiError extends Error {
|
|
|
3691
3841
|
* See docs/engineering-design/error-contract-design.md
|
|
3692
3842
|
*/
|
|
3693
3843
|
function buildApiError(
|
|
3694
|
-
res: { status: number; statusText: string },
|
|
3844
|
+
res: { status: number; statusText: string; headers?: { get(name: string): string | null } },
|
|
3695
3845
|
rawErrorBody: unknown,
|
|
3696
3846
|
): ApiError {
|
|
3697
3847
|
const errorBody =
|
|
@@ -3714,6 +3864,8 @@ function buildApiError(
|
|
|
3714
3864
|
(typeof errorObj?.code === 'string' ? errorObj.code : undefined) ??
|
|
3715
3865
|
(typeof errorBody.code === 'string' ? (errorBody.code as string) : undefined);
|
|
3716
3866
|
const apiError = new ApiError(res.status, errMsg ?? res.statusText, errCode);
|
|
3867
|
+
const retryAfter = Number(res.headers?.get('Retry-After'));
|
|
3868
|
+
if (Number.isFinite(retryAfter) && retryAfter > 0) apiError.retryAfterSeconds = retryAfter;
|
|
3717
3869
|
// Machine anchors: present under `error`, with a legacy flat fallback.
|
|
3718
3870
|
const anchors = errorObj ?? errorBody;
|
|
3719
3871
|
if (typeof anchors.action === 'string') apiError.action = anchors.action;
|
package/src/constants.ts
CHANGED
|
@@ -410,6 +410,9 @@ export const ENDPOINTS = {
|
|
|
410
410
|
MESSAGE_WATCH: (id: string) => `${API_BASE}/messages/${id}/watch`,
|
|
411
411
|
MESSAGE_WATCHERS: (id: string) => `${API_BASE}/messages/${id}/watchers`,
|
|
412
412
|
MESSAGE_WATCHING: (id: string) => `${API_BASE}/messages/${id}/watching`,
|
|
413
|
+
MESSAGE_REACTIONS: (id: string) => `${API_BASE}/messages/${id}/reactions`,
|
|
414
|
+
MESSAGE_REACTION: (id: string, emoji: string) =>
|
|
415
|
+
`${API_BASE}/messages/${id}/reactions/${encodeURIComponent(emoji)}`,
|
|
413
416
|
|
|
414
417
|
// Upload (org-scoped)
|
|
415
418
|
UPLOAD_PRESIGN: (orgId: string) => `${API_BASE}/orgs/${orgId}/upload/presign`,
|
|
@@ -780,6 +783,8 @@ export const ENDPOINTS = {
|
|
|
780
783
|
UNREAD: `${API_BASE}/me/unread`,
|
|
781
784
|
ORG_UNREAD: (orgId: string) => `${API_BASE}/orgs/${orgId}/unread`,
|
|
782
785
|
CHAT_READ: (orgId: string, chatId: string) => `${API_BASE}/orgs/${orgId}/chats/${chatId}/read`,
|
|
786
|
+
CHAT_READ_ALL: (orgId: string, chatId: string) =>
|
|
787
|
+
`${API_BASE}/orgs/${orgId}/chats/${chatId}/read-all`,
|
|
783
788
|
THREAD_UNREAD: (orgId: string, chatId: string, threadRootId: string) =>
|
|
784
789
|
`${API_BASE}/orgs/${orgId}/chats/${chatId}/threads/${threadRootId}/unread`,
|
|
785
790
|
THREAD_READ: (orgId: string, chatId: string, threadRootId: string) =>
|
|
@@ -788,6 +793,7 @@ export const ENDPOINTS = {
|
|
|
788
793
|
// References (org-scoped)
|
|
789
794
|
REFS_RESOLVE: (orgId: string) => `${API_BASE}/orgs/${orgId}/refs/resolve`,
|
|
790
795
|
REFS_BACKLINKS: (orgId: string) => `${API_BASE}/orgs/${orgId}/refs/backlinks`,
|
|
796
|
+
REFS_OUTBOUND: (orgId: string) => `${API_BASE}/orgs/${orgId}/refs/outbound`,
|
|
791
797
|
REFS_GRAPH: (orgId: string) => `${API_BASE}/orgs/${orgId}/refs/graph`,
|
|
792
798
|
REFS_CHECK: (orgId: string) => `${API_BASE}/orgs/${orgId}/refs/check`,
|
|
793
799
|
|
|
@@ -876,7 +882,15 @@ export const ENDPOINTS = {
|
|
|
876
882
|
ORG_EDGE_ONBOARDING: (orgId: string) => `/api/v1/orgs/${orgId}/edge/onboarding`,
|
|
877
883
|
ORG_EDGE_PROFILES: (orgId: string, edgeId: string) =>
|
|
878
884
|
`/api/v1/orgs/${orgId}/edge/${edgeId}/profiles`,
|
|
885
|
+
// Per-profile egress proxy (hosted Cloud Profiles; manager-only, human-only).
|
|
886
|
+
ORG_EDGE_PROFILE_PROXY: (orgId: string, edgeId: string, profileName: string) =>
|
|
887
|
+
`/api/v1/orgs/${orgId}/edge/${edgeId}/profiles/${encodeURIComponent(profileName)}/proxy`,
|
|
879
888
|
ORG_EDGE_EXEC: (orgId: string) => `/api/v1/orgs/${orgId}/edge/exec`,
|
|
889
|
+
// Cloud Edge live viewer command (V1b) — api-server, gated on cap:edge-viewer.
|
|
890
|
+
// Same request/reply shape as the v2 browser-profile viewer, on the v3 edge
|
|
891
|
+
// pipe. Additive: does NOT replace BROWSER_PROFILE_VIEWER_COMMAND.
|
|
892
|
+
ORG_EDGE_VIEWER_COMMAND: (orgId: string, edgeId: string) =>
|
|
893
|
+
`/api/v1/orgs/${orgId}/edge/${edgeId}/viewer/command`,
|
|
880
894
|
CLIP_CONNECTIONS: (orgId: string, clipId: string) =>
|
|
881
895
|
`/api/v1/orgs/${orgId}/clip-registry/${clipId}/connections`,
|
|
882
896
|
CLIP_CONNECTION: (orgId: string, connId: string) =>
|
|
@@ -941,6 +955,7 @@ export const WS_EVENTS = {
|
|
|
941
955
|
MESSAGE_PATCH: 'message.patch',
|
|
942
956
|
MESSAGE_EDIT: 'message.edit',
|
|
943
957
|
MESSAGE_DELETE: 'message.delete',
|
|
958
|
+
MESSAGE_REACTION_UPDATED: 'message.reaction.updated',
|
|
944
959
|
TYPING_UPDATE: 'typing.update',
|
|
945
960
|
CHAT_UPDATE: 'chat.update',
|
|
946
961
|
CHAT_DELETED: 'chat.deleted',
|
|
@@ -981,6 +996,7 @@ export const WS_EVENTS = {
|
|
|
981
996
|
INBOX_UPDATE: 'inbox.update',
|
|
982
997
|
INBOX_BULK_UPDATE: 'inbox.bulk_update',
|
|
983
998
|
READ_POSITION_UPDATED: 'read_position.updated',
|
|
999
|
+
THREAD_READ_POSITION_UPDATED: 'thread_read_position.updated',
|
|
984
1000
|
DISPATCH_NEW: 'dispatch.new',
|
|
985
1001
|
DISPATCH_RECEIVED: 'dispatch.received',
|
|
986
1002
|
DISPATCH_RESOLVED: 'dispatch.resolved',
|
package/src/types.ts
CHANGED
|
@@ -111,6 +111,12 @@ export interface TransferChatOwnershipRequest {
|
|
|
111
111
|
export interface UnreadEntry {
|
|
112
112
|
count: number;
|
|
113
113
|
mentions: number;
|
|
114
|
+
/** Share of `count` contributed by unread thread replies (only present when
|
|
115
|
+
* the unread fetch opted into `include_thread_replies`). Top-level timeline
|
|
116
|
+
* unread = count - (thread_count ?? 0). */
|
|
117
|
+
thread_count?: number;
|
|
118
|
+
/** Share of `mentions` contributed by unread thread replies. */
|
|
119
|
+
thread_mentions?: number;
|
|
114
120
|
since?: string;
|
|
115
121
|
}
|
|
116
122
|
|
|
@@ -273,6 +279,12 @@ export interface Message {
|
|
|
273
279
|
* absent from the stack. A reload re-derives it from the server's view.
|
|
274
280
|
*/
|
|
275
281
|
recent_repliers?: User[];
|
|
282
|
+
/**
|
|
283
|
+
* Per-viewer count of thread replies newer than the viewer's thread read
|
|
284
|
+
* cursor, excluding the viewer's own replies (root only). Populated on
|
|
285
|
+
* top-level list responses; omitted when zero.
|
|
286
|
+
*/
|
|
287
|
+
unread_reply_count?: number;
|
|
276
288
|
edited_at: string | null;
|
|
277
289
|
deleted_at: string | null;
|
|
278
290
|
created_at: string;
|
|
@@ -281,6 +293,27 @@ export interface Message {
|
|
|
281
293
|
agent_session_id?: string | null;
|
|
282
294
|
hints?: MessageHints | null;
|
|
283
295
|
attachments?: Attachment[];
|
|
296
|
+
reactions?: ReactionSummary[];
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Aggregated reactions for one emoji on a message.
|
|
301
|
+
*
|
|
302
|
+
* `has_reacted` is viewer-relative in REST responses. In
|
|
303
|
+
* `message.reaction.updated` WS broadcasts it is computed for the ACTOR who
|
|
304
|
+
* triggered the toggle — subscribers must recompute their own state from
|
|
305
|
+
* `user_ids` (see docs/engineering-design/ws-protocol.md).
|
|
306
|
+
*/
|
|
307
|
+
export interface ReactionSummary {
|
|
308
|
+
emoji: string;
|
|
309
|
+
count: number;
|
|
310
|
+
user_ids: string[];
|
|
311
|
+
has_reacted: boolean;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
export interface ToggleReactionResponse {
|
|
315
|
+
added: boolean;
|
|
316
|
+
reactions: ReactionSummary[];
|
|
284
317
|
}
|
|
285
318
|
|
|
286
319
|
export interface Attachment {
|
|
@@ -1159,6 +1192,13 @@ export interface Task {
|
|
|
1159
1192
|
seq_number: number | null;
|
|
1160
1193
|
identifier: string | null;
|
|
1161
1194
|
sort_order: number;
|
|
1195
|
+
/**
|
|
1196
|
+
* Planned start date, YYYY-MM-DD (calendar date, timezone-free) — the
|
|
1197
|
+
* planned schedule's left edge, independent of started_at (when work
|
|
1198
|
+
* actually began). Absent on servers older than migration 145. When both
|
|
1199
|
+
* dates are set, planned_start_date <= due_date.
|
|
1200
|
+
*/
|
|
1201
|
+
planned_start_date?: string | null;
|
|
1162
1202
|
/** Planned completion date, YYYY-MM-DD (calendar date, timezone-free). */
|
|
1163
1203
|
due_date: string | null;
|
|
1164
1204
|
assignee?: User;
|
|
@@ -1246,6 +1286,8 @@ export interface CreateTaskRequest {
|
|
|
1246
1286
|
project_id?: string;
|
|
1247
1287
|
source_chat_id?: string;
|
|
1248
1288
|
sort_order?: number;
|
|
1289
|
+
/** Planned start date, YYYY-MM-DD. Must be <= due_date when both are set. */
|
|
1290
|
+
planned_start_date?: string;
|
|
1249
1291
|
/** Planned completion date, YYYY-MM-DD. */
|
|
1250
1292
|
due_date?: string;
|
|
1251
1293
|
}
|
|
@@ -1266,6 +1308,12 @@ export interface UpdateTaskRequest {
|
|
|
1266
1308
|
* full column. Mutually exclusive with sort_order.
|
|
1267
1309
|
*/
|
|
1268
1310
|
placement?: 'end';
|
|
1311
|
+
/**
|
|
1312
|
+
* Planned start date, YYYY-MM-DD; explicit null clears it. The post-patch
|
|
1313
|
+
* state must satisfy planned_start_date <= due_date when both are set
|
|
1314
|
+
* (400 INVALID_DATE_RANGE otherwise).
|
|
1315
|
+
*/
|
|
1316
|
+
planned_start_date?: string | null;
|
|
1269
1317
|
/** Planned completion date, YYYY-MM-DD; explicit null clears it. */
|
|
1270
1318
|
due_date?: string | null;
|
|
1271
1319
|
/**
|
|
@@ -2179,6 +2227,20 @@ export interface MessageDeleteData {
|
|
|
2179
2227
|
thread_root_id?: string;
|
|
2180
2228
|
}
|
|
2181
2229
|
|
|
2230
|
+
/**
|
|
2231
|
+
* Payload of the `message.reaction.updated` WS broadcast. `reactions` is the
|
|
2232
|
+
* full aggregated snapshot for the message; its `has_reacted` flags are
|
|
2233
|
+
* actor-relative (see {@link ReactionSummary}) — recompute from `user_ids`.
|
|
2234
|
+
*/
|
|
2235
|
+
export interface ReactionUpdatedData {
|
|
2236
|
+
message_id: string;
|
|
2237
|
+
chat_id: string;
|
|
2238
|
+
emoji: string;
|
|
2239
|
+
user_id: string;
|
|
2240
|
+
added: boolean;
|
|
2241
|
+
reactions: ReactionSummary[];
|
|
2242
|
+
}
|
|
2243
|
+
|
|
2182
2244
|
export interface TypingUpdateData {
|
|
2183
2245
|
chat_id: string;
|
|
2184
2246
|
thread_root_id: string | null;
|
|
@@ -3073,6 +3135,13 @@ export interface ReadPositionUpdateData {
|
|
|
3073
3135
|
last_read_message_id: string;
|
|
3074
3136
|
}
|
|
3075
3137
|
|
|
3138
|
+
/** Per-thread read cursor sync across the user's devices. */
|
|
3139
|
+
export interface ThreadReadPositionUpdateData {
|
|
3140
|
+
chat_id: string;
|
|
3141
|
+
thread_root_id: string;
|
|
3142
|
+
last_read_reply_id: string;
|
|
3143
|
+
}
|
|
3144
|
+
|
|
3076
3145
|
export interface NotificationAlertData {
|
|
3077
3146
|
title: string;
|
|
3078
3147
|
body: string;
|
|
@@ -3087,6 +3156,7 @@ export type WsEventMap = {
|
|
|
3087
3156
|
'message.patch': MessagePatchData;
|
|
3088
3157
|
'message.edit': MessageEditData;
|
|
3089
3158
|
'message.delete': MessageDeleteData;
|
|
3159
|
+
'message.reaction.updated': ReactionUpdatedData;
|
|
3090
3160
|
'typing.update': TypingUpdateData;
|
|
3091
3161
|
'chat.created': ChatCreatedData;
|
|
3092
3162
|
'chat.update': ChatUpdateData;
|
|
@@ -3131,6 +3201,7 @@ export type WsEventMap = {
|
|
|
3131
3201
|
'inbox.update': InboxUpdateData;
|
|
3132
3202
|
'inbox.bulk_update': InboxBulkUpdateData;
|
|
3133
3203
|
'read_position.updated': ReadPositionUpdateData;
|
|
3204
|
+
'thread_read_position.updated': ThreadReadPositionUpdateData;
|
|
3134
3205
|
'dispatch.new': DispatchNewData;
|
|
3135
3206
|
'dispatch.received': DispatchReceivedData;
|
|
3136
3207
|
'dispatch.resolved': DispatchResolvedData;
|
|
@@ -3335,6 +3406,37 @@ export interface BacklinksResponse {
|
|
|
3335
3406
|
next_cursor?: string;
|
|
3336
3407
|
}
|
|
3337
3408
|
|
|
3409
|
+
/**
|
|
3410
|
+
* Request for POST /orgs/{orgId}/refs/outbound — two mutually exclusive
|
|
3411
|
+
* forms, modeled as a union so an invalid mixed shape fails at compile time:
|
|
3412
|
+
* `thread_root_id` resolves a thread's message set server-side (root + ALL
|
|
3413
|
+
* non-deleted replies — the client's reply window may be partial), while
|
|
3414
|
+
* `source_type` + `source_ids` lists explicit sources (max 500; v1 accepts
|
|
3415
|
+
* only `message` sources).
|
|
3416
|
+
*/
|
|
3417
|
+
export type OutboundRefsRequest =
|
|
3418
|
+
| { thread_root_id: string; source_type?: never; source_ids?: never }
|
|
3419
|
+
| { source_type: string; source_ids: string[]; thread_root_id?: never };
|
|
3420
|
+
|
|
3421
|
+
/** One raw ref_links row; dedupe/grouping is a client concern. */
|
|
3422
|
+
export interface OutboundRefItem {
|
|
3423
|
+
uri: string;
|
|
3424
|
+
target_type: string;
|
|
3425
|
+
target_id: string;
|
|
3426
|
+
target_path?: string;
|
|
3427
|
+
target_frag?: string;
|
|
3428
|
+
context?: string;
|
|
3429
|
+
source_type: string;
|
|
3430
|
+
source_id: string;
|
|
3431
|
+
position: number;
|
|
3432
|
+
}
|
|
3433
|
+
|
|
3434
|
+
export interface OutboundRefsResponse {
|
|
3435
|
+
data: OutboundRefItem[];
|
|
3436
|
+
/** Set when the server-side sanity cap dropped the tail of the row set. */
|
|
3437
|
+
truncated?: boolean;
|
|
3438
|
+
}
|
|
3439
|
+
|
|
3338
3440
|
/**
|
|
3339
3441
|
* One entity in a multi-hop ref-graph traversal (GET /refs/graph). `id`/`uri` are
|
|
3340
3442
|
* the ref_links endpoint identifier: a bare prll:// entity id for most nodes
|
|
@@ -3976,6 +4078,29 @@ export interface BrowserViewerCommandResponse {
|
|
|
3976
4078
|
result: Record<string, unknown> | null;
|
|
3977
4079
|
}
|
|
3978
4080
|
|
|
4081
|
+
/**
|
|
4082
|
+
* Cloud Edge live viewer (V1b, design §6). Same request/reply shape as the v2
|
|
4083
|
+
* browser-profile viewer — the transport-agnostic `BrowserViewer` client drives
|
|
4084
|
+
* either — but a distinct type so the edge viewer surface never depends on the
|
|
4085
|
+
* v2 browser-profile viewer symbols.
|
|
4086
|
+
*/
|
|
4087
|
+
export interface EdgeViewerCommandRequest {
|
|
4088
|
+
/** Correlates a viewer session. Omit on `stream.start`; the server returns one. */
|
|
4089
|
+
session_id?: string;
|
|
4090
|
+
command: string;
|
|
4091
|
+
input?: Record<string, unknown>;
|
|
4092
|
+
}
|
|
4093
|
+
|
|
4094
|
+
export interface EdgeViewerCommandResponse {
|
|
4095
|
+
session_id: string;
|
|
4096
|
+
/**
|
|
4097
|
+
* Command-specific result. For `stream.start`:
|
|
4098
|
+
* `{ offer_sdp, candidates, ice_servers, streamed_tab_id }`. May be `null` on
|
|
4099
|
+
* the wire (a nil Go result map serializes as JSON null); coalesce to `{}`.
|
|
4100
|
+
*/
|
|
4101
|
+
result: Record<string, unknown> | null;
|
|
4102
|
+
}
|
|
4103
|
+
|
|
3979
4104
|
export interface GrantBrowserProfileConsentRequest {
|
|
3980
4105
|
clip_id: string;
|
|
3981
4106
|
}
|
|
@@ -4187,6 +4312,45 @@ export interface EdgeBrowserProfile {
|
|
|
4187
4312
|
is_default: boolean;
|
|
4188
4313
|
created_at: string;
|
|
4189
4314
|
updated_at: string;
|
|
4315
|
+
/**
|
|
4316
|
+
* True when the profile has a fixed egress proxy configured (hosted Cloud
|
|
4317
|
+
* Profiles). Presence flag only — endpoint/username/password are readable
|
|
4318
|
+
* exclusively by managers via the dedicated proxy endpoint, and the password
|
|
4319
|
+
* never leaves the server.
|
|
4320
|
+
*/
|
|
4321
|
+
proxy_configured?: boolean;
|
|
4322
|
+
}
|
|
4323
|
+
|
|
4324
|
+
/**
|
|
4325
|
+
* Sanitized per-profile egress proxy status (hosted Cloud Profiles) — the GET
|
|
4326
|
+
* response and the PUT/DELETE result. NEVER carries the password; `password_set`
|
|
4327
|
+
* is the only trace of it.
|
|
4328
|
+
*/
|
|
4329
|
+
export interface EdgeProfileProxyStatus {
|
|
4330
|
+
configured: boolean;
|
|
4331
|
+
server?: string;
|
|
4332
|
+
username?: string;
|
|
4333
|
+
password_set: boolean;
|
|
4334
|
+
/** Opaque compare-and-swap token for conditional PUT/DELETE. */
|
|
4335
|
+
version: string;
|
|
4336
|
+
/** Authoritative mutation gate; false whenever a non-released lease exists. */
|
|
4337
|
+
can_mutate: boolean;
|
|
4338
|
+
/** Actual lease state blocking a mutation (never inferred from device status). */
|
|
4339
|
+
lease_status?: 'pending' | 'assigned' | 'active' | 'releasing' | 'repair';
|
|
4340
|
+
/** Suggested delay before re-reading authoritative state. */
|
|
4341
|
+
retry_after_seconds?: number;
|
|
4342
|
+
}
|
|
4343
|
+
|
|
4344
|
+
/**
|
|
4345
|
+
* PUT body for a profile's egress proxy: the FULL triple every time (no
|
|
4346
|
+
* tri-state merge — the stored blob is encrypted, so replace always re-supplies
|
|
4347
|
+
* complete credentials). Clearing is DELETE, never an empty PUT. Username and
|
|
4348
|
+
* password go together or not at all.
|
|
4349
|
+
*/
|
|
4350
|
+
export interface SetEdgeProfileProxyRequest {
|
|
4351
|
+
server: string;
|
|
4352
|
+
username?: string;
|
|
4353
|
+
password?: string;
|
|
4190
4354
|
}
|
|
4191
4355
|
|
|
4192
4356
|
export interface ClipConnection {
|