@opengeni/contracts 0.50.0 → 2.2.0-canary.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/dist/agent-authored-durable-text.d.ts +64 -0
  2. package/dist/atlassian.d.ts +1 -0
  3. package/dist/atlassian.js +14 -13
  4. package/dist/{chunk-Y3MLSLB4.js → chunk-3SIZGL3O.js} +42 -30
  5. package/dist/chunk-3SIZGL3O.js.map +1 -0
  6. package/dist/{chunk-JBCIY7QD.js → chunk-7RMTKFJW.js} +45 -22
  7. package/dist/chunk-7RMTKFJW.js.map +1 -0
  8. package/dist/{chunk-Q6A7XT2N.js → chunk-7ZZ3R27P.js} +9598 -6021
  9. package/dist/chunk-7ZZ3R27P.js.map +1 -0
  10. package/dist/{chunk-5UDNP7AO.js → chunk-MRWYRAS5.js} +56 -8
  11. package/dist/chunk-MRWYRAS5.js.map +1 -0
  12. package/dist/{chunk-LW7OH6CS.js → chunk-N6GRVXAJ.js} +6 -5
  13. package/dist/chunk-N6GRVXAJ.js.map +1 -0
  14. package/dist/{chunk-TZ6YEYN4.js → chunk-NVJMJWLL.js} +3 -1
  15. package/dist/chunk-NVJMJWLL.js.map +1 -0
  16. package/dist/chunk-PX3VCKAU.js +29 -0
  17. package/dist/chunk-PX3VCKAU.js.map +1 -0
  18. package/dist/{chunk-LSB7GRLG.js → chunk-TXTQIYCV.js} +15 -11
  19. package/dist/chunk-TXTQIYCV.js.map +1 -0
  20. package/dist/{chunk-CADSX6UN.js → chunk-Y3KNXVTD.js} +2 -2
  21. package/dist/chunk-YBW5JSA3.js +251 -0
  22. package/dist/chunk-YBW5JSA3.js.map +1 -0
  23. package/dist/company-brain-governed-writes.d.ts +475 -0
  24. package/dist/company-brain.d.ts +398 -0
  25. package/dist/company-profile.d.ts +268 -0
  26. package/dist/connection-authority.d.ts +501 -0
  27. package/dist/connection-authority.js +364 -0
  28. package/dist/connection-authority.js.map +1 -0
  29. package/dist/connector-attachments.d.ts +95 -0
  30. package/dist/connector-attachments.js +51 -0
  31. package/dist/connector-attachments.js.map +1 -0
  32. package/dist/editable-artifact-codec-registry.d.ts +16 -7
  33. package/dist/editable-artifact-codec-registry.js +18 -8
  34. package/dist/editable-artifact-committed-transaction.d.ts +2 -2
  35. package/dist/editable-artifact-committed-transaction.js +2 -2
  36. package/dist/editable-artifact-live.d.ts +11 -12
  37. package/dist/editable-artifact-live.js +111 -46
  38. package/dist/editable-artifact-live.js.map +1 -1
  39. package/dist/editable-artifact-serialized-commit.d.ts +2 -1
  40. package/dist/editable-artifact-serialized-commit.js +9 -8
  41. package/dist/editable-artifact-versions.d.ts +20 -5
  42. package/dist/editable-artifact-versions.js +23 -5
  43. package/dist/editable-artifacts.d.ts +2 -0
  44. package/dist/editable-artifacts.js +51 -39
  45. package/dist/google-drive.d.ts +89 -1
  46. package/dist/google-drive.js +78 -17
  47. package/dist/google-drive.js.map +1 -1
  48. package/dist/governed-learning-activation.d.ts +154 -0
  49. package/dist/governed-learning-evaluator.d.ts +152 -0
  50. package/dist/index.d.ts +12395 -1426
  51. package/dist/index.js +837 -115
  52. package/dist/interaction.d.ts +68 -0
  53. package/dist/knowledge.d.ts +192 -0
  54. package/dist/organization-membership-lifecycle.d.ts +516 -0
  55. package/dist/permissions.d.ts +52 -0
  56. package/dist/personal-github.d.ts +319 -0
  57. package/dist/personal-github.js +209 -0
  58. package/dist/personal-github.js.map +1 -0
  59. package/dist/preference-registry.d.ts +17 -0
  60. package/dist/remember.d.ts +331 -0
  61. package/dist/sandbox-file-artifacts.d.ts +56 -0
  62. package/dist/sandbox-snapshots.d.ts +21 -0
  63. package/dist/slack-bot-scopes.d.ts +34 -14
  64. package/dist/slack-bot-scopes.js +5 -1
  65. package/dist/spreadsheet-artifact-commands.d.ts +2 -3
  66. package/dist/spreadsheet-artifact-commands.js +4 -2
  67. package/dist/spreadsheet-artifact-query.js +3 -2
  68. package/dist/task-notes.d.ts +42 -1
  69. package/dist/tool-result-spill.d.ts +16 -0
  70. package/dist/workspace-instruction-policies.d.ts +81 -0
  71. package/dist/workspace-learning-administration.d.ts +289 -0
  72. package/package.json +13 -1
  73. package/src/agent-authored-durable-text.ts +105 -0
  74. package/src/company-brain-governed-writes.ts +356 -0
  75. package/src/company-brain.ts +201 -0
  76. package/src/company-profile.ts +122 -1
  77. package/src/connection-authority.ts +413 -0
  78. package/src/connector-attachments.ts +327 -0
  79. package/src/editable-artifact-codec-registry.ts +55 -17
  80. package/src/editable-artifact-committed-transaction.ts +44 -31
  81. package/src/editable-artifact-live.ts +123 -57
  82. package/src/editable-artifact-serialized-commit.ts +2 -1
  83. package/src/editable-artifact-versions.ts +26 -5
  84. package/src/editable-artifacts.ts +2 -0
  85. package/src/google-drive.ts +76 -4
  86. package/src/governed-learning-activation.ts +191 -0
  87. package/src/governed-learning-evaluator.ts +176 -0
  88. package/src/index.ts +3182 -483
  89. package/src/interaction.ts +55 -1
  90. package/src/knowledge.ts +133 -6
  91. package/src/organization-membership-lifecycle.ts +330 -0
  92. package/src/permissions.ts +55 -0
  93. package/src/personal-github.ts +267 -0
  94. package/src/preference-registry.ts +17 -0
  95. package/src/remember.ts +242 -0
  96. package/src/sandbox-file-artifacts.ts +65 -0
  97. package/src/sandbox-snapshots.ts +78 -0
  98. package/src/slack-bot-scopes.ts +81 -9
  99. package/src/spreadsheet-artifact-commands.ts +12 -13
  100. package/src/task-notes.ts +14 -1
  101. package/src/tool-result-spill.ts +35 -0
  102. package/src/workspace-instruction-policies.ts +30 -0
  103. package/src/workspace-learning-administration.ts +88 -0
  104. package/dist/chunk-5UDNP7AO.js.map +0 -1
  105. package/dist/chunk-BVGIYW7D.js +0 -11
  106. package/dist/chunk-BVGIYW7D.js.map +0 -1
  107. package/dist/chunk-JBCIY7QD.js.map +0 -1
  108. package/dist/chunk-LSB7GRLG.js.map +0 -1
  109. package/dist/chunk-LW7OH6CS.js.map +0 -1
  110. package/dist/chunk-Q6A7XT2N.js.map +0 -1
  111. package/dist/chunk-TZ6YEYN4.js.map +0 -1
  112. package/dist/chunk-Y3MLSLB4.js.map +0 -1
  113. /package/dist/{chunk-CADSX6UN.js.map → chunk-Y3KNXVTD.js.map} +0 -0
@@ -364,9 +364,25 @@ export const AttachedBrowserDevice = z
364
364
  });
365
365
  export type AttachedBrowserDevice = z.infer<typeof AttachedBrowserDevice>;
366
366
 
367
+ /** One enrolled machine agent currently reporting its browser-bridge inventory.
368
+ * A bridge with zero devices is operational but has no Chrome profile connected
369
+ * through the OpenGeni extension yet. */
370
+ export const AttachedBrowserBridge = z
371
+ .object({
372
+ enrollmentId: z.string().uuid(),
373
+ state: z.enum(["online", "offline"]),
374
+ bridgeGeneration: opaqueGeneration,
375
+ inventoryRevision: z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER),
376
+ connectedProfileCount: z.number().int().nonnegative().max(10_000),
377
+ lastSeenAt: z.string().datetime({ offset: true }),
378
+ })
379
+ .strict();
380
+ export type AttachedBrowserBridge = z.infer<typeof AttachedBrowserBridge>;
381
+
367
382
  export const AttachedBrowserDeviceListResponse = z
368
383
  .object({
369
384
  revision: z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER),
385
+ bridges: z.array(AttachedBrowserBridge).max(10_000),
370
386
  devices: z.array(AttachedBrowserDevice).max(10_000),
371
387
  })
372
388
  .strict();
@@ -2162,6 +2178,41 @@ export const BrowserActionBatch = z
2162
2178
  });
2163
2179
  export type BrowserActionBatch = z.infer<typeof BrowserActionBatch>;
2164
2180
 
2181
+ /** Secret-safe projection of a connected-machine control failure carried in a
2182
+ * standard API error envelope. The outer envelope owns HTTP status, retryability,
2183
+ * and public request correlation; this preserves the exact failing control class
2184
+ * and optional inner request id without exposing subjects, local paths, or tokens. */
2185
+ export const InteractionControlFailureCode = z.enum([
2186
+ "unknown",
2187
+ "unsupported",
2188
+ "os",
2189
+ "not_found",
2190
+ "consent_required",
2191
+ "timeout",
2192
+ "draining",
2193
+ "protocol",
2194
+ "stream",
2195
+ "agent_offline",
2196
+ "fenced",
2197
+ "payload_too_large",
2198
+ ]);
2199
+ export type InteractionControlFailureCode = z.infer<typeof InteractionControlFailureCode>;
2200
+
2201
+ export const InteractionControlFailureDetails = z
2202
+ .object({
2203
+ interactionLayer: z.literal("connected_machine"),
2204
+ interactionSurface: z.enum(["browser", "computer"]),
2205
+ controlFailureCode: InteractionControlFailureCode,
2206
+ controlRequestId: z
2207
+ .string()
2208
+ .min(1)
2209
+ .max(128)
2210
+ .regex(/^[A-Za-z0-9._:-]+$/u)
2211
+ .optional(),
2212
+ })
2213
+ .strict();
2214
+ export type InteractionControlFailureDetails = z.infer<typeof InteractionControlFailureDetails>;
2215
+
2165
2216
  export const InteractionError = z
2166
2217
  .object({
2167
2218
  code: z.enum([
@@ -2502,11 +2553,14 @@ const DirectInteractionFrameStreamAttachment = z
2502
2553
  })
2503
2554
  .strict();
2504
2555
 
2556
+ /** Native tunnels offer `binary` + RFB + bearer (3). Docker and OpenSandbox
2557
+ * hide those on the API interaction frame-proxy, so the viewer sees `binary` +
2558
+ * the proxy grant (2). */
2505
2559
  const DirectComputerRfbAttachment = z
2506
2560
  .object({
2507
2561
  kind: z.literal("direct_rfb"),
2508
2562
  url: boundedUrl,
2509
- protocols: z.array(z.string().min(1).max(2_048)).length(3),
2563
+ protocols: z.array(z.string().min(1).max(2_048)).min(2).max(3),
2510
2564
  })
2511
2565
  .strict();
2512
2566
 
package/src/knowledge.ts CHANGED
@@ -3,6 +3,7 @@ import { z } from "zod";
3
3
  export const KNOWLEDGE_BROWSE_CURSOR_MAX_CHARS = 1_024;
4
4
  export const KNOWLEDGE_BROWSE_DEFAULT_LIMIT = 20;
5
5
  export const KNOWLEDGE_BROWSE_MAX_LIMIT = 50;
6
+ export const KNOWLEDGE_BROWSE_MAX_RESPONSE_BYTES = 64 * 1_024;
6
7
  export const KNOWLEDGE_TITLE_MAX_BYTES = 1_024;
7
8
  export const KNOWLEDGE_BODY_MAX_BYTES = 16 * 1_024;
8
9
  export const KNOWLEDGE_SUMMARY_MAX_BYTES = 4 * 1_024;
@@ -13,6 +14,16 @@ export const KNOWLEDGE_METADATA_MAX_ITEMS = 64;
13
14
  export const KNOWLEDGE_METADATA_MAX_DEPTH = 4;
14
15
  export const KNOWLEDGE_SOURCE_STRING_MAX_BYTES = 2_048;
15
16
  export const KNOWLEDGE_SOURCE_URI_MAX_BYTES = 8_192;
17
+ export const KNOWLEDGE_SEARCH_MAX_RESULTS = 50;
18
+ export const KNOWLEDGE_SEARCH_MAX_RESPONSE_BYTES = 64 * 1_024;
19
+ export const KNOWLEDGE_SEARCH_TOKEN_ESTIMATE_BYTES_PER_TOKEN = 4;
20
+ export const KNOWLEDGE_SEARCH_MAX_FLOOR_OMISSIONS = 200;
21
+ // Cosine similarity for unrelated embeddings clusters around 0.5 after the
22
+ // distance conversion used by Documents. Keyword search already excludes
23
+ // non-matches in SQL, but a small normalized floor removes incidental hits.
24
+ export const KNOWLEDGE_SEARCH_MIN_VECTOR_SCORE = 0.52;
25
+ export const KNOWLEDGE_SEARCH_MIN_KEYWORD_SCORE = 0.01;
26
+ export const KNOWLEDGE_QUERY_MAX_BYTES = 4 * 1_024;
16
27
 
17
28
  const utf8Bytes = (value: string): number => new TextEncoder().encode(value).byteLength;
18
29
  const boundedUtf8 = (maxBytes: number) =>
@@ -102,6 +113,59 @@ export const KnowledgeSource = z.object({
102
113
  });
103
114
  export type KnowledgeSource = z.infer<typeof KnowledgeSource>;
104
115
 
116
+ export const KnowledgeSearchRequest = z
117
+ .object({
118
+ query: boundedUtf8(KNOWLEDGE_QUERY_MAX_BYTES).pipe(z.string().min(1)),
119
+ baseIds: z.array(z.string().uuid()).max(50).optional(),
120
+ mode: z.enum(["hybrid", "vector", "keyword"]).optional(),
121
+ sourceKinds: z.array(KnowledgeSource.shape.kind).max(8).optional(),
122
+ aclTags: z
123
+ .array(boundedUtf8(KNOWLEDGE_TOPIC_MAX_BYTES).pipe(z.string().min(1)))
124
+ .max(64)
125
+ .optional(),
126
+ limit: z.number().int().positive().max(KNOWLEDGE_SEARCH_MAX_RESULTS).default(5),
127
+ })
128
+ .strict();
129
+ export type KnowledgeSearchRequest = z.input<typeof KnowledgeSearchRequest>;
130
+
131
+ export const KnowledgeBrowseRequest = z
132
+ .object({
133
+ parentId: KnowledgeRecordId.optional(),
134
+ topic: boundedUtf8(KNOWLEDGE_TOPIC_MAX_BYTES).pipe(z.string().min(1)).optional(),
135
+ sourceKinds: z.array(KnowledgeSource.shape.kind).max(8).optional(),
136
+ cursor: z.string().min(1).max(KNOWLEDGE_BROWSE_CURSOR_MAX_CHARS).optional(),
137
+ limit: z
138
+ .number()
139
+ .int()
140
+ .positive()
141
+ .max(KNOWLEDGE_BROWSE_MAX_LIMIT)
142
+ .default(KNOWLEDGE_BROWSE_DEFAULT_LIMIT),
143
+ })
144
+ .strict()
145
+ .superRefine((value, context) => {
146
+ if (value.parentId && (value.topic || (value.sourceKinds?.length ?? 0) > 0)) {
147
+ context.addIssue({
148
+ code: z.ZodIssueCode.custom,
149
+ message: "document contents do not accept topic or source filters",
150
+ });
151
+ }
152
+ });
153
+ export type KnowledgeBrowseRequest = z.input<typeof KnowledgeBrowseRequest>;
154
+
155
+ export const KnowledgeProviderCitation = z.object({
156
+ provider: z.literal("google_drive"),
157
+ externalObjectId: boundedUtf8(KNOWLEDGE_SOURCE_STRING_MAX_BYTES),
158
+ providerRevision: boundedUtf8(KNOWLEDGE_SOURCE_STRING_MAX_BYTES).nullable(),
159
+ sourceVersion: boundedUtf8(KNOWLEDGE_SOURCE_STRING_MAX_BYTES),
160
+ driveId: boundedUtf8(KNOWLEDGE_SOURCE_STRING_MAX_BYTES).nullable(),
161
+ deepLink: boundedUtf8(KNOWLEDGE_SOURCE_URI_MAX_BYTES).pipe(z.string().min(1)).nullable(),
162
+ aclRevision: z.string().regex(/^[0-9a-f]{64}$/u),
163
+ authorizationObservedAt: z.string().datetime({ offset: true }),
164
+ authorizationExpiresAt: z.string().datetime({ offset: true }),
165
+ reauthorizedAt: z.string().datetime({ offset: true }),
166
+ });
167
+ export type KnowledgeProviderCitation = z.infer<typeof KnowledgeProviderCitation>;
168
+
105
169
  export const KnowledgeLinkTarget = z.discriminatedUnion("kind", [
106
170
  z.object({
107
171
  kind: z.literal("knowledge"),
@@ -144,6 +208,7 @@ export const KnowledgeRecord = z.object({
144
208
  provenance: z.object({
145
209
  source: KnowledgeSource,
146
210
  indexedAt: z.string(),
211
+ citation: KnowledgeProviderCitation.nullable().optional(),
147
212
  }),
148
213
  lifecycle: z.object({
149
214
  state: z.literal("active"),
@@ -171,9 +236,10 @@ export const KnowledgeRecord = z.object({
171
236
  "provenance.source.title",
172
237
  "provenance.source.author",
173
238
  "provenance.source.version",
239
+ "provenance.citation",
174
240
  ]),
175
241
  )
176
- .max(10),
242
+ .max(11),
177
243
  }),
178
244
  });
179
245
  export type KnowledgeRecord = z.infer<typeof KnowledgeRecord>;
@@ -181,16 +247,59 @@ export type KnowledgeRecord = z.infer<typeof KnowledgeRecord>;
181
247
  export const KnowledgeSearchResult = z.object({
182
248
  record: KnowledgeRecord,
183
249
  retrieval: z.object({
184
- score: z.number(),
250
+ /** Final bounded ordering score after the documented quality adjustment. */
251
+ score: z.number().min(0).max(1),
252
+ /** Semantic score before the quality adjustment. */
253
+ semanticScore: z.number().min(0).max(1),
185
254
  matchType: z.enum(["hybrid", "vector", "keyword"]),
186
- vectorScore: z.number().nullable(),
187
- keywordScore: z.number().nullable(),
255
+ vectorScore: z.number().min(0).max(1).nullable(),
256
+ keywordScore: z.number().min(0).max(1).nullable(),
257
+ relevanceSignals: z
258
+ .array(z.enum(["vector", "keyword"]))
259
+ .min(1)
260
+ .max(2),
261
+ freshness: z.enum(["current", "aging", "stale"]),
262
+ qualityAdjustment: z.number().min(0).max(1),
263
+ duplicateCount: z.number().int().nonnegative(),
188
264
  }),
189
265
  });
190
266
  export type KnowledgeSearchResult = z.infer<typeof KnowledgeSearchResult>;
191
267
 
192
268
  export const KnowledgeSearchResponse = z.object({
193
- results: z.array(KnowledgeSearchResult),
269
+ results: z.array(KnowledgeSearchResult).max(KNOWLEDGE_SEARCH_MAX_RESULTS),
270
+ selection: z.object({
271
+ relevanceFloor: z.object({
272
+ policy: z.literal("any_signal"),
273
+ vectorScore: z.literal(KNOWLEDGE_SEARCH_MIN_VECTOR_SCORE),
274
+ keywordScore: z.literal(KNOWLEDGE_SEARCH_MIN_KEYWORD_SCORE),
275
+ }),
276
+ dedupe: z.object({
277
+ policy: z.literal("exact_textual_content"),
278
+ }),
279
+ candidates: z.object({
280
+ ranked: z.number().int().nonnegative().max(KNOWLEDGE_SEARCH_MAX_RESULTS),
281
+ rechecked: z.number().int().nonnegative().max(KNOWLEDGE_SEARCH_MAX_RESULTS),
282
+ omittedOnRecheck: z.number().int().nonnegative().max(KNOWLEDGE_SEARCH_MAX_RESULTS),
283
+ }),
284
+ omitted: z.object({
285
+ belowRelevanceFloor: z.number().int().nonnegative().max(KNOWLEDGE_SEARCH_MAX_FLOOR_OMISSIONS),
286
+ asDuplicate: z.number().int().nonnegative().max(KNOWLEDGE_SEARCH_MAX_RESULTS),
287
+ forLimit: z.number().int().nonnegative().max(KNOWLEDGE_SEARCH_MAX_RESULTS),
288
+ forResponseBudget: z.number().int().nonnegative().max(KNOWLEDGE_SEARCH_MAX_RESULTS),
289
+ }),
290
+ budget: z.object({
291
+ maxResults: z.literal(KNOWLEDGE_SEARCH_MAX_RESULTS),
292
+ maxResponseBytes: z.literal(KNOWLEDGE_SEARCH_MAX_RESPONSE_BYTES),
293
+ responseBytes: z.number().int().nonnegative().max(KNOWLEDGE_SEARCH_MAX_RESPONSE_BYTES),
294
+ tokenEstimateBytesPerToken: z.literal(KNOWLEDGE_SEARCH_TOKEN_ESTIMATE_BYTES_PER_TOKEN),
295
+ estimatedTokens: z.number().int().nonnegative(),
296
+ maxEstimatedTokens: z.literal(
297
+ Math.ceil(
298
+ KNOWLEDGE_SEARCH_MAX_RESPONSE_BYTES / KNOWLEDGE_SEARCH_TOKEN_ESTIMATE_BYTES_PER_TOKEN,
299
+ ),
300
+ ),
301
+ }),
302
+ }),
194
303
  });
195
304
  export type KnowledgeSearchResponse = z.infer<typeof KnowledgeSearchResponse>;
196
305
 
@@ -200,8 +309,26 @@ export const KnowledgeGetResponse = z.object({
200
309
  export type KnowledgeGetResponse = z.infer<typeof KnowledgeGetResponse>;
201
310
 
202
311
  export const KnowledgeBrowseResponse = z.object({
203
- records: z.array(KnowledgeRecord),
312
+ records: z.array(KnowledgeRecord).max(KNOWLEDGE_BROWSE_MAX_LIMIT),
204
313
  nextCursor: z.string().min(1).max(KNOWLEDGE_BROWSE_CURSOR_MAX_CHARS).nullable(),
205
314
  hasMore: z.boolean(),
315
+ selection: z.object({
316
+ omitted: z.object({
317
+ forResponseBudget: z.number().int().nonnegative().max(KNOWLEDGE_BROWSE_MAX_LIMIT),
318
+ }),
319
+ compactedRecordCount: z.number().int().nonnegative().max(1),
320
+ budget: z.object({
321
+ maxResults: z.literal(KNOWLEDGE_BROWSE_MAX_LIMIT),
322
+ maxResponseBytes: z.literal(KNOWLEDGE_BROWSE_MAX_RESPONSE_BYTES),
323
+ responseBytes: z.number().int().nonnegative().max(KNOWLEDGE_BROWSE_MAX_RESPONSE_BYTES),
324
+ tokenEstimateBytesPerToken: z.literal(KNOWLEDGE_SEARCH_TOKEN_ESTIMATE_BYTES_PER_TOKEN),
325
+ estimatedTokens: z.number().int().nonnegative(),
326
+ maxEstimatedTokens: z.literal(
327
+ Math.ceil(
328
+ KNOWLEDGE_BROWSE_MAX_RESPONSE_BYTES / KNOWLEDGE_SEARCH_TOKEN_ESTIMATE_BYTES_PER_TOKEN,
329
+ ),
330
+ ),
331
+ }),
332
+ }),
206
333
  });
207
334
  export type KnowledgeBrowseResponse = z.infer<typeof KnowledgeBrowseResponse>;
@@ -0,0 +1,330 @@
1
+ import { z } from "zod";
2
+ import { Permission } from "./permissions";
3
+
4
+ export const OrganizationMembershipRole = z.enum(["owner", "admin", "member"]);
5
+ export type OrganizationMembershipRole = z.infer<typeof OrganizationMembershipRole>;
6
+
7
+ export const OrganizationInvitationStatus = z.enum(["pending", "accepted", "revoked", "expired"]);
8
+ export type OrganizationInvitationStatus = z.infer<typeof OrganizationInvitationStatus>;
9
+
10
+ export const OrganizationInvitation = z.object({
11
+ id: z.string().uuid(),
12
+ organizationId: z.string().uuid(),
13
+ targetEmail: z.string().email(),
14
+ targetName: z.string().trim().min(1).max(120).nullable().default(null),
15
+ initialWorkspaceIds: z.array(z.string().uuid()).max(100).default([]),
16
+ role: OrganizationMembershipRole,
17
+ status: OrganizationInvitationStatus,
18
+ revision: z.number().int().positive(),
19
+ expiresAt: z.string().datetime({ offset: true }),
20
+ acceptedMembershipId: z.string().uuid().nullable(),
21
+ createdAt: z.string().datetime({ offset: true }),
22
+ updatedAt: z.string().datetime({ offset: true }),
23
+ });
24
+ export type OrganizationInvitation = z.infer<typeof OrganizationInvitation>;
25
+
26
+ export const OrganizationMember = z.object({
27
+ id: z.string().uuid(),
28
+ organizationId: z.string().uuid(),
29
+ subjectId: z.string().min(1).max(1024),
30
+ name: z.string().min(1).max(1024).nullable().default(null),
31
+ email: z.string().email().max(320).nullable().default(null),
32
+ role: OrganizationMembershipRole,
33
+ status: z.enum(["provisioning", "active", "suspended", "revoked"]),
34
+ authorizationRevision: z.number().int().positive(),
35
+ personalWorkspaceId: z.string().uuid().nullable(),
36
+ revokedAt: z.string().datetime({ offset: true }).nullable(),
37
+ personalRetentionUntil: z.string().datetime({ offset: true }).nullable(),
38
+ createdAt: z.string().datetime({ offset: true }),
39
+ updatedAt: z.string().datetime({ offset: true }),
40
+ });
41
+ export type OrganizationMember = z.infer<typeof OrganizationMember>;
42
+
43
+ export const OrganizationSummary = z.object({
44
+ id: z.string().uuid(),
45
+ name: z.string().trim().min(1).max(120),
46
+ createdAt: z.string().datetime({ offset: true }),
47
+ updatedAt: z.string().datetime({ offset: true }),
48
+ });
49
+ export type OrganizationSummary = z.infer<typeof OrganizationSummary>;
50
+
51
+ export const OrganizationPrivateSessionSettings = z.object({
52
+ organizationId: z.string().uuid(),
53
+ enabled: z.boolean(),
54
+ available: z.boolean(),
55
+ version: z.number().int().nonnegative(),
56
+ updatedAt: z.string().datetime({ offset: true }),
57
+ changed: z.boolean().optional(),
58
+ });
59
+ export type OrganizationPrivateSessionSettings = z.infer<typeof OrganizationPrivateSessionSettings>;
60
+
61
+ export const UpdateOrganizationPrivateSessionSettingsRequest = z
62
+ .object({
63
+ enabled: z.boolean(),
64
+ expectedVersion: z.number().int().nonnegative(),
65
+ operationId: z.string().uuid(),
66
+ })
67
+ .strict();
68
+ export type UpdateOrganizationPrivateSessionSettingsRequest = z.infer<
69
+ typeof UpdateOrganizationPrivateSessionSettingsRequest
70
+ >;
71
+
72
+ export const OrganizationWorkspaceAccessMember = z.object({
73
+ membershipId: z.string().uuid(),
74
+ subjectId: z.string().min(1).max(1024),
75
+ subjectLabel: z.string().min(1).max(1024).nullable(),
76
+ principalKind: z.enum(["human", "service"]),
77
+ role: z.string().min(1).max(64),
78
+ permissions: z.array(z.string().min(1).max(128)),
79
+ createdAt: z.string().datetime({ offset: true }),
80
+ });
81
+ export type OrganizationWorkspaceAccessMember = z.infer<typeof OrganizationWorkspaceAccessMember>;
82
+
83
+ export const OrganizationWorkspaceAccess = z.object({
84
+ id: z.string().uuid(),
85
+ name: z.string().min(1),
86
+ slug: z.string().nullable(),
87
+ createdAt: z.string().datetime({ offset: true }),
88
+ updatedAt: z.string().datetime({ offset: true }),
89
+ members: z.array(OrganizationWorkspaceAccessMember).max(1000),
90
+ });
91
+ export type OrganizationWorkspaceAccess = z.infer<typeof OrganizationWorkspaceAccess>;
92
+
93
+ export const OrganizationAdministrationOverview = z.object({
94
+ organization: OrganizationSummary,
95
+ workspaces: z.array(OrganizationWorkspaceAccess).max(500),
96
+ });
97
+ export type OrganizationAdministrationOverview = z.infer<typeof OrganizationAdministrationOverview>;
98
+
99
+ // Organization-control-plane assignment of an existing active organization
100
+ // member to a shared workspace. The target is a membership rather than an
101
+ // email address: joining the organization and receiving workspace access stay
102
+ // two explicit lifecycle steps, and this surface cannot become a user lookup.
103
+ export const AddOrganizationWorkspaceMemberRequest = z.object({
104
+ organizationMembershipId: z.string().uuid(),
105
+ role: z.string().trim().min(1).max(64).optional(),
106
+ permissions: z.array(Permission).max(128),
107
+ });
108
+ export type AddOrganizationWorkspaceMemberRequest = z.infer<
109
+ typeof AddOrganizationWorkspaceMemberRequest
110
+ >;
111
+
112
+ export const CreateOrganizationWorkspaceRequest = z.object({
113
+ name: z.string().trim().min(1).max(120),
114
+ slug: z.string().trim().min(1).max(120).nullable().optional(),
115
+ agentInstructions: z.string().nullable().optional(),
116
+ operationId: z.string().uuid(),
117
+ });
118
+ export type CreateOrganizationWorkspaceRequest = z.infer<typeof CreateOrganizationWorkspaceRequest>;
119
+
120
+ export const CreateOrganizationRequest = z.object({
121
+ name: z.string().trim().min(1).max(120),
122
+ operationId: z.string().uuid(),
123
+ });
124
+ export type CreateOrganizationRequest = z.infer<typeof CreateOrganizationRequest>;
125
+
126
+ export const CreateOrganizationResponse = z.object({
127
+ organization: OrganizationSummary,
128
+ workspaceId: z.string().uuid(),
129
+ });
130
+ export type CreateOrganizationResponse = z.infer<typeof CreateOrganizationResponse>;
131
+
132
+ export const UpdateOrganizationNameRequest = z.object({
133
+ name: z.string().trim().min(1).max(120),
134
+ expectedUpdatedAt: z.string().datetime({ offset: true }),
135
+ operationId: z.string().uuid(),
136
+ });
137
+ export type UpdateOrganizationNameRequest = z.infer<typeof UpdateOrganizationNameRequest>;
138
+
139
+ export const OrganizationRetentionPolicy = z
140
+ .object({
141
+ organizationId: z.string().uuid(),
142
+ mode: z.enum(["retain", "delete_after"]),
143
+ retentionDays: z.number().int().min(30).max(90).nullable(),
144
+ version: z.number().int().positive(),
145
+ updatedAt: z.string().datetime({ offset: true }),
146
+ })
147
+ .superRefine((value, context) => {
148
+ if ((value.mode === "retain") !== (value.retentionDays === null)) {
149
+ context.addIssue({
150
+ code: "custom",
151
+ path: ["retentionDays"],
152
+ message: "retain requires no duration; delete_after requires a duration",
153
+ });
154
+ }
155
+ });
156
+ export type OrganizationRetentionPolicy = z.infer<typeof OrganizationRetentionPolicy>;
157
+
158
+ export const OrganizationRetentionDeletionClaim = z.object({
159
+ organizationId: z.string().uuid(),
160
+ membershipId: z.string().uuid(),
161
+ operationId: z.string().uuid(),
162
+ retentionUntil: z.string().datetime({ offset: true }),
163
+ claimExpiresAt: z.string().datetime({ offset: true }),
164
+ personalWorkspaceId: z.string().uuid().nullable(),
165
+ objectCount: z.number().int().nonnegative(),
166
+ deletedObjectCount: z.number().int().nonnegative(),
167
+ });
168
+ export type OrganizationRetentionDeletionClaim = z.infer<typeof OrganizationRetentionDeletionClaim>;
169
+
170
+ export const OrganizationRetentionDeletionObject = z.object({
171
+ objectKind: z.enum([
172
+ "file",
173
+ "session_recording",
174
+ "browser_state_artifact",
175
+ "browser_state_upload",
176
+ "transcription_recording_object",
177
+ "video_staging_reference",
178
+ "workspace_artifact_version",
179
+ "editable_artifact_blob",
180
+ "workspace_capture_manifest",
181
+ "workspace_capture_tree_index",
182
+ "workspace_capture_blob",
183
+ ]),
184
+ sourceId: z.string().min(1).max(2048),
185
+ objectBucket: z.string().min(1).max(1024),
186
+ objectKey: z.string().min(1).max(4096),
187
+ });
188
+ export type OrganizationRetentionDeletionObject = z.infer<
189
+ typeof OrganizationRetentionDeletionObject
190
+ >;
191
+
192
+ export const OrganizationRetentionDatabaseFinalization = z.object({
193
+ organizationId: z.string().uuid(),
194
+ membershipId: z.string().uuid(),
195
+ operationId: z.string().uuid(),
196
+ outcome: z.literal("cleanup_pending"),
197
+ objectBucket: z.string().min(1).max(1024),
198
+ objectCount: z.number().int().nonnegative(),
199
+ deletedResources: z.record(z.string(), z.number().int().nonnegative()),
200
+ databaseFinalizedAt: z.string().datetime({ offset: true }),
201
+ });
202
+ export type OrganizationRetentionDatabaseFinalization = z.infer<
203
+ typeof OrganizationRetentionDatabaseFinalization
204
+ >;
205
+
206
+ export const OrganizationRetentionDeletionResult = z.object({
207
+ organizationId: z.string().uuid(),
208
+ membershipId: z.string().uuid(),
209
+ operationId: z.string().uuid(),
210
+ outcome: z.enum(["completed", "already_completed"]),
211
+ deletedResources: z.record(z.string(), z.number().int().nonnegative()),
212
+ completedAt: z.string().datetime({ offset: true }),
213
+ });
214
+ export type OrganizationRetentionDeletionResult = z.infer<
215
+ typeof OrganizationRetentionDeletionResult
216
+ >;
217
+
218
+ export const OrganizationRetentionDeletionPreview = z.object({
219
+ membershipId: z.string().uuid(),
220
+ retentionUntil: z.string().datetime({ offset: true }),
221
+ personalWorkspaceId: z.string().uuid().nullable(),
222
+ resourceCount: z.number().int().nonnegative(),
223
+ objectCount: z.number().int().nonnegative(),
224
+ });
225
+ export type OrganizationRetentionDeletionPreview = z.infer<
226
+ typeof OrganizationRetentionDeletionPreview
227
+ >;
228
+
229
+ export const CreateOrganizationInvitationRequest = z.object({
230
+ email: z.string().email().max(320),
231
+ name: z.string().trim().min(1).max(120).optional(),
232
+ initialWorkspaceIds: z.array(z.string().uuid()).max(100).default([]),
233
+ role: OrganizationMembershipRole.default("member"),
234
+ expiresAt: z.string().datetime({ offset: true }),
235
+ operationId: z.string().uuid(),
236
+ });
237
+ export type CreateOrganizationInvitationRequest = z.infer<
238
+ typeof CreateOrganizationInvitationRequest
239
+ >;
240
+
241
+ export const AcceptOrganizationInvitationRequest = z.object({
242
+ expectedRevision: z.number().int().positive(),
243
+ operationId: z.string().uuid(),
244
+ });
245
+ export type AcceptOrganizationInvitationRequest = z.infer<
246
+ typeof AcceptOrganizationInvitationRequest
247
+ >;
248
+
249
+ export const RevokeOrganizationInvitationRequest = AcceptOrganizationInvitationRequest;
250
+ export type RevokeOrganizationInvitationRequest = z.infer<
251
+ typeof RevokeOrganizationInvitationRequest
252
+ >;
253
+
254
+ export const OrganizationMemberTransitionKind = z.enum([
255
+ "change_role",
256
+ "suspend",
257
+ "reactivate",
258
+ "offboard",
259
+ ]);
260
+ export type OrganizationMemberTransitionKind = z.infer<typeof OrganizationMemberTransitionKind>;
261
+
262
+ export const UpdateOrganizationMemberRequest = z
263
+ .object({
264
+ kind: OrganizationMemberTransitionKind,
265
+ role: OrganizationMembershipRole.optional(),
266
+ expectedAuthorizationRevision: z.number().int().positive(),
267
+ operationId: z.string().uuid(),
268
+ reason: z.string().trim().min(1).max(512).optional(),
269
+ })
270
+ .superRefine((value, context) => {
271
+ if ((value.kind === "change_role") !== (value.role !== undefined)) {
272
+ context.addIssue({
273
+ code: "custom",
274
+ path: ["role"],
275
+ message: "role is required only for change_role",
276
+ });
277
+ }
278
+ });
279
+ export type UpdateOrganizationMemberRequest = z.infer<typeof UpdateOrganizationMemberRequest>;
280
+
281
+ export const UpdateOrganizationRetentionPolicyRequest = z
282
+ .object({
283
+ mode: z.enum(["retain", "delete_after"]),
284
+ retentionDays: z.number().int().min(30).max(90).nullable(),
285
+ expectedVersion: z.number().int().positive(),
286
+ operationId: z.string().uuid(),
287
+ })
288
+ .superRefine((value, context) => {
289
+ if ((value.mode === "retain") !== (value.retentionDays === null)) {
290
+ context.addIssue({
291
+ code: "custom",
292
+ path: ["retentionDays"],
293
+ message: "retain requires no duration; delete_after requires a duration",
294
+ });
295
+ }
296
+ });
297
+ export type UpdateOrganizationRetentionPolicyRequest = z.infer<
298
+ typeof UpdateOrganizationRetentionPolicyRequest
299
+ >;
300
+
301
+ export const ListOrganizationInvitationsResponse = z.object({
302
+ invitations: z.array(OrganizationInvitation).max(101),
303
+ });
304
+ export const ListOrganizationInvitationsPageQuery = z.object({
305
+ cursor: z.string().uuid().optional(),
306
+ limit: z.coerce.number().int().min(1).max(100).default(50),
307
+ });
308
+ export type ListOrganizationInvitationsPageQuery = z.infer<
309
+ typeof ListOrganizationInvitationsPageQuery
310
+ >;
311
+ export const ListOrganizationInvitationsPageResponse = z.object({
312
+ invitations: z.array(OrganizationInvitation).max(100),
313
+ nextCursor: z.string().uuid().nullable(),
314
+ });
315
+ export type ListOrganizationInvitationsPageResponse = z.infer<
316
+ typeof ListOrganizationInvitationsPageResponse
317
+ >;
318
+ export const AcceptOrganizationInvitationResponse = z.object({
319
+ invitation: OrganizationInvitation,
320
+ membership: OrganizationMember,
321
+ });
322
+ export type AcceptOrganizationInvitationResponse = z.infer<
323
+ typeof AcceptOrganizationInvitationResponse
324
+ >;
325
+ export const ListOrganizationMembersResponse = z.object({
326
+ members: z.array(OrganizationMember),
327
+ });
328
+ export const ListSelfOrganizationMembershipsResponse = z.object({
329
+ memberships: z.array(OrganizationMember),
330
+ });
@@ -0,0 +1,55 @@
1
+ import { z } from "zod";
2
+
3
+ /** Canonical public permission vocabulary shared by operational and control-plane contracts. */
4
+ export const Permission = z.enum([
5
+ "account:read",
6
+ "account:admin",
7
+ "members:manage",
8
+ "workspace:create",
9
+ "billing:read",
10
+ "billing:manage",
11
+ "workspace:read",
12
+ "workspace:admin",
13
+ "sessions:create",
14
+ "sessions:read",
15
+ "sessions:control",
16
+ "stream:view",
17
+ "stream:control",
18
+ "stream:acknowledge",
19
+ "files:upload",
20
+ "files:read",
21
+ "files:write",
22
+ "terminal:attach",
23
+ "documents:manage",
24
+ "documents:search",
25
+ "scheduled_tasks:manage",
26
+ "scheduled_tasks:run",
27
+ "github:manage",
28
+ "github:use",
29
+ "api_keys:manage",
30
+ "connections:read",
31
+ "connections:write",
32
+ /** @deprecated alias of variable-sets:manage */
33
+ "environments:manage",
34
+ /** @deprecated alias of variable-sets:use */
35
+ "environments:use",
36
+ "variable-sets:list",
37
+ "variable-sets:read",
38
+ "variable-sets:write",
39
+ "variable-sets:manage",
40
+ "variable-sets:attach",
41
+ "variable-sets:use",
42
+ "secrets:list",
43
+ "secrets:read",
44
+ "secrets:write",
45
+ "mcp_servers:attach",
46
+ "codemode:call",
47
+ "goals:manage",
48
+ "enrollments:read",
49
+ "enrollments:manage",
50
+ "rigs:use",
51
+ "rigs:manage",
52
+ "artifacts:read",
53
+ "artifacts:publish",
54
+ ]);
55
+ export type Permission = z.infer<typeof Permission>;