@parall/sdk 1.55.0 → 1.55.2
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 +36 -7
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +44 -5
- package/dist/constants.d.ts +8 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +11 -0
- package/dist/project-task-client.d.ts +33 -1
- package/dist/project-task-client.d.ts.map +1 -1
- package/dist/project-task-client.js +56 -0
- package/dist/subject.d.ts +7 -10
- package/dist/subject.d.ts.map +1 -1
- package/dist/subject.js +22 -31
- package/dist/types.d.ts +231 -22
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +80 -6
- package/src/constants.ts +17 -0
- package/src/project-task-client.ts +93 -0
- package/src/subject.ts +23 -32
- package/src/types.ts +255 -24
|
@@ -114,4 +114,60 @@ export class ProjectTaskClient {
|
|
|
114
114
|
async deleteProject(orgId, projectId) {
|
|
115
115
|
return this.request('DELETE', ENDPOINTS.PROJECT(orgId, projectId));
|
|
116
116
|
}
|
|
117
|
+
/** Roster with display info; readable by anyone who can read the project. */
|
|
118
|
+
async getProjectMembers(orgId, projectId) {
|
|
119
|
+
const res = await this.request('GET', ENDPOINTS.PROJECT_MEMBERS(orgId, projectId));
|
|
120
|
+
return res.data;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* User IDs who may read the project — the assignee-eligibility set. Every
|
|
124
|
+
* tier answers the roster expansion (direct, team-reached, org
|
|
125
|
+
* owners/admins); visibility only shapes admission, never reach.
|
|
126
|
+
*/
|
|
127
|
+
async getProjectReaders(orgId, projectId) {
|
|
128
|
+
const res = await this.request('GET', ENDPOINTS.PROJECT_READERS(orgId, projectId));
|
|
129
|
+
return res.data;
|
|
130
|
+
}
|
|
131
|
+
/** The join library: every discoverable project (public + restricted, plus
|
|
132
|
+
* private for org owners/admins) with the caller's admission state. */
|
|
133
|
+
async getProjectLibrary(orgId) {
|
|
134
|
+
const res = await this.request('GET', ENDPOINTS.PROJECT_LIBRARY(orgId));
|
|
135
|
+
return res.data;
|
|
136
|
+
}
|
|
137
|
+
/** Public-tier self-admission: writes the caller's own member row.
|
|
138
|
+
* Other tiers answer `404 PROJECT_NOT_FOUND`; a duplicate answers
|
|
139
|
+
* `409 MEMBER_EXISTS`. */
|
|
140
|
+
async joinProject(orgId, projectId) {
|
|
141
|
+
return this.request('POST', ENDPOINTS.PROJECT_JOIN(orgId, projectId));
|
|
142
|
+
}
|
|
143
|
+
/** Restricted-tier admission petition. A pending duplicate answers
|
|
144
|
+
* `409 REQUEST_EXISTS`; membership answers `409 MEMBER_EXISTS`. */
|
|
145
|
+
async createProjectJoinRequest(orgId, projectId) {
|
|
146
|
+
return this.request('POST', ENDPOINTS.PROJECT_JOIN_REQUESTS(orgId, projectId));
|
|
147
|
+
}
|
|
148
|
+
/** Pending petitions for one project — manager standing required. */
|
|
149
|
+
async listProjectJoinRequests(orgId, projectId) {
|
|
150
|
+
const res = await this.request('GET', ENDPOINTS.PROJECT_JOIN_REQUESTS(orgId, projectId));
|
|
151
|
+
return res.data;
|
|
152
|
+
}
|
|
153
|
+
/** Withdraws the caller's own pending petition. */
|
|
154
|
+
async cancelProjectJoinRequest(orgId, projectId) {
|
|
155
|
+
return this.request('DELETE', ENDPOINTS.PROJECT_JOIN_REQUESTS(orgId, projectId));
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Adds one subject (user ID or team ID) to the roster. Manager-only,
|
|
159
|
+
* create-only: an existing row answers `409 MEMBER_EXISTS` — change roles
|
|
160
|
+
* through updateProjectMember instead.
|
|
161
|
+
*/
|
|
162
|
+
async addProjectMember(orgId, projectId, req) {
|
|
163
|
+
return this.request('POST', ENDPOINTS.PROJECT_MEMBERS(orgId, projectId), req);
|
|
164
|
+
}
|
|
165
|
+
/** Sets one roster entry's role. Demoting the last manager answers `400 LAST_MANAGER`. */
|
|
166
|
+
async updateProjectMember(orgId, projectId, subject, req) {
|
|
167
|
+
return this.request('PATCH', ENDPOINTS.PROJECT_MEMBER(orgId, projectId, subject), req);
|
|
168
|
+
}
|
|
169
|
+
/** Removes one roster entry. Removing the last manager answers `400 LAST_MANAGER`. */
|
|
170
|
+
async removeProjectMember(orgId, projectId, subject) {
|
|
171
|
+
return this.request('DELETE', ENDPOINTS.PROJECT_MEMBER(orgId, projectId, subject));
|
|
172
|
+
}
|
|
117
173
|
}
|
package/dist/subject.d.ts
CHANGED
|
@@ -2,11 +2,10 @@
|
|
|
2
2
|
export type SubjectKind = 'wildcard' | 'user' | 'team';
|
|
3
3
|
export interface ParsedSubject {
|
|
4
4
|
kind: SubjectKind;
|
|
5
|
-
/** Empty for wildcard, user ID for user, and
|
|
5
|
+
/** Empty for wildcard, user ID for user, and the full team ID for team. */
|
|
6
6
|
value: string;
|
|
7
7
|
}
|
|
8
|
-
export declare function
|
|
9
|
-
export declare function formatTeamSubject(slug: string): string;
|
|
8
|
+
export declare function isTeamSubject(token: string): boolean;
|
|
10
9
|
export declare function parseSubjectToken(token: string): ParsedSubject;
|
|
11
10
|
/**
|
|
12
11
|
* Maximum distinct team references one ACL row may carry. Mirrors
|
|
@@ -14,12 +13,10 @@ export declare function parseSubjectToken(token: string): ParsedSubject;
|
|
|
14
13
|
*/
|
|
15
14
|
export declare const MAX_TEAM_SUBJECTS_PER_WRITE = 200;
|
|
16
15
|
/**
|
|
17
|
-
* Returns unique team
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* check and be reported missing, so the write fails with a legible error
|
|
22
|
-
* instead of storing a token that matches nobody.
|
|
16
|
+
* Returns unique team IDs in first-seen order for batched write validation.
|
|
17
|
+
* An ID that names no team comes back from the server's existence check
|
|
18
|
+
* reported missing, so the write fails with a legible error instead of
|
|
19
|
+
* storing a token that matches nobody.
|
|
23
20
|
*/
|
|
24
|
-
export declare function
|
|
21
|
+
export declare function teamIdsFromSubjects(subjects: readonly string[]): string[];
|
|
25
22
|
//# sourceMappingURL=subject.d.ts.map
|
package/dist/subject.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subject.d.ts","sourceRoot":"","sources":["../src/subject.ts"],"names":[],"mappings":"AAAA,iFAAiF;AAEjF,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,MAAM,GAAG,MAAM,CAAC;AAEvD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,WAAW,CAAC;IAClB,2EAA2E;IAC3E,KAAK,EAAE,MAAM,CAAC;CACf;
|
|
1
|
+
{"version":3,"file":"subject.d.ts","sourceRoot":"","sources":["../src/subject.ts"],"names":[],"mappings":"AAAA,iFAAiF;AAEjF,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,MAAM,GAAG,MAAM,CAAC;AAEvD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,WAAW,CAAC;IAClB,2EAA2E;IAC3E,KAAK,EAAE,MAAM,CAAC;CACf;AAUD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,CAW9D;AAED;;;GAGG;AACH,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAE/C;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CASzE"}
|
package/dist/subject.js
CHANGED
|
@@ -1,28 +1,24 @@
|
|
|
1
1
|
/** Shared ACL subject token helpers for clients that edit permission rosters. */
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
return
|
|
2
|
+
/**
|
|
3
|
+
* Team subjects are stored as bare team IDs (`team_...`), mirroring the
|
|
4
|
+
* server's `pkg/subject`: the ID prefix is what makes a token a team
|
|
5
|
+
* reference, so no marker syntax exists and a rename never invalidates a
|
|
6
|
+
* stored reference.
|
|
7
|
+
*/
|
|
8
|
+
const TEAM_ID_PREFIX = 'team_';
|
|
9
|
+
export function isTeamSubject(token) {
|
|
10
|
+
return token.startsWith(TEAM_ID_PREFIX);
|
|
11
11
|
}
|
|
12
12
|
export function parseSubjectToken(token) {
|
|
13
13
|
if (token === '*') {
|
|
14
14
|
return { kind: 'wildcard', value: '' };
|
|
15
15
|
}
|
|
16
|
-
if (token.startsWith('@')) {
|
|
17
|
-
const slug = token.slice(1);
|
|
18
|
-
if (!isValidTeamSlug(slug)) {
|
|
19
|
-
throw new Error(`Invalid team subject: ${token}`);
|
|
20
|
-
}
|
|
21
|
-
return { kind: 'team', value: slug };
|
|
22
|
-
}
|
|
23
16
|
if (!token) {
|
|
24
17
|
throw new Error('Subject token is empty');
|
|
25
18
|
}
|
|
19
|
+
if (isTeamSubject(token)) {
|
|
20
|
+
return { kind: 'team', value: token };
|
|
21
|
+
}
|
|
26
22
|
return { kind: 'user', value: token };
|
|
27
23
|
}
|
|
28
24
|
/**
|
|
@@ -31,24 +27,19 @@ export function parseSubjectToken(token) {
|
|
|
31
27
|
*/
|
|
32
28
|
export const MAX_TEAM_SUBJECTS_PER_WRITE = 200;
|
|
33
29
|
/**
|
|
34
|
-
* Returns unique team
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* check and be reported missing, so the write fails with a legible error
|
|
39
|
-
* instead of storing a token that matches nobody.
|
|
30
|
+
* Returns unique team IDs in first-seen order for batched write validation.
|
|
31
|
+
* An ID that names no team comes back from the server's existence check
|
|
32
|
+
* reported missing, so the write fails with a legible error instead of
|
|
33
|
+
* storing a token that matches nobody.
|
|
40
34
|
*/
|
|
41
|
-
export function
|
|
35
|
+
export function teamIdsFromSubjects(subjects) {
|
|
42
36
|
const seen = new Set();
|
|
43
|
-
const
|
|
37
|
+
const ids = [];
|
|
44
38
|
for (const token of subjects) {
|
|
45
|
-
if (!token.
|
|
46
|
-
continue;
|
|
47
|
-
const slug = token.slice(1);
|
|
48
|
-
if (!slug || seen.has(slug))
|
|
39
|
+
if (!isTeamSubject(token) || seen.has(token))
|
|
49
40
|
continue;
|
|
50
|
-
seen.add(
|
|
51
|
-
|
|
41
|
+
seen.add(token);
|
|
42
|
+
ids.push(token);
|
|
52
43
|
}
|
|
53
|
-
return
|
|
44
|
+
return ids;
|
|
54
45
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -381,7 +381,8 @@ export interface Team {
|
|
|
381
381
|
id: string;
|
|
382
382
|
org_id: string;
|
|
383
383
|
name: string;
|
|
384
|
-
slug
|
|
384
|
+
/** @deprecated Removed since migration 176 — teams have no slug anymore. */
|
|
385
|
+
slug?: string;
|
|
385
386
|
created_by: string;
|
|
386
387
|
created_at: string;
|
|
387
388
|
updated_at: string;
|
|
@@ -411,12 +412,11 @@ export interface TeamMember {
|
|
|
411
412
|
}
|
|
412
413
|
export interface CreateTeamRequest {
|
|
413
414
|
name: string;
|
|
414
|
-
|
|
415
|
+
/** @deprecated Accepted and ignored by the server since migration 176. */
|
|
416
|
+
slug?: string;
|
|
415
417
|
}
|
|
416
418
|
export interface UpdateTeamRequest {
|
|
417
419
|
name: string;
|
|
418
|
-
/** Team slugs are immutable because wiki ACL rows store them as @slug. */
|
|
419
|
-
slug?: never;
|
|
420
420
|
}
|
|
421
421
|
export interface AddTeamMemberRequest {
|
|
422
422
|
user_id: string;
|
|
@@ -839,11 +839,6 @@ export interface DirectMessageResponse {
|
|
|
839
839
|
chat: Chat;
|
|
840
840
|
message: Message;
|
|
841
841
|
}
|
|
842
|
-
export interface JsonPatchOp {
|
|
843
|
-
op: 'replace' | 'add';
|
|
844
|
-
path: string;
|
|
845
|
-
value: unknown;
|
|
846
|
-
}
|
|
847
842
|
export interface CreateAgentRequest {
|
|
848
843
|
display_name: string;
|
|
849
844
|
agent_provider?: string;
|
|
@@ -1241,7 +1236,8 @@ export interface Task {
|
|
|
1241
1236
|
assignee_id: string | null;
|
|
1242
1237
|
creator_id: string;
|
|
1243
1238
|
parent_id: string | null;
|
|
1244
|
-
|
|
1239
|
+
/** Every Task belongs to exactly one Project; immutable after creation. */
|
|
1240
|
+
project_id: string;
|
|
1245
1241
|
seq_number: number | null;
|
|
1246
1242
|
identifier: string | null;
|
|
1247
1243
|
sort_order: number;
|
|
@@ -1265,7 +1261,7 @@ export interface Task {
|
|
|
1265
1261
|
deleted_at?: string | null;
|
|
1266
1262
|
/**
|
|
1267
1263
|
* Per-viewer: whether the requesting user may manage OTHER members' comment
|
|
1268
|
-
* subscriptions for this task (creator / assignee / project
|
|
1264
|
+
* subscriptions for this task (creator / assignee / project manager / org
|
|
1269
1265
|
* owner-admin). Populated on single-task GET; undefined elsewhere. Read this to
|
|
1270
1266
|
* gate subscriber-management UI — do not re-derive the rule client-side.
|
|
1271
1267
|
*/
|
|
@@ -1333,7 +1329,13 @@ export interface CreateTaskRequest {
|
|
|
1333
1329
|
priority?: TaskPriority;
|
|
1334
1330
|
assignee_id?: string;
|
|
1335
1331
|
parent_id?: string;
|
|
1336
|
-
|
|
1332
|
+
/**
|
|
1333
|
+
* Required: every Task is created inside a Project (missing → 400
|
|
1334
|
+
* MISSING_FIELDS with `error.details.available_projects`; archived project →
|
|
1335
|
+
* 400 PROJECT_ARCHIVED). A parent task's subtasks must use the parent's
|
|
1336
|
+
* project (400 INVALID_PARENT otherwise). Immutable after creation.
|
|
1337
|
+
*/
|
|
1338
|
+
project_id: string;
|
|
1337
1339
|
source_chat_id?: string;
|
|
1338
1340
|
sort_order?: number;
|
|
1339
1341
|
/** Planned start date, YYYY-MM-DD. Must be <= due_date when both are set. */
|
|
@@ -1349,7 +1351,6 @@ export interface UpdateTaskRequest {
|
|
|
1349
1351
|
priority?: TaskPriority;
|
|
1350
1352
|
assignee_id?: string | null;
|
|
1351
1353
|
parent_id?: string | null;
|
|
1352
|
-
project_id?: string | null;
|
|
1353
1354
|
sort_order?: number;
|
|
1354
1355
|
/**
|
|
1355
1356
|
* Ordering intent resolved server-side in the update transaction:
|
|
@@ -1389,34 +1390,114 @@ export interface CreateTaskRelationRequest {
|
|
|
1389
1390
|
relation_type: TaskRelationType;
|
|
1390
1391
|
}
|
|
1391
1392
|
export type ProjectStatus = 'active' | 'paused' | 'completed' | 'archived';
|
|
1393
|
+
/** Visibility only decides how someone becomes a member (self-join /
|
|
1394
|
+
* request+approval / invite-only); membership rights are identical on every
|
|
1395
|
+
* tier, and reads are always roster-scoped. */
|
|
1396
|
+
export type ProjectVisibility = 'public' | 'restricted' | 'private';
|
|
1397
|
+
/** A role held on a project roster. Managers administer the project; members
|
|
1398
|
+
* only reach it. Org owners and admins are implicit managers everywhere, which
|
|
1399
|
+
* is why a project can never become unmanageable. */
|
|
1400
|
+
export type ProjectRole = 'member' | 'manager';
|
|
1392
1401
|
export interface Project {
|
|
1393
1402
|
id: string;
|
|
1394
1403
|
org_id: string;
|
|
1395
1404
|
name: string;
|
|
1396
1405
|
key: string;
|
|
1397
1406
|
description: string | null;
|
|
1398
|
-
lead_id: string | null;
|
|
1399
1407
|
status: ProjectStatus;
|
|
1408
|
+
visibility: ProjectVisibility;
|
|
1400
1409
|
color: string | null;
|
|
1401
1410
|
sort_order: number;
|
|
1402
1411
|
created_at: string;
|
|
1403
1412
|
updated_at: string;
|
|
1413
|
+
/** The requesting user's own role, computed per request rather than stored.
|
|
1414
|
+
* Absent means they hold no membership (direct or team-derived). */
|
|
1415
|
+
my_role?: ProjectRole;
|
|
1416
|
+
/** True when the requesting user holds their own roster row — the fact
|
|
1417
|
+
* Leave acts on, as opposed to team-derived or org-admin standing. */
|
|
1418
|
+
my_direct_member?: boolean;
|
|
1419
|
+
/**
|
|
1420
|
+
* @deprecated Project authority now comes from the project roster. Retained
|
|
1421
|
+
* only for source compatibility during the pre-GA migration window; current
|
|
1422
|
+
* API responses omit it.
|
|
1423
|
+
*/
|
|
1424
|
+
lead_id?: string | null;
|
|
1425
|
+
}
|
|
1426
|
+
/** One join-library row: the minimal metadata a non-member may see about a
|
|
1427
|
+
* discoverable project, plus the caller's own admission state. */
|
|
1428
|
+
export interface ProjectLibraryEntry {
|
|
1429
|
+
id: string;
|
|
1430
|
+
name: string;
|
|
1431
|
+
key: string;
|
|
1432
|
+
color?: string | null;
|
|
1433
|
+
visibility: ProjectVisibility;
|
|
1434
|
+
joined: boolean;
|
|
1435
|
+
requested: boolean;
|
|
1436
|
+
}
|
|
1437
|
+
/** One pending join request, as the Collaborators pending tab renders it. */
|
|
1438
|
+
export interface ProjectJoinRequest {
|
|
1439
|
+
id: string;
|
|
1440
|
+
requester_id: string;
|
|
1441
|
+
created_at: string;
|
|
1442
|
+
requester?: User;
|
|
1443
|
+
}
|
|
1444
|
+
/** One roster entry. `subject` is a bare user ID or a bare team ID; exactly one
|
|
1445
|
+
* of `user` / `team` is filled in for display, according to which kind it is. */
|
|
1446
|
+
export interface ProjectMember {
|
|
1447
|
+
project_id: string;
|
|
1448
|
+
subject: string;
|
|
1449
|
+
role: ProjectRole;
|
|
1450
|
+
added_by?: string;
|
|
1451
|
+
added_at: string;
|
|
1452
|
+
user?: User;
|
|
1453
|
+
team?: Team;
|
|
1454
|
+
}
|
|
1455
|
+
/**
|
|
1456
|
+
* Adds one subject to a project's roster. Create-only: an existing row answers
|
|
1457
|
+
* `409 MEMBER_EXISTS` rather than being mutated — role changes go through the
|
|
1458
|
+
* member role endpoint. A subject naming nobody reachable answers
|
|
1459
|
+
* `400 UNKNOWN_SUBJECT`. Member rows are storable on every tier.
|
|
1460
|
+
*/
|
|
1461
|
+
export interface AddProjectMemberRequest {
|
|
1462
|
+
/** A bare user ID, or a bare team ID (`team_...`) for a team. */
|
|
1463
|
+
subject: string;
|
|
1464
|
+
/** Defaults to `member` when omitted. */
|
|
1465
|
+
role?: ProjectRole;
|
|
1466
|
+
}
|
|
1467
|
+
/**
|
|
1468
|
+
* Changes one roster entry's role. Demoting the last manager answers
|
|
1469
|
+
* `400 LAST_MANAGER`; a concurrent roster change answers `409 CONFLICT`.
|
|
1470
|
+
*/
|
|
1471
|
+
export interface UpdateProjectMemberRequest {
|
|
1472
|
+
role: ProjectRole;
|
|
1404
1473
|
}
|
|
1405
1474
|
export interface CreateProjectRequest {
|
|
1406
1475
|
name: string;
|
|
1407
1476
|
key?: string;
|
|
1408
1477
|
description?: string;
|
|
1409
|
-
|
|
1478
|
+
/** Defaults to `public` when omitted. The creator is always written as the
|
|
1479
|
+
* first manager, which is what naming yourself lead used to mean. */
|
|
1480
|
+
visibility?: ProjectVisibility;
|
|
1410
1481
|
color?: string;
|
|
1482
|
+
/**
|
|
1483
|
+
* @deprecated Use the project roster after creation. Retained only for
|
|
1484
|
+
* source compatibility; the current API ignores this retired field.
|
|
1485
|
+
*/
|
|
1486
|
+
lead_id?: string;
|
|
1411
1487
|
}
|
|
1412
1488
|
export interface UpdateProjectRequest {
|
|
1413
1489
|
name?: string;
|
|
1414
1490
|
key?: string;
|
|
1415
1491
|
description?: string | null;
|
|
1416
|
-
lead_id?: string | null;
|
|
1417
1492
|
status?: ProjectStatus;
|
|
1493
|
+
visibility?: ProjectVisibility;
|
|
1418
1494
|
color?: string | null;
|
|
1419
1495
|
sort_order?: number;
|
|
1496
|
+
/**
|
|
1497
|
+
* @deprecated Use the project roster. Retained only for source
|
|
1498
|
+
* compatibility; the current API ignores this retired field.
|
|
1499
|
+
*/
|
|
1500
|
+
lead_id?: string | null;
|
|
1420
1501
|
}
|
|
1421
1502
|
export interface ProjectTaskStatusCounts {
|
|
1422
1503
|
todo: number;
|
|
@@ -2137,17 +2218,36 @@ export interface MessageNewData {
|
|
|
2137
2218
|
hints?: MessageHints | null;
|
|
2138
2219
|
attachments?: Attachment[];
|
|
2139
2220
|
}
|
|
2221
|
+
/** @deprecated The `message.patch` event is retired — the server no longer
|
|
2222
|
+
* publishes it (content updates arrive as full-content `message.edit`). Kept
|
|
2223
|
+
* only so existing consumers keep compiling through the deprecation window;
|
|
2224
|
+
* a handler typed with this will never fire. */
|
|
2225
|
+
export interface JsonPatchOp {
|
|
2226
|
+
op: 'replace' | 'add';
|
|
2227
|
+
path: string;
|
|
2228
|
+
value: unknown;
|
|
2229
|
+
}
|
|
2230
|
+
/** @deprecated See {@link JsonPatchOp} — `message.patch` is never published. */
|
|
2140
2231
|
export interface MessagePatchData {
|
|
2141
2232
|
message_id: string;
|
|
2142
2233
|
chat_id: string;
|
|
2143
2234
|
version: number;
|
|
2144
2235
|
ops: JsonPatchOp[];
|
|
2145
2236
|
}
|
|
2237
|
+
/**
|
|
2238
|
+
* Unified message-content-update event: every persisted content write (author
|
|
2239
|
+
* edit, server link-preview write-back) publishes it with the full content and
|
|
2240
|
+
* post-write version. Apply only when `version` is greater than the local one;
|
|
2241
|
+
* the "(edited)" marker keys off `edited_at` alone — a preview write-back
|
|
2242
|
+
* never creates or changes edited state (it carries the pre-existing value,
|
|
2243
|
+
* absent when the message was never author-edited).
|
|
2244
|
+
*/
|
|
2146
2245
|
export interface MessageEditData {
|
|
2147
2246
|
message_id: string;
|
|
2148
2247
|
chat_id: string;
|
|
2149
2248
|
content: MessageContent;
|
|
2150
|
-
|
|
2249
|
+
version: number;
|
|
2250
|
+
edited_at?: string;
|
|
2151
2251
|
}
|
|
2152
2252
|
export interface MessageDeleteData {
|
|
2153
2253
|
message_id: string;
|
|
@@ -3049,6 +3149,7 @@ export interface NotificationAlertData {
|
|
|
3049
3149
|
export type WsEventMap = {
|
|
3050
3150
|
hello: HelloData;
|
|
3051
3151
|
'message.new': MessageNewData;
|
|
3152
|
+
/** @deprecated Never published anymore — kept so existing `ws.on('message.patch', …)` registrations keep compiling. */
|
|
3052
3153
|
'message.patch': MessagePatchData;
|
|
3053
3154
|
'message.edit': MessageEditData;
|
|
3054
3155
|
'message.delete': MessageDeleteData;
|
|
@@ -3220,6 +3321,8 @@ export interface ResolvedRef {
|
|
|
3220
3321
|
message_type?: string;
|
|
3221
3322
|
created_at?: string;
|
|
3222
3323
|
attachments?: Attachment[];
|
|
3324
|
+
quoted_text?: string;
|
|
3325
|
+
quote_from_edited?: boolean;
|
|
3223
3326
|
range_messages?: Array<{
|
|
3224
3327
|
id: string;
|
|
3225
3328
|
sender_id: string;
|
|
@@ -4079,6 +4182,51 @@ export interface SetEdgeProfileProxyRequest {
|
|
|
4079
4182
|
username?: string;
|
|
4080
4183
|
password?: string;
|
|
4081
4184
|
}
|
|
4185
|
+
/**
|
|
4186
|
+
* One normalized cookie in a hosted-profile cookie-seed import — the exact shape
|
|
4187
|
+
* the pod-side `session.cookies.set()` consumes (mirrors the desktop
|
|
4188
|
+
* cookie-import output). Web parses the manager's paste (a raw `Cookie` header +
|
|
4189
|
+
* target domain, or a Cookie-Editor JSON export) into an array of these before
|
|
4190
|
+
* the PUT. Values are write-only; the sanitized status never echoes them.
|
|
4191
|
+
*/
|
|
4192
|
+
export interface EdgeCookie {
|
|
4193
|
+
url: string;
|
|
4194
|
+
name: string;
|
|
4195
|
+
value: string;
|
|
4196
|
+
domain: string;
|
|
4197
|
+
path: string;
|
|
4198
|
+
secure: boolean;
|
|
4199
|
+
httpOnly: boolean;
|
|
4200
|
+
/** Unix epoch seconds; null for a session cookie (no persisted expiry). */
|
|
4201
|
+
expirationDate: number | null;
|
|
4202
|
+
sameSite: 'no_restriction' | 'lax' | 'strict' | null;
|
|
4203
|
+
}
|
|
4204
|
+
/**
|
|
4205
|
+
* PUT body for a hosted profile's one-shot cookie seed: the full normalized
|
|
4206
|
+
* cookie array. Injected at the next cold start and consumed once. Clearing is
|
|
4207
|
+
* DELETE, never an empty PUT.
|
|
4208
|
+
*/
|
|
4209
|
+
export interface SetEdgeCookieSeedRequest {
|
|
4210
|
+
cookies: EdgeCookie[];
|
|
4211
|
+
}
|
|
4212
|
+
/**
|
|
4213
|
+
* Sanitized cookie-seed status (hosted Cloud Profiles) — the GET response and
|
|
4214
|
+
* the PUT/DELETE result. NEVER carries cookie values: only the count and the
|
|
4215
|
+
* distinct target domains are exposed.
|
|
4216
|
+
*/
|
|
4217
|
+
export interface EdgeCookieSeedStatus {
|
|
4218
|
+
configured: boolean;
|
|
4219
|
+
cookie_count: number;
|
|
4220
|
+
domains: string[];
|
|
4221
|
+
/** Opaque compare-and-swap token for conditional PUT/DELETE (`cookieseed-<version>` ETag). */
|
|
4222
|
+
version: string;
|
|
4223
|
+
/** Authoritative mutation gate; false whenever a non-released lease exists. */
|
|
4224
|
+
can_mutate: boolean;
|
|
4225
|
+
/** Actual lease state blocking a mutation (never inferred from device status). */
|
|
4226
|
+
lease_status?: 'pending' | 'assigned' | 'active' | 'releasing' | 'repair';
|
|
4227
|
+
/** Suggested delay before re-reading authoritative state. */
|
|
4228
|
+
retry_after_seconds?: number | null;
|
|
4229
|
+
}
|
|
4082
4230
|
export interface ClipConnection {
|
|
4083
4231
|
id: string;
|
|
4084
4232
|
clip_id: string;
|
|
@@ -4100,7 +4248,17 @@ export interface ClipConnection {
|
|
|
4100
4248
|
* would make `putClipMCPConfig({auth_type: 'oauth'})` type-legal while its
|
|
4101
4249
|
* declared return type is wrong. Reads use MCPConfigAuthType.
|
|
4102
4250
|
*/
|
|
4103
|
-
export type MCPAuthType = 'none' | 'bearer' | 'api_key';
|
|
4251
|
+
export type MCPAuthType = 'none' | 'bearer' | 'api_key' | 'basic';
|
|
4252
|
+
/**
|
|
4253
|
+
* One declared credential input of an `api_key` clip (manifest
|
|
4254
|
+
* `mcp.auth_headers`): the header the value is delivered in and, for
|
|
4255
|
+
* `Authorization`, the `Bearer` scheme prefix. `bearer` remains the legacy
|
|
4256
|
+
* alias for the single `Authorization: Bearer` shape.
|
|
4257
|
+
*/
|
|
4258
|
+
export interface MCPAuthHeaderSlot {
|
|
4259
|
+
name: string;
|
|
4260
|
+
scheme?: 'Bearer';
|
|
4261
|
+
}
|
|
4104
4262
|
/**
|
|
4105
4263
|
* MCP clip auth modes a config can REPORT. A config authorized through the
|
|
4106
4264
|
* OAuth flow reads back as `oauth`, so every reader must handle it even
|
|
@@ -4218,9 +4376,20 @@ export interface MCPConfigResponse {
|
|
|
4218
4376
|
* persists nothing.
|
|
4219
4377
|
*/
|
|
4220
4378
|
export interface MCPConfigPutRequest {
|
|
4379
|
+
/**
|
|
4380
|
+
* Required on the wire, but when the clip's manifest declares the server
|
|
4381
|
+
* an empty string means "use the declaration" — the server fills it in and
|
|
4382
|
+
* refuses a contradicting value. (The Console sends '' for declared clips.)
|
|
4383
|
+
*/
|
|
4221
4384
|
server_url: string;
|
|
4222
4385
|
auth_type: MCPAuthType;
|
|
4223
4386
|
credential?: string;
|
|
4387
|
+
/**
|
|
4388
|
+
* Slot-aligned multi-value form: one value per declared `auth_headers`
|
|
4389
|
+
* slot, or `[username, password]` for `basic`. Mutually exclusive with
|
|
4390
|
+
* `credential`.
|
|
4391
|
+
*/
|
|
4392
|
+
credentials?: string[];
|
|
4224
4393
|
}
|
|
4225
4394
|
/**
|
|
4226
4395
|
* POST body of `…/clip-registry/{clipId}/mcp-configs` — a NEW connection
|
|
@@ -4238,6 +4407,8 @@ export interface MCPConfigCreateRequest {
|
|
|
4238
4407
|
server_url?: string;
|
|
4239
4408
|
auth_type: MCPAuthType | 'oauth';
|
|
4240
4409
|
credential?: string;
|
|
4410
|
+
/** See MCPConfigPutRequest.credentials. */
|
|
4411
|
+
credentials?: string[];
|
|
4241
4412
|
alias?: string;
|
|
4242
4413
|
oauth_client?: MCPOAuthClientParams;
|
|
4243
4414
|
}
|
|
@@ -4340,13 +4511,32 @@ export interface PublishRegistryClipRequest {
|
|
|
4340
4511
|
/** filename → UTF-8 content (e.g. `search.js`). */
|
|
4341
4512
|
files: Record<string, string>;
|
|
4342
4513
|
}
|
|
4514
|
+
/**
|
|
4515
|
+
* One granted agent's entry under `selected_agents` (ADR-019).
|
|
4516
|
+
*
|
|
4517
|
+
* - `connection_scope: 'all'` — the grant covers every connection of the clip
|
|
4518
|
+
* (what a legacy `agent_ids` write means). `connection_ids` must be [].
|
|
4519
|
+
* - `connection_scope: 'selected'` — the grant admits only the connections in
|
|
4520
|
+
* `connection_ids` (non-empty on write; a grant can still READ back with []
|
|
4521
|
+
* when its granted connections were deleted, and then admits nothing).
|
|
4522
|
+
*/
|
|
4523
|
+
export interface ClipAgentExecGrant {
|
|
4524
|
+
agent_id: string;
|
|
4525
|
+
connection_scope: 'all' | 'selected';
|
|
4526
|
+
/** Granted connection ids (`ccn_…`) under `selected`, sorted; [] under `all`. */
|
|
4527
|
+
connection_ids: string[];
|
|
4528
|
+
}
|
|
4343
4529
|
/**
|
|
4344
4530
|
* A clip's per-org agent exec access (`GET/PUT /orgs/{orgId}/clips/{clipId}/exec-access`).
|
|
4345
4531
|
*
|
|
4346
4532
|
* - `all_agents` (default): every org agent may exec the clip.
|
|
4347
|
-
* - `selected_agents`: only the agents in `
|
|
4348
|
-
*
|
|
4349
|
-
* `clips/installed
|
|
4533
|
+
* - `selected_agents`: only the agents in `grants` may exec, each through the
|
|
4534
|
+
* connections its `connection_scope` admits; an empty list blocks every
|
|
4535
|
+
* agent. Denied agents also stop seeing the clip in `clips/installed`; exec
|
|
4536
|
+
* answers `403 CLIP_AGENT_NOT_ALLOWED` (no grant at all) or
|
|
4537
|
+
* `403 CLIP_AGENT_CONNECTION_NOT_ALLOWED` (grant does not cover the named
|
|
4538
|
+
* connection). Agents must always exec through a connection — a
|
|
4539
|
+
* connectionless agent exec answers `400 AGENT_CONNECTION_REQUIRED`.
|
|
4350
4540
|
*
|
|
4351
4541
|
* Decided by the CALLING org (an installer restricts its own agents, never the
|
|
4352
4542
|
* publisher's). Humans are never restricted; the PUT is human-only (an agent
|
|
@@ -4354,8 +4544,23 @@ export interface PublishRegistryClipRequest {
|
|
|
4354
4544
|
*/
|
|
4355
4545
|
export interface ClipAgentExecAccess {
|
|
4356
4546
|
mode: 'all_agents' | 'selected_agents';
|
|
4357
|
-
/**
|
|
4547
|
+
/**
|
|
4548
|
+
* Granted agent user ids under `selected_agents` — the flat projection of
|
|
4549
|
+
* `grants`, kept for older readers; always [] under `all_agents`.
|
|
4550
|
+
*/
|
|
4358
4551
|
agent_ids: string[];
|
|
4552
|
+
/** Per-agent connection scope under `selected_agents`, sorted by agent id. */
|
|
4553
|
+
grants: ClipAgentExecGrant[];
|
|
4554
|
+
}
|
|
4555
|
+
/**
|
|
4556
|
+
* The PUT body for a clip's agent exec access. Two shapes, one semantic
|
|
4557
|
+
* space — pass EITHER `agent_ids` (legacy flat form; every listed agent gets
|
|
4558
|
+
* `connection_scope: 'all'`) OR `grants` (connection-scoped form), never both.
|
|
4559
|
+
*/
|
|
4560
|
+
export interface ClipAgentExecAccessUpdate {
|
|
4561
|
+
mode: 'all_agents' | 'selected_agents';
|
|
4562
|
+
agent_ids?: string[];
|
|
4563
|
+
grants?: ClipAgentExecGrant[];
|
|
4359
4564
|
}
|
|
4360
4565
|
/**
|
|
4361
4566
|
* Execute a registry (Edge) clip command on an Edge device
|
|
@@ -4369,6 +4574,10 @@ export interface ClipAgentExecAccess {
|
|
|
4369
4574
|
* here is refused (`400 HOSTED_CONNECTION_REQUIRED`).
|
|
4370
4575
|
* - neither: legacy BYOC fallback — resolves only to the caller's OWN online
|
|
4371
4576
|
* desktop device, never to a hosted one.
|
|
4577
|
+
*
|
|
4578
|
+
* AGENT principals must always pass `connection` (ADR-019): the device paths
|
|
4579
|
+
* answer `400 AGENT_CONNECTION_REQUIRED`, and a connection outside the agent's
|
|
4580
|
+
* granted scope answers `403 CLIP_AGENT_CONNECTION_NOT_ALLOWED`.
|
|
4372
4581
|
*/
|
|
4373
4582
|
export interface ExecEdgeClipRequest {
|
|
4374
4583
|
/**
|