@collective-intelligence/external-apps-client-sdk 0.1.10 → 0.1.11

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/README.md CHANGED
@@ -5,6 +5,14 @@ The root entrypoint provides federated login, typed CI operations, and direct or
5
5
  same-origin proxy transports. It contains no confidential credentials or
6
6
  framework state.
7
7
 
8
+ The typed transport `execute` method supports `users_create_or_get`, `users_get`,
9
+ `users_list`, `users_deactivate`, `roles_list`, `roles_assign`, and `roles_revoke`
10
+ through the dedicated Application HTTP routes. Supply `organizationId` in the
11
+ execution options. Role assignment inputs use `{ userId, roles }`; an empty
12
+ `roles` array is forwarded unchanged. The backend checks the signed-in user's
13
+ current permissions. Server credentials and Server Role selection belong to the
14
+ Server SDK.
15
+
8
16
  `createFederatedAuth` implements the public OAuth authorization-code flow with
9
17
  PKCE. It validates same-origin return targets, keeps the login transaction in
10
18
  session storage, exchanges the callback code, tracks token expiry, and supports
@@ -134,7 +142,7 @@ authorizes access. They are configuration, never mutation-body authority.
134
142
  including identity, login, logout, and `runs_follow`. `createFixedWorkflowClient`
135
143
  posts a Fixed workflow BFF route and returns `{ runId }`.
136
144
 
137
- The common client exposes `list`, `get`, `create`, `update`, `delete`, and
145
+ The common client exposes `list`, `listMembers`, `get`, `create`, `update`, `delete`, and
138
146
  `upload` (see [File uploads](#file-uploads)).
139
147
  `delete` calls the explicit soft-delete route. Every mutation requires an operation
140
148
  key; update/delete also require the revision originally edited. Reads accept an
@@ -153,6 +161,53 @@ During migration, omitting `protocol` retains the distinct legacy resource facad
153
161
  including its optional update keys, cursor pagination and explicit lifecycle
154
162
  methods. Existing hard-delete behavior is never relabeled as common `delete`.
155
163
 
164
+ ### Relation members
165
+
166
+ `resource.listMembers(parentId, field, query, { signal })` reads a forward or
167
+ inverse relation as an ordinary entity page. `query` uses `EntityListQuery`
168
+ filters, sorting, page pagination and includes on the resolved **member** schema.
169
+ For example:
170
+
171
+ ```ts
172
+ const members = await leads.listMembers("lead-1", "companies", {
173
+ filter: { field: "industry", operator: "eq", value: "Research" },
174
+ sort: [{ field: "industry", direction: "asc" }],
175
+ pagination: { mode: "page", page: 1, pageSize: 25 }
176
+ })
177
+ ```
178
+
179
+ CI transport sends `POST /application/v1/resources/:schemaFqn/records/:parentId/relation-members/search`
180
+ with `{ field, ...query }`. The existing page envelope and exact totals describe
181
+ the authorized filtered membership, including zero/one-member scalar relations.
182
+ Without explicit sorting, forward members use stored position and inverse members
183
+ use source ID order. CI authorizes the parent and members and validates the field.
184
+ A forward field needs no inverse declaration.
185
+
186
+ Member values are `EntityMemberValue` JSON objects, not the parent's generic type;
187
+ the codec validates the entire page and JSON without applying the parent's entity
188
+ schema or query field allowlist. Narrow member values using the member's own
189
+ schema before treating them as a specific application type.
190
+
191
+ Successful pages and root relation-ID values are complete. Included objects
192
+ return complete relation values only for requested next-hop fields; leaf objects
193
+ omit relation fields entirely rather than returning fabricated empty arrays or
194
+ nulls. Ordinary data and File values remain projected. Includes keep the existing
195
+ three-level depth and 100-readable-object per-field cap with explicit `truncated`
196
+ markers; nested include pagination is unavailable. Overall exhaustion fails with
197
+ `invalid_request` and details `{ reason: "read_limit_exceeded", budget }`, where
198
+ `budget` is `work`, `nodes`, `relation_ids` or `bytes`. The `/resources` export
199
+ `isEntityReadLimitError(error)` narrows to `EntityReadLimitDetails`. Narrow the
200
+ query or includes before retrying; these failures expose no member IDs or counts.
201
+ Current request-wide ceilings are 100,000 work units, 2,000 nested object
202
+ occurrences, 50,000 relation-ID occurrences and 8,388,608 accounted bytes.
203
+ Repeated serialized occurrences count even when target reads are deduplicated.
204
+ These are workload ceilings, not a latency or process-memory guarantee. See the
205
+ [limits and measured envelope](../../../docs/reference/knowledge-relation-fields.md#read-limits-and-measured-envelope)
206
+ for scope, recovery and benchmark evidence.
207
+
208
+ Cancellation and malformed responses retain read-only dispatch outcomes and
209
+ correlation IDs.
210
+
156
211
  ## File uploads
157
212
 
158
213
  A File field holds files of a CI entity. The browser sends the file bytes
@@ -205,8 +260,8 @@ deletes an unused one after a retention window. Request a new one to retry.
205
260
  not presign, with `invalid_request` (`details.reason` `not_a_file_field` or
206
261
  `type_not_accepted`) for a field or MIME type the schema refuses, and with
207
262
  `not_found` for an unknown schema. A write that refuses its write form answers
208
- `invalid_request` with `details.field` and `details.reason`; a File field of a
209
- connector-owned entity answers `conflict`.
263
+ `invalid_request` with `details.field` and `details.reason`; a File field a
264
+ connector writes answers `conflict` with `details.field`.
210
265
 
211
266
  ## Workspace development
212
267
 
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { $ as ResourceUpdateRequest, A as ResourceError, At as FederatedAuthOptions, B as ResourceListRequest, C as PortableResourceSchema, Ct as QueryFilter, D as ResourceCreateRequest, Dt as FederatedAuth, E as ResourceCreateInput, Et as ClientFetch, F as ResourceIdentityField, G as ResourceRecord, H as ResourceMutationInput, I as ResourceJsonValue, J as ResourceResult, K as ResourceRecordId, L as ResourceLifecycleInput, M as ResourceFilter, Mt as FederatedSessionIdentity, N as ResourceGetRequest, Nt as createFederatedAuth, O as ResourceCursor, Ot as FederatedAuthError, P as ResourceId, Q as ResourceTransportRequest, R as ResourceLifecycleRequest, S as IdempotencyKey, St as KnowledgeQuery, T as ResourceClient, Tt as WorkflowInvokeTarget, U as ResourcePagination, V as ResourceListResult, W as ResourcePaginationMode, X as ResourceSort, Y as ResourceRevision, Z as ResourceTransport, _ as EntityRequest, _t as isClientOperationId, a as createResourceClient, at as CiResult, b as EntityUploadInput, bt as ConversationHistory, c as EntityDeleteInput, ct as OperationSuccess, d as EntityFileWrite, dt as ClientOperationInput, et as ProxyAuthentication, f as EntityListQuery, ft as ClientOperationMap, g as EntityProtocol, gt as clientOperationIds, h as EntityPage, ht as TypedOperationExecutor, i as createEntityProtocol, it as CiErrorCode, j as ResourceErrorCode, jt as FederatedAuthState, k as ResourceDefinition, kt as FederatedAuthErrorCode, l as EntityFileFieldWrite, lt as ClientOperationDefinition, m as EntityOperationResult, mt as OperationExecutionOptions, n as EntityHttpTransportOptions, nt as createProxyTransport, o as EntityClient, ot as JsonValue, p as EntityOperation, pt as ClientOperationOutput, q as ResourceRequestOptions, r as createEntityHttpTransport, rt as CiError, s as EntityCreateInput, st as OperationRequest, t as EntityHttpDestination, tt as ProxyTransportOptions, u as EntityFileValue, ut as ClientOperationId, v as EntityTransport, vt as AgentInvokeTarget, w as ResourceCapabilities, wt as SearchQuery, x as EntityUploadSlot, xt as JsonObject, y as EntityUpdateInput, yt as ConversationContinueTarget, z as ResourceListQuery } from "./resources-D0bzEPx3.js";
1
+ import { $ as ResourceSort, A as ResourceCreateRequest, At as ClientFetch, B as ResourceLifecycleInput, C as EntityUploadInput, Ct as ConversationContinueTarget, D as ResourceCapabilities, Dt as QueryFilter, E as PortableResourceSchema, Et as KnowledgeQuery, F as ResourceFilter, Ft as FederatedAuthState, G as ResourceMutationInput, H as ResourceListQuery, I as ResourceGetRequest, It as FederatedSessionIdentity, J as ResourceRecord, K as ResourcePagination, L as ResourceId, Lt as createFederatedAuth, M as ResourceDefinition, Mt as FederatedAuthError, N as ResourceError, Nt as FederatedAuthErrorCode, O as ResourceClient, Ot as SearchQuery, P as ResourceErrorCode, Pt as FederatedAuthOptions, Q as ResourceRevision, R as ResourceIdentityField, S as EntityUpdateInput, St as ApplicationRole, T as IdempotencyKey, Tt as JsonObject, U as ResourceListRequest, V as ResourceLifecycleRequest, W as ResourceListResult, X as ResourceRequestOptions, Y as ResourceRecordId, Z as ResourceResult, _ as EntityPage, _t as OperationExecutionOptions, a as isEntityReadLimitError, at as createProxyTransport, b as EntityRequest, bt as isClientOperationId, c as EntityCreateInput, ct as CiResult, d as EntityFileValue, dt as OperationSuccess, et as ResourceTransport, f as EntityFileWrite, ft as ClientOperationDefinition, g as EntityOperationResult, gt as ClientOperationOutput, h as EntityOperation, ht as ClientOperationMap, i as createEntityProtocol, it as ProxyTransportOptions, j as ResourceCursor, jt as FederatedAuth, k as ResourceCreateInput, kt as WorkflowInvokeTarget, l as EntityDeleteInput, lt as JsonValue, m as EntityMemberValue, mt as ClientOperationInput, n as EntityHttpTransportOptions, nt as ResourceUpdateRequest, o as createResourceClient, ot as CiError, p as EntityListQuery, pt as ClientOperationId, q as ResourcePaginationMode, r as createEntityHttpTransport, rt as ProxyAuthentication, s as EntityClient, st as CiErrorCode, t as EntityHttpDestination, tt as ResourceTransportRequest, u as EntityFileFieldWrite, ut as OperationRequest, v as EntityProtocol, vt as TypedOperationExecutor, w as EntityUploadSlot, wt as ConversationHistory, x as EntityTransport, xt as AgentInvokeTarget, y as EntityReadLimitDetails, yt as clientOperationIds, z as ResourceJsonValue } from "./resources-BDcYZzER.js";
2
2
  type ServerSessionAuthOptions = Readonly<{
3
3
  basePath: string;
4
4
  fetch?: ClientFetch;
@@ -158,6 +158,54 @@ declare const createDelegatedApplicationRuntime: (options: DelegatedApplicationR
158
158
  subscribe: (listener: (state: FederatedAuthState) => void) => () => void;
159
159
  }>;
160
160
  client: ClientSdkClient<Readonly<{
161
+ users_get: ClientOperationDefinition<{
162
+ userId: string;
163
+ }, {
164
+ email: string | null;
165
+ name: string | null;
166
+ userId: string;
167
+ }>;
168
+ users_list: ClientOperationDefinition<{
169
+ page?: number;
170
+ pageSize?: number;
171
+ }, {
172
+ items: Array<{
173
+ email: string | null;
174
+ name: string | null;
175
+ userId: string;
176
+ }>;
177
+ }>;
178
+ users_deactivate: ClientOperationDefinition<{
179
+ userId: string;
180
+ }, {
181
+ userId: string;
182
+ }>;
183
+ roles_list: ClientOperationDefinition<Record<string, never>, {
184
+ items: ApplicationRole[];
185
+ }>;
186
+ roles_assign: ClientOperationDefinition<{
187
+ userId: string;
188
+ roles: string[];
189
+ }, {
190
+ userId: string;
191
+ }>;
192
+ roles_revoke: ClientOperationDefinition<{
193
+ userId: string;
194
+ roles: string[];
195
+ }, {
196
+ userId: string;
197
+ }>;
198
+ users_create_or_get: ClientOperationDefinition<{
199
+ email: string;
200
+ name: string;
201
+ roles: Array<string>;
202
+ }, {
203
+ email: string | null;
204
+ name: string | null;
205
+ userId: string;
206
+ created: boolean;
207
+ kind: "member" | "external_app_user";
208
+ }>;
161
209
  context_get: ClientOperationDefinition<Readonly<Record<string, string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | readonly (string | number | boolean | /*elided*/ any | Readonly<{
162
210
  readonly [key: string]: string | number | boolean | /*elided*/ any | Readonly< /*elided*/ any> | null;
163
211
  }> | null)[] | Readonly<{
@@ -889,4 +937,4 @@ type DirectTransportOptions = Readonly<{
889
937
  tenantUrl: string;
890
938
  }>;
891
939
  declare const createDirectTransport: <Operations extends ClientOperationMap>(options: DirectTransportOptions) => TypedOperationExecutor<Operations>;
892
- export { type CiError, type CiErrorCode, type CiResult, type CiRunCancellation, type CiStreamEvent, type CiStreamPage, type ClientDomains, type ClientFetch, type ClientOperationDefinition, type ClientOperationId, type ClientOperationInput, type ClientOperationMap, type ClientOperationOutput, type ClientSdkClient, type ClientSdkEntrypoint, DEFAULT_FOLLOW_RUN_DEADLINE_MS, type DelegatedApplicationRuntime, type DelegatedApplicationRuntimeOptions, type DelegatedRuntimeState, type DirectTransportOptions, type EntityClient, type EntityCreateInput, type EntityDeleteInput, type EntityFileFieldWrite, type EntityFileValue, type EntityFileWrite, type EntityHttpDestination, type EntityHttpTransportOptions, type EntityListQuery, type EntityOperation, type EntityOperationResult, type EntityPage, type EntityProtocol, type EntityRequest, type EntityTransport, type EntityUpdateInput, type EntityUploadInput, type EntityUploadSlot, type FederatedAuth, FederatedAuthError, type FederatedAuthErrorCode, type FederatedAuthOptions, type FederatedAuthState, type FederatedSessionIdentity, type FixedWorkflowClient, type FixedWorkflowClientOptions, type FollowRunOptions, type FollowRunSource, type IdempotencyKey, type JsonObject, type JsonValue, type KnowledgeQuery, type OperationExecutionOptions, type OperationRequest, type OperationSuccess, type OrganizationClient, type PortableResourceSchema, type ProxyAuthentication, type ProxyTransportOptions, type QueryFilter, type ResourceCapabilities, type ResourceClient, type ResourceCreateInput, type ResourceCreateRequest, type ResourceCursor, type ResourceDefinition, type ResourceError, type ResourceErrorCode, type ResourceFilter, type ResourceGetRequest, type ResourceId, type ResourceIdentityField, type ResourceJsonValue, type ResourceLifecycleInput, type ResourceLifecycleRequest, type ResourceListQuery, type ResourceListRequest, type ResourceListResult, type ResourceMutationInput, type ResourcePagination, type ResourcePaginationMode, type ResourceRecord, type ResourceRecordId, type ResourceRequestOptions, type ResourceResult, type ResourceRevision, type ResourceSort, type ResourceTransport, type ResourceTransportRequest, type ResourceUpdateRequest, type SearchQuery, type ServerSessionAuthOptions, type TypedOperationExecutor, type WorkflowInvokeTarget, clientOperationIds, clientSdkProtocolVersion, createClient, createDelegatedApplicationRuntime, createDirectTransport, createEntityHttpTransport, createEntityProtocol, createFederatedAuth, createFixedWorkflowClient, createProxyTransport, createResourceClient, createServerSessionAuth, followRun, isClientOperationId, nextStreamCursor };
940
+ export { type CiError, type CiErrorCode, type CiResult, type CiRunCancellation, type CiStreamEvent, type CiStreamPage, type ClientDomains, type ClientFetch, type ClientOperationDefinition, type ClientOperationId, type ClientOperationInput, type ClientOperationMap, type ClientOperationOutput, type ClientSdkClient, type ClientSdkEntrypoint, DEFAULT_FOLLOW_RUN_DEADLINE_MS, type DelegatedApplicationRuntime, type DelegatedApplicationRuntimeOptions, type DelegatedRuntimeState, type DirectTransportOptions, type EntityClient, type EntityCreateInput, type EntityDeleteInput, type EntityFileFieldWrite, type EntityFileValue, type EntityFileWrite, type EntityHttpDestination, type EntityHttpTransportOptions, type EntityListQuery, type EntityMemberValue, type EntityOperation, type EntityOperationResult, type EntityPage, type EntityProtocol, type EntityReadLimitDetails, type EntityRequest, type EntityTransport, type EntityUpdateInput, type EntityUploadInput, type EntityUploadSlot, type FederatedAuth, FederatedAuthError, type FederatedAuthErrorCode, type FederatedAuthOptions, type FederatedAuthState, type FederatedSessionIdentity, type FixedWorkflowClient, type FixedWorkflowClientOptions, type FollowRunOptions, type FollowRunSource, type IdempotencyKey, type JsonObject, type JsonValue, type KnowledgeQuery, type OperationExecutionOptions, type OperationRequest, type OperationSuccess, type OrganizationClient, type PortableResourceSchema, type ProxyAuthentication, type ProxyTransportOptions, type QueryFilter, type ResourceCapabilities, type ResourceClient, type ResourceCreateInput, type ResourceCreateRequest, type ResourceCursor, type ResourceDefinition, type ResourceError, type ResourceErrorCode, type ResourceFilter, type ResourceGetRequest, type ResourceId, type ResourceIdentityField, type ResourceJsonValue, type ResourceLifecycleInput, type ResourceLifecycleRequest, type ResourceListQuery, type ResourceListRequest, type ResourceListResult, type ResourceMutationInput, type ResourcePagination, type ResourcePaginationMode, type ResourceRecord, type ResourceRecordId, type ResourceRequestOptions, type ResourceResult, type ResourceRevision, type ResourceSort, type ResourceTransport, type ResourceTransportRequest, type ResourceUpdateRequest, type SearchQuery, type ServerSessionAuthOptions, type TypedOperationExecutor, type WorkflowInvokeTarget, clientOperationIds, clientSdkProtocolVersion, createClient, createDelegatedApplicationRuntime, createDirectTransport, createEntityHttpTransport, createEntityProtocol, createFederatedAuth, createFixedWorkflowClient, createProxyTransport, createResourceClient, createServerSessionAuth, followRun, isClientOperationId, isEntityReadLimitError, nextStreamCursor };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { a as parseMountPath, c as isClientOperationId, i as createHttpOperationTransport, n as createResourceClient, o as parseOriginUrl, r as createEntityProtocol, s as clientOperationIds, t as createEntityHttpTransport } from "./resources-C0wYfzcV.js";
1
+ import { a as createHttpOperationTransport, c as clientOperationIds, i as isEntityReadLimitError, l as isClientOperationId, n as createResourceClient, o as parseMountPath, r as createEntityProtocol, s as parseOriginUrl, t as createEntityHttpTransport } from "./resources--kU5LiFu.js";
2
2
  const base64Url = (bytes) => {
3
3
  let binary = "";
4
4
  for (const byte of bytes) binary += String.fromCodePoint(byte);
@@ -250,18 +250,35 @@ const readString$1 = (record, key) => {
250
250
  const candidate = record[key];
251
251
  return typeof candidate === "string" ? candidate : null;
252
252
  };
253
+ const readStrings = (record, key) => {
254
+ const candidate = record[key];
255
+ if (!Array.isArray(candidate)) return null;
256
+ const items = candidate;
257
+ return items.every((item) => typeof item === "string") ? items : null;
258
+ };
259
+ const readKind = (record) => {
260
+ const { kind } = record;
261
+ return kind === "member" || kind === "external_app_user" ? kind : null;
262
+ };
253
263
  const parseIdentity = (value) => {
254
- const payload = asRecord$2(value);
255
- if (payload === null) return null;
256
- const nested = asRecord$2(payload.identity) ?? payload;
257
- const id = readString$1(nested, "id");
258
- const organizationId = readString$1(nested, "organizationId") ?? readString$1(payload, "organizationId");
259
- if (id === null || organizationId === null) return null;
264
+ const identity = asRecord$2(asRecord$2(value)?.identity);
265
+ if (identity === null) return null;
266
+ const appId = readString$1(identity, "appId");
267
+ const appPermissions = readStrings(identity, "appPermissions");
268
+ const kind = readKind(identity);
269
+ const organizationId = readString$1(identity, "organizationId");
270
+ const roles = readStrings(identity, "roles");
271
+ const userId = readString$1(identity, "userId");
272
+ if (appId === null || appPermissions === null || kind === null || organizationId === null || roles === null || userId === null) return null;
260
273
  return {
261
- email: readString$1(nested, "email"),
262
- id,
263
- name: readString$1(nested, "name"),
264
- organizationId
274
+ appId,
275
+ appPermissions,
276
+ email: readString$1(identity, "email"),
277
+ kind,
278
+ name: readString$1(identity, "name"),
279
+ organizationId,
280
+ roles,
281
+ userId
265
282
  };
266
283
  };
267
284
  /** Browser session client for a sealed-cookie BFF. The access token never leaves the server. */
@@ -722,4 +739,4 @@ const createDirectTransport = (options) => {
722
739
  origin: tenantUrl
723
740
  });
724
741
  };
725
- export { DEFAULT_FOLLOW_RUN_DEADLINE_MS, FederatedAuthError, clientOperationIds, clientSdkProtocolVersion, createClient, createDelegatedApplicationRuntime, createDirectTransport, createEntityHttpTransport, createEntityProtocol, createFederatedAuth, createFixedWorkflowClient, createProxyTransport, createResourceClient, createServerSessionAuth, followRun, isClientOperationId, nextStreamCursor };
742
+ export { DEFAULT_FOLLOW_RUN_DEADLINE_MS, FederatedAuthError, clientOperationIds, clientSdkProtocolVersion, createClient, createDelegatedApplicationRuntime, createDirectTransport, createEntityHttpTransport, createEntityProtocol, createFederatedAuth, createFixedWorkflowClient, createProxyTransport, createResourceClient, createServerSessionAuth, followRun, isClientOperationId, isEntityReadLimitError, nextStreamCursor };
@@ -22,6 +22,13 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
22
22
  const completeOperationRegistry = (ids) => ids;
23
23
  /** Generated, curated external-application operation authority. */
24
24
  const clientOperationIds = completeOperationRegistry([
25
+ "users_get",
26
+ "users_list",
27
+ "users_deactivate",
28
+ "roles_list",
29
+ "roles_assign",
30
+ "roles_revoke",
31
+ "users_create_or_get",
25
32
  "context_get",
26
33
  "knowledge_query",
27
34
  "knowledge_get_entity_schema_snapshot",
@@ -234,6 +241,47 @@ const dedicatedHttpCall = (operationId, input) => {
234
241
  if (removedEntityOperation.has(operationId)) return null;
235
242
  const record = isRecord$1(input) ? input : {};
236
243
  switch (operationId) {
244
+ case "users_create_or_get": return {
245
+ body: input,
246
+ method: "POST",
247
+ parse: "json",
248
+ pathname: "/users"
249
+ };
250
+ case "users_list": {
251
+ const query = {};
252
+ if (typeof record.page === "number") query.page = String(record.page);
253
+ if (typeof record.pageSize === "number") query.pageSize = String(record.pageSize);
254
+ return {
255
+ method: "GET",
256
+ parse: "json",
257
+ pathname: "/users",
258
+ query
259
+ };
260
+ }
261
+ case "roles_list": return {
262
+ method: "GET",
263
+ parse: "json",
264
+ pathname: "/roles"
265
+ };
266
+ case "users_get":
267
+ case "users_deactivate":
268
+ case "roles_assign":
269
+ case "roles_revoke": {
270
+ const userId = textField(record, "userId");
271
+ if (userId === void 0) return null;
272
+ const pathname = `/users/${encodeURIComponent(userId)}`;
273
+ if (operationId === "users_get" || operationId === "users_deactivate") return {
274
+ method: operationId === "users_get" ? "GET" : "DELETE",
275
+ parse: "json",
276
+ pathname
277
+ };
278
+ return {
279
+ body: { roles: record.roles },
280
+ method: operationId === "roles_assign" ? "POST" : "DELETE",
281
+ parse: "json",
282
+ pathname: `${pathname}/roles`
283
+ };
284
+ }
237
285
  case "context_get": return {
238
286
  method: "GET",
239
287
  parse: "json",
@@ -7814,6 +7862,94 @@ const entityQuerySchema = (definition) => {
7814
7862
  query
7815
7863
  };
7816
7864
  };
7865
+ /** Member query structure is portable; CI validates fields against the resolved member schema. */
7866
+ const memberQuerySchema = {
7867
+ filter: { oneOf: [
7868
+ objectSchema({
7869
+ field: identifier,
7870
+ operator: { enum: ["eq", "ne"] },
7871
+ value: true
7872
+ }),
7873
+ objectSchema({
7874
+ field: identifier,
7875
+ operator: { enum: [
7876
+ "gt",
7877
+ "gte",
7878
+ "lt",
7879
+ "lte"
7880
+ ] },
7881
+ value: { type: ["number", "string"] }
7882
+ }),
7883
+ objectSchema({
7884
+ field: identifier,
7885
+ operator: { enum: [
7886
+ "contains",
7887
+ "starts_with",
7888
+ "ends_with"
7889
+ ] },
7890
+ value: { type: "string" }
7891
+ }),
7892
+ objectSchema({
7893
+ field: identifier,
7894
+ operator: { enum: [
7895
+ "in",
7896
+ "not_in",
7897
+ "contains_any",
7898
+ "contains_all"
7899
+ ] },
7900
+ value: {
7901
+ minItems: 1,
7902
+ type: "array"
7903
+ }
7904
+ }),
7905
+ objectSchema({
7906
+ field: identifier,
7907
+ operator: { enum: [
7908
+ "is_null",
7909
+ "is_not_null",
7910
+ "is_empty"
7911
+ ] }
7912
+ }),
7913
+ objectSchema({
7914
+ filters: {
7915
+ items: { $ref: "#/$defs/memberFilter" },
7916
+ minItems: 1,
7917
+ type: "array"
7918
+ },
7919
+ operator: { enum: ["and", "or"] }
7920
+ }),
7921
+ objectSchema({
7922
+ filter: { $ref: "#/$defs/memberFilter" },
7923
+ operator: { const: "not" }
7924
+ })
7925
+ ] },
7926
+ query: objectSchema({
7927
+ filter: { $ref: "#/$defs/memberFilter" },
7928
+ include: includeSchema,
7929
+ pagination: objectSchema({
7930
+ mode: { const: "page" },
7931
+ page: {
7932
+ minimum: 1,
7933
+ type: "integer"
7934
+ },
7935
+ pageSize: {
7936
+ maximum: 100,
7937
+ minimum: 1,
7938
+ type: "integer"
7939
+ }
7940
+ }),
7941
+ sort: {
7942
+ items: objectSchema({
7943
+ direction: { enum: ["asc", "desc"] },
7944
+ field: identifier
7945
+ }),
7946
+ type: "array"
7947
+ },
7948
+ textSearch: { type: "string" }
7949
+ }, ["pagination"])
7950
+ };
7951
+ /** Narrow a decoded resource failure to its documented request-wide read limit. */
7952
+ const isEntityReadLimitError = (error) => error.code === "invalid_request" && error.details?.reason === "read_limit_exceeded" && (error.details.budget === "work" || error.details.budget === "nodes" || error.details.budget === "relation_ids" || error.details.budget === "bytes");
7817
7953
  const operationKey = {
7818
7954
  pattern: "^[\\w.-]{1,256}$",
7819
7955
  type: "string"
@@ -7847,6 +7983,12 @@ const correlation = (input, key, fallback) => {
7847
7983
  else if (key === "correlationId" && "correlationId" in input) value = input.correlationId;
7848
7984
  return typeof value === "string" && value.length > 0 ? value : fallback;
7849
7985
  };
7986
+ const coherentPage = (validatePageEnvelope) => (input) => {
7987
+ if (!validatePageEnvelope(input)) return false;
7988
+ if (!input.ok) return true;
7989
+ const { value } = input;
7990
+ return value.totalPages === Math.ceil(value.totalItems / value.pageSize) && value.items.length <= value.pageSize && value.items.length <= value.totalItems && (value.page <= value.totalPages || value.items.length === 0);
7991
+ };
7850
7992
  /** Common entity wire codec; transport and persistence remain with their owners. */
7851
7993
  const createEntityProtocol = (definition) => {
7852
7994
  const { filter, filterValues, query } = entityQuerySchema(definition);
@@ -7860,10 +8002,16 @@ const createEntityProtocol = (definition) => {
7860
8002
  create: scopeSchema(definition.schemas.create ?? false, "#/$defs/create"),
7861
8003
  filter,
7862
8004
  filterEntity: scopeSchema(filterValues, "#/$defs/filterEntity"),
8005
+ memberFilter: memberQuerySchema.filter,
7863
8006
  update: scopeSchema(definition.schemas.update ?? false, "#/$defs/update")
7864
8007
  },
7865
8008
  oneOf: [
7866
8009
  requestSchema(definition, "list", { query }),
8010
+ requestSchema(definition, "list_members", {
8011
+ field: identifier,
8012
+ parentId: identifier,
8013
+ query: memberQuerySchema.query
8014
+ }),
7867
8015
  requestSchema(definition, "get", { id: identifier }, { include: includeSchema }),
7868
8016
  requestSchema(definition, "create", {
7869
8017
  idempotencyKey: operationKey,
@@ -7908,33 +8056,56 @@ const createEntityProtocol = (definition) => {
7908
8056
  "revision",
7909
8057
  "value"
7910
8058
  ]);
7911
- const error = objectSchema({
7912
- code: { enum: [
7913
- "capability_not_supported",
7914
- "conflict",
7915
- "forbidden",
7916
- "internal",
7917
- "invalid_request",
7918
- "not_found",
7919
- "rate_limited",
7920
- "transport_error",
7921
- "unauthenticated",
7922
- "unavailable",
7923
- "upload_not_supported"
7924
- ] },
7925
- details: { type: "object" },
7926
- message: { type: "string" },
7927
- outcome: { enum: [
7928
- "not_dispatched",
7929
- "rejected",
7930
- "uncertain"
7931
- ] },
7932
- retryable: { type: "boolean" }
7933
- }, [
7934
- "code",
7935
- "message",
7936
- "retryable"
7937
- ]);
8059
+ const error = {
8060
+ ...objectSchema({
8061
+ code: { enum: [
8062
+ "capability_not_supported",
8063
+ "conflict",
8064
+ "forbidden",
8065
+ "internal",
8066
+ "invalid_request",
8067
+ "not_found",
8068
+ "rate_limited",
8069
+ "transport_error",
8070
+ "unauthenticated",
8071
+ "unavailable",
8072
+ "upload_not_supported"
8073
+ ] },
8074
+ details: { type: "object" },
8075
+ message: { type: "string" },
8076
+ outcome: { enum: [
8077
+ "not_dispatched",
8078
+ "rejected",
8079
+ "uncertain"
8080
+ ] },
8081
+ retryable: { type: "boolean" }
8082
+ }, [
8083
+ "code",
8084
+ "message",
8085
+ "retryable"
8086
+ ]),
8087
+ allOf: [{
8088
+ if: {
8089
+ properties: { details: {
8090
+ properties: { reason: { const: "read_limit_exceeded" } },
8091
+ required: ["reason"]
8092
+ } },
8093
+ required: ["details"]
8094
+ },
8095
+ then: { properties: {
8096
+ code: { const: "invalid_request" },
8097
+ details: objectSchema({
8098
+ budget: { enum: [
8099
+ "work",
8100
+ "nodes",
8101
+ "relation_ids",
8102
+ "bytes"
8103
+ ] },
8104
+ reason: { const: "read_limit_exceeded" }
8105
+ })
8106
+ } }
8107
+ }]
8108
+ };
7938
8109
  const liveRecord = {
7939
8110
  ...record,
7940
8111
  properties: {
@@ -7993,17 +8164,28 @@ const createEntityProtocol = (definition) => {
7993
8164
  uploadId: identifier,
7994
8165
  url: identifier
7995
8166
  })));
7996
- const coherentPage = (input) => {
7997
- if (!validatePage(input)) return false;
7998
- if (!input.ok) return true;
7999
- const { value } = input;
8000
- return value.totalPages === Math.ceil(value.totalItems / value.pageSize) && value.items.length <= value.pageSize && value.items.length <= value.totalItems && (value.page <= value.totalPages || value.items.length === 0);
8001
- };
8167
+ const validateMemberPage = ajv.compile(resultSchema({
8168
+ ...page,
8169
+ properties: {
8170
+ ...page.properties,
8171
+ items: {
8172
+ items: {
8173
+ ...liveRecord,
8174
+ properties: {
8175
+ ...liveRecord.properties,
8176
+ value: { type: "object" }
8177
+ }
8178
+ },
8179
+ type: "array"
8180
+ }
8181
+ }
8182
+ }));
8002
8183
  const validateOperationResult = {
8003
8184
  create: validateRecord,
8004
8185
  delete: validateDeleted,
8005
8186
  get: validateRecord,
8006
- list: coherentPage,
8187
+ list: coherentPage(validatePage),
8188
+ list_members: coherentPage(validateMemberPage),
8007
8189
  update: validateRecord,
8008
8190
  upload: validateUploadSlot
8009
8191
  };
@@ -8078,6 +8260,7 @@ const createCommonEntityClient = (options) => {
8078
8260
  delete: "delete",
8079
8261
  get: "get",
8080
8262
  list: "search",
8263
+ list_members: "search",
8081
8264
  update: "update",
8082
8265
  upload: "upload"
8083
8266
  }[input.operation]] !== true) return {
@@ -8097,7 +8280,7 @@ const createCommonEntityClient = (options) => {
8097
8280
  ...decoded,
8098
8281
  error: {
8099
8282
  ...decoded.error,
8100
- outcome: input.operation === "list" || input.operation === "get" ? "rejected" : "uncertain"
8283
+ outcome: input.operation === "list" || input.operation === "list_members" || input.operation === "get" ? "rejected" : "uncertain"
8101
8284
  }
8102
8285
  } : decoded;
8103
8286
  } catch {
@@ -8106,7 +8289,7 @@ const createCommonEntityClient = (options) => {
8106
8289
  error: {
8107
8290
  code: "transport_error",
8108
8291
  message: "The entity transport failed",
8109
- outcome: input.operation === "list" || input.operation === "get" ? "rejected" : "uncertain",
8292
+ outcome: input.operation === "list" || input.operation === "list_members" || input.operation === "get" ? "rejected" : "uncertain",
8110
8293
  retryable: false
8111
8294
  },
8112
8295
  ok: false
@@ -8131,6 +8314,12 @@ const createCommonEntityClient = (options) => {
8131
8314
  operation: "list",
8132
8315
  query
8133
8316
  }, requestOptions),
8317
+ listMembers: (parentId, field, query, requestOptions) => execute({
8318
+ field,
8319
+ operation: "list_members",
8320
+ parentId,
8321
+ query
8322
+ }, requestOptions),
8134
8323
  update: (input) => execute({
8135
8324
  ...input,
8136
8325
  operation: "update"
@@ -8234,6 +8423,14 @@ const encode = (request) => {
8234
8423
  method: "POST",
8235
8424
  path: "/search"
8236
8425
  };
8426
+ case "list_members": return {
8427
+ body: JSON.stringify({
8428
+ ...request.query,
8429
+ field: request.field
8430
+ }),
8431
+ method: "POST",
8432
+ path: `/records/${encodeURIComponent(request.parentId)}/relation-members/search`
8433
+ };
8237
8434
  case "get": {
8238
8435
  const query = request.include?.length ? `?include=${encodeURIComponent(request.include.join(","))}` : "";
8239
8436
  return {
@@ -8338,10 +8535,10 @@ const createEntityHttpTransport = (options) => {
8338
8535
  return failure({
8339
8536
  code: "transport_error",
8340
8537
  message: "The entity response could not be received",
8341
- outcome: request.operation === "get" || request.operation === "list" ? "rejected" : "uncertain",
8538
+ outcome: request.operation === "get" || request.operation === "list" || request.operation === "list_members" ? "rejected" : "uncertain",
8342
8539
  retryable: false
8343
8540
  });
8344
8541
  }
8345
8542
  } };
8346
8543
  };
8347
- export { parseMountPath as a, isClientOperationId as c, createHttpOperationTransport as i, createResourceClient as n, parseOriginUrl as o, createEntityProtocol as r, clientOperationIds as s, createEntityHttpTransport as t };
8544
+ export { createHttpOperationTransport as a, clientOperationIds as c, isEntityReadLimitError as i, isClientOperationId as l, createResourceClient as n, parseMountPath as o, createEntityProtocol as r, parseOriginUrl as s, createEntityHttpTransport as t };
@@ -3,11 +3,22 @@ declare class FederatedAuthError extends Error {
3
3
  readonly code: FederatedAuthErrorCode;
4
4
  constructor(code: FederatedAuthErrorCode, message: string);
5
5
  }
6
+ /**
7
+ * The signed-in CI user as the application's BFF reports it: the fields of
8
+ * CI's `/oauth/identity`, read live by the server, plus email and name.
9
+ */
6
10
  type FederatedSessionIdentity = Readonly<{
11
+ appId: string;
12
+ /** The App Permissions of the user's effective roles. */
13
+ appPermissions: readonly string[];
7
14
  email: string | null;
8
- id: string;
15
+ /** A person is a member or an External App User of one Organization, never both. */
16
+ kind: "member" | "external_app_user";
9
17
  name: string | null;
10
18
  organizationId: string;
19
+ /** The user's effective roles on the app. */
20
+ roles: readonly string[];
21
+ userId: string;
11
22
  }>;
12
23
  type FederatedAuthState = Readonly<{
13
24
  status: "anonymous";
@@ -51,6 +62,87 @@ type FederatedAuthOptions = Readonly<{
51
62
  tenantUrl: string;
52
63
  }>;
53
64
  declare const createFederatedAuth: (options: FederatedAuthOptions) => FederatedAuth;
65
+ type ExternalApplicationsListAppUsersResponses = {
66
+ /**
67
+ * Success
68
+ */
69
+ 200: {
70
+ correlationId: string;
71
+ result: {
72
+ items: Array<{
73
+ email: string | null;
74
+ name: string | null;
75
+ userId: string;
76
+ }>;
77
+ };
78
+ };
79
+ };
80
+ type ExternalApplicationsListAppUsersResponse = ExternalApplicationsListAppUsersResponses[keyof ExternalApplicationsListAppUsersResponses];
81
+ type ExternalApplicationsCreateOrGetAppUserData = {
82
+ body: {
83
+ email: string;
84
+ name: string;
85
+ roles: Array<string>;
86
+ };
87
+ headers: {
88
+ authorization?: string;
89
+ 'x-organization-id': string;
90
+ 'x-correlation-id'?: string;
91
+ 'x-external-audit-issuer'?: string;
92
+ 'x-external-audit-subject'?: string;
93
+ 'x-external-caller-kind'?: 'anonymous_visitor';
94
+ 'x-external-ci-user-id'?: string;
95
+ 'x-external-server-role'?: string;
96
+ };
97
+ path?: never;
98
+ query?: never;
99
+ url: '/application/v1/users';
100
+ };
101
+ type ExternalApplicationsCreateOrGetAppUserResponses = {
102
+ /**
103
+ * Success
104
+ */
105
+ 200: {
106
+ correlationId: string;
107
+ result: {
108
+ email: string | null;
109
+ name: string | null;
110
+ userId: string;
111
+ created: boolean;
112
+ kind: 'member' | 'external_app_user';
113
+ };
114
+ };
115
+ };
116
+ type ExternalApplicationsCreateOrGetAppUserResponse = ExternalApplicationsCreateOrGetAppUserResponses[keyof ExternalApplicationsCreateOrGetAppUserResponses];
117
+ type ExternalApplicationsGetAppUserResponses = {
118
+ /**
119
+ * Success
120
+ */
121
+ 200: {
122
+ correlationId: string;
123
+ result: {
124
+ email: string | null;
125
+ name: string | null;
126
+ userId: string;
127
+ };
128
+ };
129
+ };
130
+ type ExternalApplicationsGetAppUserResponse = ExternalApplicationsGetAppUserResponses[keyof ExternalApplicationsGetAppUserResponses];
131
+ type ExternalApplicationsListAppRolesResponses = {
132
+ /**
133
+ * Success
134
+ */
135
+ 200: {
136
+ correlationId: string;
137
+ result: {
138
+ items: Array<{
139
+ id: string;
140
+ key: string;
141
+ }>;
142
+ };
143
+ };
144
+ };
145
+ type ExternalApplicationsListAppRolesResponse = ExternalApplicationsListAppRolesResponses[keyof ExternalApplicationsListAppRolesResponses];
54
146
  type JsonValue$1 = boolean | null | number | readonly JsonValue$1[] | Readonly<{
55
147
  readonly [key: string]: JsonValue$1;
56
148
  }> | string;
@@ -135,6 +227,40 @@ type KnowledgeQuery = {
135
227
  op: "autocomplete";
136
228
  });
137
229
  type ExternalApplicationOperationRequest = {
230
+ input: {
231
+ userId: string;
232
+ };
233
+ operationId: "users_get";
234
+ } | {
235
+ input: {
236
+ page?: number;
237
+ pageSize?: number;
238
+ };
239
+ operationId: "users_list";
240
+ } | {
241
+ input: {
242
+ userId: string;
243
+ };
244
+ operationId: "users_deactivate";
245
+ } | {
246
+ input: Record<string, never>;
247
+ operationId: "roles_list";
248
+ } | {
249
+ input: {
250
+ userId: string;
251
+ roles: string[];
252
+ };
253
+ operationId: "roles_assign";
254
+ } | {
255
+ input: {
256
+ userId: string;
257
+ roles: string[];
258
+ };
259
+ operationId: "roles_revoke";
260
+ } | {
261
+ input: ExternalApplicationsCreateOrGetAppUserData["body"];
262
+ operationId: "users_create_or_get";
263
+ } | {
138
264
  input: JsonObject | unknown[];
139
265
  operationId: "context_get";
140
266
  } | {
@@ -336,7 +462,15 @@ interface EnvelopeSuccess<Id extends string, Result> {
336
462
  operationId: Id;
337
463
  result: Result;
338
464
  }
339
- type ExternalApplicationOperationSuccess = EnvelopeSuccess<"context_get", JsonObject> | EnvelopeSuccess<"knowledge_query", JsonObject> | EnvelopeSuccess<"knowledge_get_entity_schema_snapshot", JsonObject> | EnvelopeSuccess<"knowledge_search_entities", JsonObject> | EnvelopeSuccess<"knowledge_facets", JsonObject> | EnvelopeSuccess<"knowledge_get_schema_query_context", JsonObject> | EnvelopeSuccess<"knowledge_autocomplete", JsonObject> | EnvelopeSuccess<"knowledge_get_entity", JsonObject> | EnvelopeSuccess<"knowledge_create_entity", JsonObject> | EnvelopeSuccess<"knowledge_update_entity", JsonObject> | EnvelopeSuccess<"knowledge_upsert_entity", JsonObject> | EnvelopeSuccess<"knowledge_delete_entity", JsonObject> | EnvelopeSuccess<"knowledge_traverse", JsonObject> | EnvelopeSuccess<"knowledge_create_relation", JsonObject> | EnvelopeSuccess<"knowledge_update_relation", JsonObject> | EnvelopeSuccess<"knowledge_delete_relation", JsonObject> | EnvelopeSuccess<"agents_list", JsonObject> | EnvelopeSuccess<"agents_invoke", {
465
+ type ExternalApplicationOperationSuccess = EnvelopeSuccess<"users_get", ApplicationUser> | EnvelopeSuccess<"users_list", ApplicationUserPage> | EnvelopeSuccess<"users_deactivate", {
466
+ userId: string;
467
+ }> | EnvelopeSuccess<"roles_list", {
468
+ items: ApplicationRole[];
469
+ }> | EnvelopeSuccess<"roles_assign", {
470
+ userId: string;
471
+ }> | EnvelopeSuccess<"roles_revoke", {
472
+ userId: string;
473
+ }> | EnvelopeSuccess<"users_create_or_get", ApplicationUserResolution> | EnvelopeSuccess<"context_get", JsonObject> | EnvelopeSuccess<"knowledge_query", JsonObject> | EnvelopeSuccess<"knowledge_get_entity_schema_snapshot", JsonObject> | EnvelopeSuccess<"knowledge_search_entities", JsonObject> | EnvelopeSuccess<"knowledge_facets", JsonObject> | EnvelopeSuccess<"knowledge_get_schema_query_context", JsonObject> | EnvelopeSuccess<"knowledge_autocomplete", JsonObject> | EnvelopeSuccess<"knowledge_get_entity", JsonObject> | EnvelopeSuccess<"knowledge_create_entity", JsonObject> | EnvelopeSuccess<"knowledge_update_entity", JsonObject> | EnvelopeSuccess<"knowledge_upsert_entity", JsonObject> | EnvelopeSuccess<"knowledge_delete_entity", JsonObject> | EnvelopeSuccess<"knowledge_traverse", JsonObject> | EnvelopeSuccess<"knowledge_create_relation", JsonObject> | EnvelopeSuccess<"knowledge_update_relation", JsonObject> | EnvelopeSuccess<"knowledge_delete_relation", JsonObject> | EnvelopeSuccess<"agents_list", JsonObject> | EnvelopeSuccess<"agents_invoke", {
340
474
  runId: string;
341
475
  }> | EnvelopeSuccess<"skills_list", JsonObject> | EnvelopeSuccess<"skills_invoke", {
342
476
  runId: string;
@@ -354,28 +488,11 @@ type ExternalApplicationOperationSuccess = EnvelopeSuccess<"context_get", JsonOb
354
488
  conversationId: string;
355
489
  runId: string;
356
490
  }> | EnvelopeSuccess<"conversations_history", ConversationHistory>;
357
- /**
358
- * Operations only the confidential application itself may invoke. They stay
359
- * out of `externalApplicationOperationIds`, so browser clients and the user
360
- * proxy never offer them.
361
- */
362
- /** A person whose only role in the application's Organization is `member`. */
363
- interface MemberUser {
364
- email: string | null;
365
- name: string | null;
366
- userId: string;
367
- }
368
- /**
369
- * How create-or-get resolved the email: a new user, an existing CI user who
370
- * joined the Organization as a member, or a user who already was one.
371
- */
372
- type MemberUserResolution = "created" | "existing" | "linked";
373
- interface MemberUserPage {
374
- items: MemberUser[];
375
- page: number;
376
- pageSize: number;
377
- totalItems: number;
378
- }
491
+ /** User details returned by the application's user-management gateway. */
492
+ type ApplicationUser = ExternalApplicationsGetAppUserResponse["result"];
493
+ type ApplicationUserResolution = ExternalApplicationsCreateOrGetAppUserResponse["result"];
494
+ type ApplicationUserPage = ExternalApplicationsListAppUsersResponse["result"];
495
+ type ApplicationRole = ExternalApplicationsListAppRolesResponse["result"]["items"][number];
379
496
  declare const storageFileIdBrand: unique symbol;
380
497
  /** A durable private file of the application's Organization. */
381
498
  type StorageFileId = string & Readonly<{
@@ -394,34 +511,6 @@ interface DurableFileUpload {
394
511
  type ExternalApplicationServiceOperationRequest = {
395
512
  input: DurableFileUpload;
396
513
  operationId: "files_upload";
397
- } | {
398
- input: {
399
- email: string;
400
- name: string;
401
- };
402
- operationId: "members_create_or_get";
403
- } | {
404
- input: {
405
- userId: string;
406
- };
407
- operationId: "members_get";
408
- } | {
409
- input: {
410
- page?: number;
411
- pageSize?: number;
412
- };
413
- operationId: "members_list";
414
- } | {
415
- input: {
416
- name: string;
417
- userId: string;
418
- };
419
- operationId: "members_update";
420
- } | {
421
- input: {
422
- userId: string;
423
- };
424
- operationId: "members_remove";
425
514
  } | {
426
515
  input: {
427
516
  origin: string;
@@ -445,10 +534,6 @@ interface UserCompanyLinks {
445
534
  }
446
535
  type ExternalApplicationServiceOperationSuccess = EnvelopeSuccess<"files_upload", {
447
536
  storageFileId: StorageFileId;
448
- }> | EnvelopeSuccess<"members_create_or_get", MemberUser & {
449
- outcome: MemberUserResolution;
450
- }> | EnvelopeSuccess<"members_get", MemberUser> | EnvelopeSuccess<"members_list", MemberUserPage> | EnvelopeSuccess<"members_update", MemberUser> | EnvelopeSuccess<"members_remove", {
451
- userId: string;
452
537
  }> | EnvelopeSuccess<"origins_set_runtime", {
453
538
  origin: string;
454
539
  }> | EnvelopeSuccess<"users_list_company_links", UserCompanyLinks> | EnvelopeSuccess<"users_link_companies", UserCompanyLinks>;
@@ -463,7 +548,7 @@ type ExternalApplicationOperationSuccessFor<Id extends ExternalApplicationServer
463
548
  operationId: Id;
464
549
  }>;
465
550
  /** Generated, curated external-application operation authority. */
466
- declare const clientOperationIds: readonly ["context_get", "knowledge_query", "knowledge_get_entity_schema_snapshot", "knowledge_search_entities", "knowledge_facets", "knowledge_get_schema_query_context", "knowledge_autocomplete", "knowledge_get_entity", "knowledge_create_entity", "knowledge_update_entity", "knowledge_upsert_entity", "knowledge_delete_entity", "knowledge_traverse", "knowledge_create_relation", "knowledge_update_relation", "knowledge_delete_relation", "agents_list", "agents_invoke", "skills_list", "skills_invoke", "workflows_list", "workflows_invoke", "runs_get", "runs_stream", "runs_cancel", "attachments_upload", "attachments_download_url", "conversations_continue", "conversations_history"];
551
+ declare const clientOperationIds: readonly ["users_get", "users_list", "users_deactivate", "roles_list", "roles_assign", "roles_revoke", "users_create_or_get", "context_get", "knowledge_query", "knowledge_get_entity_schema_snapshot", "knowledge_search_entities", "knowledge_facets", "knowledge_get_schema_query_context", "knowledge_autocomplete", "knowledge_get_entity", "knowledge_create_entity", "knowledge_update_entity", "knowledge_upsert_entity", "knowledge_delete_entity", "knowledge_traverse", "knowledge_create_relation", "knowledge_update_relation", "knowledge_delete_relation", "agents_list", "agents_invoke", "skills_list", "skills_invoke", "workflows_list", "workflows_invoke", "runs_get", "runs_stream", "runs_cancel", "attachments_upload", "attachments_download_url", "conversations_continue", "conversations_history"];
467
552
  type ClientOperationId = ExternalApplicationOperationId;
468
553
  declare const isClientOperationId: (value: string) => value is ClientOperationId;
469
554
  interface ClientOperationDefinition<Input, Output> {
@@ -655,6 +740,11 @@ type ResourceListResult<Entity> = Readonly<{
655
740
  type ResourceErrorCode = "capability_not_supported" | "conflict" | "forbidden" | "internal" | "invalid_request" | "not_found" | "rate_limited" | "transport_error" | "unauthenticated" | "unavailable" |
656
741
  /** The CI Organization storage can not take a presigned File upload. */
657
742
  "upload_not_supported";
743
+ /** Stable, content-free diagnostics for request-wide Knowledge read limits. */
744
+ type EntityReadLimitDetails = Readonly<{
745
+ reason: "read_limit_exceeded";
746
+ budget: "work" | "nodes" | "relation_ids" | "bytes";
747
+ }>;
658
748
  type ResourceError = Readonly<{
659
749
  code: ResourceErrorCode;
660
750
  /** Client-observed dispatch outcome; uncertainty never proves rollback. */
@@ -746,7 +836,7 @@ interface ResourceClient<Entity, Create = Entity, Update = Partial<Entity>> {
746
836
  readonly update: (input: ResourceMutationInput<Update>, options?: ResourceRequestOptions) => Promise<ResourceResult<ResourceRecord<Entity>>>;
747
837
  }
748
838
  /** Common entity operations. Generic resource lifecycle/cursor APIs remain separate. */
749
- type EntityOperation = "list" | "get" | "create" | "update" | "delete" | "upload";
839
+ type EntityOperation = "list_members" | "list" | "get" | "create" | "update" | "delete" | "upload";
750
840
  type EntityListQuery = Omit<ResourceListQuery, "pagination" | "includeDeleted"> & Readonly<{
751
841
  pagination: Extract<ResourcePagination, {
752
842
  mode: "page";
@@ -755,6 +845,8 @@ type EntityListQuery = Omit<ResourceListQuery, "pagination" | "includeDeleted">
755
845
  type EntityPage<Value> = Extract<ResourceListResult<Value>, {
756
846
  pagination: "page";
757
847
  }>;
848
+ /** Member schemas are resolved by CI, independently of the parent resource. */
849
+ type EntityMemberValue = Readonly<Record<string, ResourceJsonValue>>;
758
850
  type EntityCreateInput<Value> = ResourceCreateInput<Value>;
759
851
  type EntityUpdateInput<Patch> = ResourceMutationInput<Patch> & Readonly<{
760
852
  idempotencyKey: IdempotencyKey;
@@ -805,6 +897,11 @@ type EntityRequestIdentity = Readonly<{
805
897
  type EntityRequest<Create = unknown, Patch = unknown> = EntityRequestIdentity & (Readonly<{
806
898
  operation: "list";
807
899
  query: EntityListQuery;
900
+ }> | Readonly<{
901
+ operation: "list_members";
902
+ parentId: ResourceRecordId;
903
+ field: string;
904
+ query: EntityListQuery;
808
905
  }> | Readonly<{
809
906
  operation: "get";
810
907
  id: ResourceRecordId;
@@ -818,7 +915,7 @@ type EntityRequest<Create = unknown, Patch = unknown> = EntityRequestIdentity &
818
915
  }> & EntityDeleteInput) | (Readonly<{
819
916
  operation: "upload";
820
917
  }> & EntityUploadInput));
821
- type EntityOperationResult<Value, Operation extends EntityOperation> = Operation extends "list" ? EntityPage<Value> : Operation extends "upload" ? EntityUploadSlot : ResourceRecord<Value>;
918
+ type EntityOperationResult<Value, Operation extends EntityOperation> = Operation extends "list_members" ? EntityPage<EntityMemberValue> : Operation extends "list" ? EntityPage<Value> : Operation extends "upload" ? EntityUploadSlot : ResourceRecord<Value>;
822
919
  /** Codecs return safe typed failures without coercing values or performing I/O. */
823
920
  type EntityProtocol<Value, Create = Value, Patch = Partial<Value>> = Readonly<{
824
921
  decodeRequest: (input: unknown) => ResourceResult<EntityRequest<Create, Patch>>;
@@ -829,6 +926,8 @@ interface EntityTransport {
829
926
  }
830
927
  /** A logical write retains its key, payload and edited revision on explicit resubmission. */
831
928
  interface EntityClient<Value, Create = Value, Patch = Partial<Value>> {
929
+ /** Filter, sort and page the resolved member schema; includes remain bounded. */
930
+ readonly listMembers: (parentId: ResourceRecordId, field: string, query: EntityListQuery, options?: ResourceRequestOptions) => Promise<ResourceResult<EntityPage<EntityMemberValue>>>;
832
931
  readonly definition: ResourceDefinition<Value, Create, Patch>;
833
932
  readonly list: (query: EntityListQuery, options?: ResourceRequestOptions) => Promise<ResourceResult<EntityPage<Value>>>;
834
933
  readonly get: (input: Readonly<{
@@ -852,6 +951,11 @@ declare function createResourceClient<Value, Create = Value, Patch = Partial<Val
852
951
  declare function createResourceClient<Value, Create = Value, Patch = Partial<Value>>(options: ClientOptions<Value, Create, Patch> & Readonly<{
853
952
  transport: ResourceTransport;
854
953
  }>): ResourceClient<Value, Create, Patch>;
954
+ /** Narrow a decoded resource failure to its documented request-wide read limit. */
955
+ declare const isEntityReadLimitError: (error: ResourceError) => error is ResourceError & Readonly<{
956
+ code: "invalid_request";
957
+ details: EntityReadLimitDetails;
958
+ }>;
855
959
  /** Common entity wire codec; transport and persistence remain with their owners. */
856
960
  declare const createEntityProtocol: <Value, Create = Value, Patch = Partial<Value>>(definition: ResourceDefinition<Value, Create, Patch>) => EntityProtocol<Value, Create, Patch>;
857
961
  type EntityHttpDestination = Readonly<{
@@ -869,4 +973,4 @@ type EntityHttpTransportOptions = Readonly<{
869
973
  fetch?: ClientFetch;
870
974
  }>;
871
975
  declare const createEntityHttpTransport: (options: EntityHttpTransportOptions) => EntityTransport;
872
- export { ResourceUpdateRequest as $, ResourceError as A, FederatedAuthOptions as At, ResourceListRequest as B, PortableResourceSchema as C, QueryFilter as Ct, ResourceCreateRequest as D, FederatedAuth as Dt, ResourceCreateInput as E, ClientFetch as Et, ResourceIdentityField as F, ResourceRecord as G, ResourceMutationInput as H, ResourceJsonValue as I, ResourceResult as J, ResourceRecordId as K, ResourceLifecycleInput as L, ResourceFilter as M, FederatedSessionIdentity as Mt, ResourceGetRequest as N, createFederatedAuth as Nt, ResourceCursor as O, FederatedAuthError as Ot, ResourceId as P, ResourceTransportRequest as Q, ResourceLifecycleRequest as R, IdempotencyKey as S, KnowledgeQuery as St, ResourceClient as T, WorkflowInvokeTarget as Tt, ResourcePagination as U, ResourceListResult as V, ResourcePaginationMode as W, ResourceSort as X, ResourceRevision as Y, ResourceTransport as Z, EntityRequest as _, isClientOperationId as _t, createResourceClient as a, CiResult as at, EntityUploadInput as b, ConversationHistory as bt, EntityDeleteInput as c, OperationSuccess as ct, EntityFileWrite as d, ClientOperationInput as dt, ProxyAuthentication as et, EntityListQuery as f, ClientOperationMap as ft, EntityProtocol as g, clientOperationIds as gt, EntityPage as h, TypedOperationExecutor as ht, createEntityProtocol as i, CiErrorCode as it, ResourceErrorCode as j, FederatedAuthState as jt, ResourceDefinition as k, FederatedAuthErrorCode as kt, EntityFileFieldWrite as l, ClientOperationDefinition as lt, EntityOperationResult as m, OperationExecutionOptions as mt, EntityHttpTransportOptions as n, createProxyTransport as nt, EntityClient as o, JsonValue as ot, EntityOperation as p, ClientOperationOutput as pt, ResourceRequestOptions as q, createEntityHttpTransport as r, CiError as rt, EntityCreateInput as s, OperationRequest as st, EntityHttpDestination as t, ProxyTransportOptions as tt, EntityFileValue as u, ClientOperationId as ut, EntityTransport as v, AgentInvokeTarget as vt, ResourceCapabilities as w, SearchQuery as wt, EntityUploadSlot as x, JsonObject as xt, EntityUpdateInput as y, ConversationContinueTarget as yt, ResourceListQuery as z };
976
+ export { ResourceSort as $, ResourceCreateRequest as A, ClientFetch as At, ResourceLifecycleInput as B, EntityUploadInput as C, ConversationContinueTarget as Ct, ResourceCapabilities as D, QueryFilter as Dt, PortableResourceSchema as E, KnowledgeQuery as Et, ResourceFilter as F, FederatedAuthState as Ft, ResourceMutationInput as G, ResourceListQuery as H, ResourceGetRequest as I, FederatedSessionIdentity as It, ResourceRecord as J, ResourcePagination as K, ResourceId as L, createFederatedAuth as Lt, ResourceDefinition as M, FederatedAuthError as Mt, ResourceError as N, FederatedAuthErrorCode as Nt, ResourceClient as O, SearchQuery as Ot, ResourceErrorCode as P, FederatedAuthOptions as Pt, ResourceRevision as Q, ResourceIdentityField as R, EntityUpdateInput as S, ApplicationRole as St, IdempotencyKey as T, JsonObject as Tt, ResourceListRequest as U, ResourceLifecycleRequest as V, ResourceListResult as W, ResourceRequestOptions as X, ResourceRecordId as Y, ResourceResult as Z, EntityPage as _, OperationExecutionOptions as _t, isEntityReadLimitError as a, createProxyTransport as at, EntityRequest as b, isClientOperationId as bt, EntityCreateInput as c, CiResult as ct, EntityFileValue as d, OperationSuccess as dt, ResourceTransport as et, EntityFileWrite as f, ClientOperationDefinition as ft, EntityOperationResult as g, ClientOperationOutput as gt, EntityOperation as h, ClientOperationMap as ht, createEntityProtocol as i, ProxyTransportOptions as it, ResourceCursor as j, FederatedAuth as jt, ResourceCreateInput as k, WorkflowInvokeTarget as kt, EntityDeleteInput as l, JsonValue as lt, EntityMemberValue as m, ClientOperationInput as mt, EntityHttpTransportOptions as n, ResourceUpdateRequest as nt, createResourceClient as o, CiError as ot, EntityListQuery as p, ClientOperationId as pt, ResourcePaginationMode as q, createEntityHttpTransport as r, ProxyAuthentication as rt, EntityClient as s, CiErrorCode as st, EntityHttpDestination as t, ResourceTransportRequest as tt, EntityFileFieldWrite as u, OperationRequest as ut, EntityProtocol as v, TypedOperationExecutor as vt, EntityUploadSlot as w, ConversationHistory as wt, EntityTransport as x, AgentInvokeTarget as xt, EntityReadLimitDetails as y, clientOperationIds as yt, ResourceJsonValue as z };
@@ -1,2 +1,2 @@
1
- import { $ as ResourceUpdateRequest, A as ResourceError, B as ResourceListRequest, C as PortableResourceSchema, D as ResourceCreateRequest, E as ResourceCreateInput, F as ResourceIdentityField, G as ResourceRecord, H as ResourceMutationInput, I as ResourceJsonValue, J as ResourceResult, K as ResourceRecordId, L as ResourceLifecycleInput, M as ResourceFilter, N as ResourceGetRequest, O as ResourceCursor, P as ResourceId, Q as ResourceTransportRequest, R as ResourceLifecycleRequest, S as IdempotencyKey, T as ResourceClient, U as ResourcePagination, V as ResourceListResult, W as ResourcePaginationMode, X as ResourceSort, Y as ResourceRevision, Z as ResourceTransport, _ as EntityRequest, a as createResourceClient, b as EntityUploadInput, c as EntityDeleteInput, d as EntityFileWrite, f as EntityListQuery, g as EntityProtocol, h as EntityPage, i as createEntityProtocol, j as ResourceErrorCode, k as ResourceDefinition, l as EntityFileFieldWrite, m as EntityOperationResult, n as EntityHttpTransportOptions, o as EntityClient, p as EntityOperation, q as ResourceRequestOptions, r as createEntityHttpTransport, s as EntityCreateInput, t as EntityHttpDestination, u as EntityFileValue, v as EntityTransport, w as ResourceCapabilities, x as EntityUploadSlot, y as EntityUpdateInput, z as ResourceListQuery } from "./resources-D0bzEPx3.js";
2
- export { type EntityClient, type EntityCreateInput, type EntityDeleteInput, type EntityFileFieldWrite, type EntityFileValue, type EntityFileWrite, type EntityHttpDestination, type EntityHttpTransportOptions, type EntityListQuery, type EntityOperation, type EntityOperationResult, type EntityPage, type EntityProtocol, type EntityRequest, type EntityTransport, type EntityUpdateInput, type EntityUploadInput, type EntityUploadSlot, type IdempotencyKey, type PortableResourceSchema, type ResourceCapabilities, type ResourceClient, type ResourceCreateInput, type ResourceCreateRequest, type ResourceCursor, type ResourceDefinition, type ResourceError, type ResourceErrorCode, type ResourceFilter, type ResourceGetRequest, type ResourceId, type ResourceIdentityField, type ResourceJsonValue, type ResourceLifecycleInput, type ResourceLifecycleRequest, type ResourceListQuery, type ResourceListRequest, type ResourceListResult, type ResourceMutationInput, type ResourcePagination, type ResourcePaginationMode, type ResourceRecord, type ResourceRecordId, type ResourceRequestOptions, type ResourceResult, type ResourceRevision, type ResourceSort, type ResourceTransport, type ResourceTransportRequest, type ResourceUpdateRequest, createEntityHttpTransport, createEntityProtocol, createResourceClient };
1
+ import { $ as ResourceSort, A as ResourceCreateRequest, B as ResourceLifecycleInput, C as EntityUploadInput, D as ResourceCapabilities, E as PortableResourceSchema, F as ResourceFilter, G as ResourceMutationInput, H as ResourceListQuery, I as ResourceGetRequest, J as ResourceRecord, K as ResourcePagination, L as ResourceId, M as ResourceDefinition, N as ResourceError, O as ResourceClient, P as ResourceErrorCode, Q as ResourceRevision, R as ResourceIdentityField, S as EntityUpdateInput, T as IdempotencyKey, U as ResourceListRequest, V as ResourceLifecycleRequest, W as ResourceListResult, X as ResourceRequestOptions, Y as ResourceRecordId, Z as ResourceResult, _ as EntityPage, a as isEntityReadLimitError, b as EntityRequest, c as EntityCreateInput, d as EntityFileValue, et as ResourceTransport, f as EntityFileWrite, g as EntityOperationResult, h as EntityOperation, i as createEntityProtocol, j as ResourceCursor, k as ResourceCreateInput, l as EntityDeleteInput, m as EntityMemberValue, n as EntityHttpTransportOptions, nt as ResourceUpdateRequest, o as createResourceClient, p as EntityListQuery, q as ResourcePaginationMode, r as createEntityHttpTransport, s as EntityClient, t as EntityHttpDestination, tt as ResourceTransportRequest, u as EntityFileFieldWrite, v as EntityProtocol, w as EntityUploadSlot, x as EntityTransport, y as EntityReadLimitDetails, z as ResourceJsonValue } from "./resources-BDcYZzER.js";
2
+ export { type EntityClient, type EntityCreateInput, type EntityDeleteInput, type EntityFileFieldWrite, type EntityFileValue, type EntityFileWrite, type EntityHttpDestination, type EntityHttpTransportOptions, type EntityListQuery, type EntityMemberValue, type EntityOperation, type EntityOperationResult, type EntityPage, type EntityProtocol, type EntityReadLimitDetails, type EntityRequest, type EntityTransport, type EntityUpdateInput, type EntityUploadInput, type EntityUploadSlot, type IdempotencyKey, type PortableResourceSchema, type ResourceCapabilities, type ResourceClient, type ResourceCreateInput, type ResourceCreateRequest, type ResourceCursor, type ResourceDefinition, type ResourceError, type ResourceErrorCode, type ResourceFilter, type ResourceGetRequest, type ResourceId, type ResourceIdentityField, type ResourceJsonValue, type ResourceLifecycleInput, type ResourceLifecycleRequest, type ResourceListQuery, type ResourceListRequest, type ResourceListResult, type ResourceMutationInput, type ResourcePagination, type ResourcePaginationMode, type ResourceRecord, type ResourceRecordId, type ResourceRequestOptions, type ResourceResult, type ResourceRevision, type ResourceSort, type ResourceTransport, type ResourceTransportRequest, type ResourceUpdateRequest, createEntityHttpTransport, createEntityProtocol, createResourceClient, isEntityReadLimitError };
package/dist/resources.js CHANGED
@@ -1,2 +1,2 @@
1
- import { n as createResourceClient, r as createEntityProtocol, t as createEntityHttpTransport } from "./resources-C0wYfzcV.js";
2
- export { createEntityHttpTransport, createEntityProtocol, createResourceClient };
1
+ import { i as isEntityReadLimitError, n as createResourceClient, r as createEntityProtocol, t as createEntityHttpTransport } from "./resources--kU5LiFu.js";
2
+ export { createEntityHttpTransport, createEntityProtocol, createResourceClient, isEntityReadLimitError };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@collective-intelligence/external-apps-client-sdk",
3
- "version": "0.1.10",
3
+ "version": "0.1.11",
4
4
  "description": "Framework-neutral client for Collective Intelligence external applications.",
5
5
  "type": "module",
6
6
  "sideEffects": false,