@granular-software/sdk 0.1.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.
@@ -0,0 +1,616 @@
1
+ import * as Automerge from '@automerge/automerge';
2
+ import { Doc } from '@automerge/automerge';
3
+ import { W as WSClientOptions, T as ToolWithHandler, P as PublishToolsResult, J as Job, a as ToolHandler, I as InstanceToolHandler, D as DomainState, G as GranularOptions, R as RecordUserOptions, U as User, C as ConnectOptions, E as EnvironmentData, b as GraphQLResult, c as DefineRelationshipOptions, d as RelationshipInfo, M as ModelRef, e as ManifestContent, f as RecordObjectOptions, g as RecordObjectResult, S as SandboxListResponse, h as Sandbox, i as CreateSandboxData, j as DeleteResponse, k as PermissionProfile, l as CreatePermissionProfileData, m as CreateEnvironmentData, n as Subject, A as AssignmentListResponse } from './types-D46q5WTh.js';
4
+ export { $ as APIError, r as Assignment, w as Build, x as BuildListResponse, B as BuildPolicy, v as BuildStatus, s as EnvironmentListResponse, y as JobStatus, z as JobSubmitResult, t as Manifest, Z as ManifestImport, u as ManifestListResponse, Y as ManifestOperation, V as ManifestPropertySpec, X as ManifestRelationshipDef, _ as ManifestVolume, q as PermissionProfileListResponse, p as PermissionRules, F as Prompt, H as RPCRequest, N as RPCRequestFromServer, K as RPCResponse, L as SyncMessage, O as ToolInvokeParams, Q as ToolResultParams, o as ToolSchema } from './types-D46q5WTh.js';
5
+
6
+ declare class WSClient {
7
+ private ws;
8
+ private url;
9
+ private sessionId;
10
+ private token;
11
+ private messageQueue;
12
+ private syncHandlers;
13
+ private rpcHandlers;
14
+ private eventHandlers;
15
+ private nextRpcId;
16
+ doc: Automerge.Doc<Record<string, unknown>>;
17
+ private syncState;
18
+ private reconnectTimer;
19
+ private isExplicitlyDisconnected;
20
+ constructor(options: WSClientOptions);
21
+ /**
22
+ * Connect to the WebSocket server
23
+ * @returns {Promise<void>} Resolves when connection is open
24
+ */
25
+ connect(): Promise<void>;
26
+ private handleDisconnect;
27
+ private handleMessage;
28
+ /**
29
+ * Make an RPC call to the server
30
+ * @param {string} method - RPC method name
31
+ * @param {unknown} params - Request parameters
32
+ * @returns {Promise<unknown>} Response result
33
+ * @throws {Error} If connection is closed or timeout occurs
34
+ */
35
+ call(method: string, params: unknown): Promise<unknown>;
36
+ private handleIncomingRpc;
37
+ /**
38
+ * Subscribe to client events
39
+ * @param {string} event - Event name
40
+ * @param {Function} handler - Event handler
41
+ */
42
+ on(event: string, handler: (params: unknown) => void): void;
43
+ /**
44
+ * Register an RPC handler for incoming server requests
45
+ * @param {string} method - RPC method name
46
+ * @param {Function} handler - Handler function
47
+ */
48
+ registerRpcHandler(method: string, handler: (params: unknown) => Promise<unknown>): void;
49
+ /**
50
+ * Unsubscribe from client events
51
+ * @param {string} event - Event name
52
+ * @param {Function} handler - Handler to remove
53
+ */
54
+ off(event: string, handler: (params: unknown) => void): void;
55
+ /**
56
+ * Emit an event locally
57
+ * @param {string} event - Event name
58
+ * @param params - Event data
59
+ */
60
+ emit(event: string, params: unknown): void;
61
+ /**
62
+ * Disconnect the WebSocket and clear state
63
+ */
64
+ disconnect(): void;
65
+ }
66
+
67
+ declare class Session {
68
+ protected client: WSClient;
69
+ private clientId;
70
+ private jobsMap;
71
+ private eventListeners;
72
+ private toolHandlers;
73
+ /** Tracks which tools are instance methods (className set, not static) */
74
+ private instanceTools;
75
+ private currentDomainRevision;
76
+ constructor(client: WSClient, clientId?: string);
77
+ get document(): Doc<Record<string, unknown>>;
78
+ get domainRevision(): string | null;
79
+ /**
80
+ * Make a raw RPC call to the session's Durable Object.
81
+ *
82
+ * Use this when you need to call an RPC method that doesn't have a
83
+ * dedicated wrapper method on the Session/Environment class.
84
+ *
85
+ * @param method - RPC method name (e.g. 'domain.fetchPackagePart')
86
+ * @param params - Request parameters
87
+ * @returns The raw RPC response
88
+ *
89
+ * @example
90
+ * ```typescript
91
+ * const result = await env.rpc('domain.fetchPackagePart', {
92
+ * moduleSpecifier: '@sandbox/domain',
93
+ * part: 'types',
94
+ * });
95
+ * ```
96
+ */
97
+ rpc<T = unknown>(method: string, params?: Record<string, unknown>): Promise<T>;
98
+ /**
99
+ * Send client hello to establish the session
100
+ */
101
+ hello(): Promise<{
102
+ ok: boolean;
103
+ environmentId?: string;
104
+ docId?: string;
105
+ }>;
106
+ /**
107
+ * Publish tools to the sandbox and register handlers for reverse-RPC.
108
+ *
109
+ * Tools can be:
110
+ * - **Instance methods**: set `className` (handler receives `(objectId, params)`)
111
+ * - **Static methods**: set `className` + `static: true` (handler receives `(params)`)
112
+ * - **Global tools**: omit `className` (handler receives `(params)`)
113
+ *
114
+ * Both `inputSchema` and `outputSchema` accept JSON Schema objects. The
115
+ * `outputSchema` drives the return type in the auto-generated TypeScript
116
+ * class declarations that sandbox code imports from `./sandbox-tools`.
117
+ *
118
+ * This method:
119
+ * 1. Extracts tool schemas (including `outputSchema`) from the provided tools
120
+ * 2. Publishes them via `client.publishRawToolCatalog` RPC
121
+ * 3. Registers handlers locally for `tool.invoke` RPC calls
122
+ * 4. Returns the `domainRevision` needed for job submission
123
+ *
124
+ * @param tools - Array of tools with handlers
125
+ * @param revision - Optional revision string (default: "1.0.0")
126
+ * @returns PublishToolsResult with domainRevision
127
+ *
128
+ * @example
129
+ * ```typescript
130
+ * await env.publishTools([
131
+ * {
132
+ * name: 'get_bio',
133
+ * description: 'Get biography of an author',
134
+ * className: 'author',
135
+ * inputSchema: { type: 'object', properties: { detailed: { type: 'boolean' } } },
136
+ * outputSchema: { type: 'object', properties: { bio: { type: 'string' } }, required: ['bio'] },
137
+ * handler: async (id, params) => ({ bio: `Bio of ${id}` }),
138
+ * },
139
+ * ]);
140
+ * ```
141
+ */
142
+ publishTools(tools: ToolWithHandler[], revision?: string): Promise<PublishToolsResult>;
143
+ /**
144
+ * Submit a job to execute code in the sandbox.
145
+ *
146
+ * The code can import typed classes from `./sandbox-tools`:
147
+ * ```typescript
148
+ * import { Author, Book, global_search } from './sandbox-tools';
149
+ *
150
+ * const tolkien = await Author.find({ id: 'tolkien' });
151
+ * const bio = await tolkien.get_bio({ detailed: true });
152
+ * const books = await tolkien.get_books();
153
+ * ```
154
+ *
155
+ * Tool calls (instance methods, static methods, global functions) trigger
156
+ * `tool.invoke` RPC back to this client, where the registered handlers
157
+ * execute locally and return the result to the sandbox.
158
+ */
159
+ submitJob(code: string, domainRevision?: string): Promise<Job>;
160
+ /**
161
+ * Register a handler for a specific tool.
162
+ * @param isInstance - If true, handler will receive (id, params) for instance method dispatch.
163
+ */
164
+ registerToolHandler(name: string, handler: ToolHandler | InstanceToolHandler, isInstance?: boolean): void;
165
+ /**
166
+ * Respond to a prompt request from the sandbox
167
+ */
168
+ answerPrompt(promptId: string, answer: unknown): Promise<void>;
169
+ /**
170
+ * Get the current domain state and available tools
171
+ */
172
+ getDomain(): Promise<DomainState>;
173
+ /**
174
+ * Get auto-generated TypeScript class declarations for the current domain.
175
+ *
176
+ * Returns typed declarations including:
177
+ * - Classes with readonly properties (from manifest)
178
+ * - `static find(query: { id: string })` for each class
179
+ * - Instance methods with typed input/output (from `publishTools` with `className`)
180
+ * - Static methods (from `publishTools` with `className` + `static: true`)
181
+ * - Relationship accessors (`get_books()`, `get_author()`, etc.)
182
+ * - Global tool functions (from `publishTools` without `className`)
183
+ *
184
+ * Pass this documentation to LLMs so they can write correct typed code
185
+ * that imports from `./sandbox-tools`.
186
+ *
187
+ * Falls back to generating markdown docs from the domain summary if
188
+ * the synthesis server is unavailable.
189
+ */
190
+ getDomainDocumentation(): Promise<string>;
191
+ /**
192
+ * Generate markdown documentation from the domain summary.
193
+ * Class-aware: groups tools by class with property/relationship info.
194
+ */
195
+ private generateFallbackDocs;
196
+ /**
197
+ * Close the session and disconnect from the sandbox
198
+ */
199
+ disconnect(): Promise<void>;
200
+ /**
201
+ * Subscribe to session events
202
+ */
203
+ on(event: string, handler: (data: unknown) => void): void;
204
+ /**
205
+ * Unsubscribe from session events
206
+ */
207
+ off(event: string, handler: (data: unknown) => void): void;
208
+ private setupToolInvokeHandler;
209
+ private setupEventHandlers;
210
+ private emit;
211
+ }
212
+
213
+ /**
214
+ * Environment represents a connected session to a sandbox for a specific user.
215
+ *
216
+ * After connecting, you can:
217
+ * 1. Define your domain ontology via `applyManifest()` (classes, properties, relationships)
218
+ * 2. Record object instances via `recordObject()` (with fields and relationship attachments)
219
+ * 3. Publish tools via `publishTools()` (instance methods, static methods, global tools — with typed I/O)
220
+ * 4. Submit jobs via `submitJob()` that import auto-generated typed classes from `./sandbox-tools`
221
+ * 5. Execute GraphQL queries via `graphql()` (authenticated automatically)
222
+ *
223
+ * Tool calls from the sandbox automatically invoke your handlers via reverse-RPC.
224
+ *
225
+ * Object IDs are unique per class. Internally, the graph path is `{className}_{id}`
226
+ * (e.g., `author_tolkien`). Use `Environment.toGraphPath()` and
227
+ * `Environment.extractIdFromGraphPath()` for conversions.
228
+ */
229
+ declare class Environment extends Session {
230
+ private envData;
231
+ private _apiKey;
232
+ private _apiEndpoint;
233
+ constructor(client: WSClient, envData: EnvironmentData, clientId: string, apiKey: string, apiEndpoint: string);
234
+ /** The environment ID */
235
+ get environmentId(): string;
236
+ /** The sandbox ID */
237
+ get sandboxId(): string;
238
+ /** The subject ID */
239
+ get subjectId(): string;
240
+ /** The permission profile ID */
241
+ get permissionProfileId(): string;
242
+ /** The GraphQL API endpoint URL */
243
+ get apiEndpoint(): string;
244
+ /**
245
+ * Convert a class name + real-world ID into a unique graph path.
246
+ *
247
+ * Two objects of *different* classes may share the same real-world ID,
248
+ * so the graph path must incorporate the class to guarantee uniqueness.
249
+ *
250
+ * Format: `{className}_{id}` — deterministic, human-readable.
251
+ *
252
+ * **Convention**: class names should be simple identifiers without
253
+ * underscores (e.g. `author`, `book`). This ensures the prefix is
254
+ * unambiguously parseable by `extractIdFromGraphPath`.
255
+ */
256
+ static toGraphPath(className: string, id: string): string;
257
+ /**
258
+ * Extract the real-world ID from a graph path, given the class name.
259
+ *
260
+ * Strips the `{className}_` prefix. Returns the raw path if the
261
+ * expected prefix is not found.
262
+ */
263
+ static extractIdFromGraphPath(graphPath: string, className: string): string;
264
+ /**
265
+ * Execute a GraphQL query against the environment's graph.
266
+ *
267
+ * The query uses the Granular graph query language (based on Cypher/GraphQL).
268
+ * Authentication is handled automatically using the SDK's API key.
269
+ *
270
+ * @param query - The GraphQL query string
271
+ * @param variables - Optional variables for the query
272
+ * @returns The query result data
273
+ *
274
+ * @example
275
+ * ```typescript
276
+ * // Read the workspace
277
+ * const result = await env.graphql(
278
+ * `query { model(path: "workspace") { path label submodels { path label } } }`
279
+ * );
280
+ * console.log(result.data);
281
+ *
282
+ * // Create a model
283
+ * const created = await env.graphql(
284
+ * `mutation { at(path: "workspace") { create_submodel(subpath: "my_node", label: "My Node", prototype: "Model") { model { path label } } } }`
285
+ * );
286
+ * ```
287
+ */
288
+ graphql<T = any>(query: string, variables?: Record<string, any>): Promise<GraphQLResult<T>>;
289
+ /**
290
+ * Define a relationship between two model types.
291
+ *
292
+ * Creates both submodels (if they don't exist) and links them with
293
+ * a RelationshipDef node that encodes cardinality.
294
+ *
295
+ * @example
296
+ * ```typescript
297
+ * // Author has many Books, Book has one Author
298
+ * const rel = await env.defineRelationship({
299
+ * model: 'author',
300
+ * localSubmodel: 'books',
301
+ * localIsMany: true,
302
+ * foreignModel: 'book',
303
+ * foreignSubmodel: 'author',
304
+ * foreignIsMany: false,
305
+ * });
306
+ * console.log(rel.relationship_kind); // "one_to_many"
307
+ * ```
308
+ */
309
+ defineRelationship(options: DefineRelationshipOptions): Promise<RelationshipInfo>;
310
+ /**
311
+ * Get all relationships for a model type.
312
+ *
313
+ * @param modelPath - The model type path (e.g., "author")
314
+ * @returns Array of relationships from this model's perspective
315
+ *
316
+ * @example
317
+ * ```typescript
318
+ * const rels = await env.getRelationships('author');
319
+ * for (const rel of rels) {
320
+ * console.log(`${rel.local_submodel.path} -> ${rel.foreign_model.path} (${rel.relationship_kind})`);
321
+ * }
322
+ * ```
323
+ */
324
+ getRelationships(modelPath: string): Promise<RelationshipInfo[]>;
325
+ /**
326
+ * Attach a target model to a relationship submodel.
327
+ *
328
+ * Handles cardinality automatically:
329
+ * - "One" side: sets/replaces the reference
330
+ * - "Many" side: adds the target to the collection
331
+ *
332
+ * If the target model doesn't exist, it's created as an instance of the foreign type.
333
+ * Bidirectional sync is automatic.
334
+ *
335
+ * @param modelPath - The model instance path (e.g., "tolkien")
336
+ * @param submodelPath - The relationship submodel (e.g., "books")
337
+ * @param targetPath - The target model to attach (e.g., "lord_of_the_rings")
338
+ *
339
+ * @example
340
+ * ```typescript
341
+ * // Attach a book to an author (many side)
342
+ * await env.attach('tolkien', 'books', 'lord_of_the_rings');
343
+ * // This also automatically sets lord_of_the_rings:author -> tolkien
344
+ * ```
345
+ */
346
+ attach(modelPath: string, submodelPath: string, targetPath: string): Promise<void>;
347
+ /**
348
+ * Detach a target model from a relationship submodel.
349
+ *
350
+ * Handles bidirectional cleanup automatically.
351
+ *
352
+ * @param modelPath - The model instance path
353
+ * @param submodelPath - The relationship submodel
354
+ * @param targetPath - The target to detach (optional for "one" side; omit on "many" side to detach all)
355
+ *
356
+ * @example
357
+ * ```typescript
358
+ * // Detach a specific book
359
+ * await env.detach('tolkien', 'books', 'lord_of_the_rings');
360
+ *
361
+ * // Detach all books
362
+ * await env.detach('tolkien', 'books');
363
+ * ```
364
+ */
365
+ detach(modelPath: string, submodelPath: string, targetPath?: string): Promise<void>;
366
+ /**
367
+ * List all related models through a relationship submodel.
368
+ *
369
+ * @param modelPath - The model instance path
370
+ * @param submodelPath - The relationship submodel
371
+ * @returns Array of related model references
372
+ *
373
+ * @example
374
+ * ```typescript
375
+ * const books = await env.listRelated('tolkien', 'books');
376
+ * console.log(books); // [{ path: "lord_of_the_rings", label: "Lord of the Rings" }, ...]
377
+ * ```
378
+ */
379
+ listRelated(modelPath: string, submodelPath: string): Promise<ModelRef[]>;
380
+ /**
381
+ * Apply a manifest to the current environment's graph.
382
+ *
383
+ * Translates each manifest operation into GraphQL mutations and executes them
384
+ * in order. This is the core mechanism for creating classes, fields, and
385
+ * relationships from a declarative manifest.
386
+ *
387
+ * @param manifest - The manifest content to apply
388
+ * @returns Summary of applied operations
389
+ *
390
+ * @example
391
+ * ```typescript
392
+ * await environment.applyManifest({
393
+ * schemaVersion: 2,
394
+ * name: 'my-app',
395
+ * volumes: [{
396
+ * name: 'schema',
397
+ * scope: 'sandbox',
398
+ * operations: [
399
+ * { create: 'author', extends: 'class', has: { name: { type: 'string' } } },
400
+ * { create: 'book', extends: 'class', has: { title: { type: 'string' } } },
401
+ * { defineRelationship: {
402
+ * left: 'author', right: 'book',
403
+ * leftSubmodel: 'books', rightSubmodel: 'author',
404
+ * leftIsMany: true, rightIsMany: false,
405
+ * }},
406
+ * ],
407
+ * }],
408
+ * });
409
+ * ```
410
+ */
411
+ applyManifest(manifest: ManifestContent): Promise<{
412
+ applied: number;
413
+ errors: string[];
414
+ }>;
415
+ /**
416
+ * Resolve an alias reference like "@std/class" → "class"
417
+ * Strips the alias prefix, returning the bare model path.
418
+ */
419
+ private _resolveAlias;
420
+ /**
421
+ * Apply a single manifest operation via GraphQL
422
+ */
423
+ private _applyOperation;
424
+ /**
425
+ * Apply field definitions (has) to a model via GraphQL
426
+ */
427
+ private _applyFields;
428
+ /**
429
+ * Create or update an instance of a class in the graph.
430
+ *
431
+ * Uses `instantiate` under the hood, which has find-or-create semantics:
432
+ * if an instance with the given `id` already exists for the class it is
433
+ * returned; otherwise a new instance is created. Fields are then set
434
+ * (overwriting previous values) and relationships are attached.
435
+ *
436
+ * The graph path is derived as `{className}_{id}` to ensure uniqueness
437
+ * across classes (two objects of different classes may share the same
438
+ * real-world ID). Relationship targets are also resolved automatically
439
+ * using the foreign class from the relationship definition.
440
+ *
441
+ * @param options - The object specification
442
+ * @returns The graph path, real-world ID, and creation status
443
+ *
444
+ * @example
445
+ * ```typescript
446
+ * // Create an author with fields
447
+ * const result = await env.recordObject({
448
+ * className: 'author',
449
+ * id: 'tolkien',
450
+ * label: 'J.R.R. Tolkien',
451
+ * fields: { name: 'J.R.R. Tolkien', birth_year: 1892 },
452
+ * relationships: { books: ['lotr', 'silmarillion'] },
453
+ * });
454
+ * // result.path → 'author_tolkien' (internal graph path)
455
+ * // result.id → 'tolkien' (real-world ID)
456
+ * // result.created → true
457
+ * ```
458
+ */
459
+ recordObject(options: RecordObjectOptions): Promise<RecordObjectResult>;
460
+ /**
461
+ * Convenience method: publish tools and get back wrapped result.
462
+ * This is the main entry point for setting up tools.
463
+ *
464
+ * @example
465
+ * ```typescript
466
+ * const tools = [
467
+ * {
468
+ * name: 'get_weather',
469
+ * description: 'Get weather for a city',
470
+ * inputSchema: { type: 'object', properties: { city: { type: 'string' } } },
471
+ * handler: async ({ city }) => ({ temp: 22 }),
472
+ * },
473
+ * ];
474
+ *
475
+ * const { domainRevision } = await environment.publishTools(tools);
476
+ *
477
+ * // Now submit jobs that use those tools
478
+ * const job = await environment.submitJob(`
479
+ * import { Author } from './sandbox-tools';
480
+ * const weather = await Author.get_weather({ city: 'Paris' });
481
+ * return weather;
482
+ * `);
483
+ *
484
+ * const result = await job.result;
485
+ * ```
486
+ */
487
+ publishTools(tools: ToolWithHandler[], revision?: string): Promise<PublishToolsResult>;
488
+ }
489
+ declare class Granular {
490
+ private apiKey;
491
+ private apiUrl;
492
+ private httpUrl;
493
+ /**
494
+ * Create a new Granular client
495
+ * @param options - Client configuration
496
+ */
497
+ constructor(options: GranularOptions);
498
+ /**
499
+ * Records/upserts a user and prepares them for sandbox connections
500
+ *
501
+ * @param options - User options
502
+ * @returns The user object to pass to connect()
503
+ *
504
+ * @example
505
+ * ```typescript
506
+ * const user = await granular.recordUser({
507
+ * userId: 'user_123',
508
+ * name: 'John Doe',
509
+ * permissions: ['agent'],
510
+ * });
511
+ * ```
512
+ */
513
+ recordUser(options: RecordUserOptions): Promise<User>;
514
+ /**
515
+ * Connect to a sandbox and establish a real-time environment session.
516
+ *
517
+ * After connecting, use `environment.publishTools()` to register tools,
518
+ * then `environment.submitJob()` to execute code that uses those tools.
519
+ *
520
+ * @param options - Connection options
521
+ * @returns An active environment session
522
+ *
523
+ * @example
524
+ * ```typescript
525
+ * const user = await granular.recordUser({
526
+ * userId: 'user_123',
527
+ * permissions: ['agent'],
528
+ * });
529
+ *
530
+ * const environment = await granular.connect({
531
+ * sandbox: 'my-sandbox',
532
+ * user,
533
+ * });
534
+ *
535
+ * // Publish tools
536
+ * await environment.publishTools([
537
+ * { name: 'greet', description: 'Say hello', inputSchema: {}, handler: async () => 'Hello!' },
538
+ * ]);
539
+ *
540
+ * // Submit job
541
+ * const job = await environment.submitJob(`
542
+ * import { tools } from './sandbox-tools';
543
+ * return await tools.greet({});
544
+ * `);
545
+ *
546
+ * console.log(await job.result); // 'Hello!'
547
+ * ```
548
+ */
549
+ connect(options: ConnectOptions): Promise<Environment>;
550
+ /**
551
+ * Find a sandbox by name or create it if it doesn't exist
552
+ */
553
+ private findOrCreateSandbox;
554
+ /**
555
+ * Ensure a permission profile exists for a sandbox, creating it if needed.
556
+ * If profileName matches an existing profile name, returns its ID.
557
+ * Otherwise, creates a new profile with default allow-all rules.
558
+ */
559
+ private ensurePermissionProfile;
560
+ /**
561
+ * Ensure an assignment exists for a subject in a sandbox with a permission profile
562
+ */
563
+ private ensureAssignment;
564
+ /**
565
+ * Sandbox management API
566
+ */
567
+ get sandboxes(): {
568
+ list: () => Promise<SandboxListResponse>;
569
+ get: (id: string) => Promise<Sandbox>;
570
+ create: (data: CreateSandboxData) => Promise<Sandbox>;
571
+ update: (id: string, data: Partial<CreateSandboxData>) => Promise<Sandbox>;
572
+ delete: (id: string) => Promise<DeleteResponse>;
573
+ };
574
+ /**
575
+ * Permission Profile management for sandboxes
576
+ */
577
+ get permissionProfiles(): {
578
+ list: (sandboxId: string) => Promise<PermissionProfile[]>;
579
+ get: (sandboxId: string, profileId: string) => Promise<PermissionProfile>;
580
+ create: (sandboxId: string, data: CreatePermissionProfileData) => Promise<PermissionProfile>;
581
+ delete: (sandboxId: string, profileId: string) => Promise<DeleteResponse>;
582
+ };
583
+ /**
584
+ * Environment management
585
+ */
586
+ get environments(): {
587
+ list: (sandboxId: string) => Promise<EnvironmentData[]>;
588
+ get: (environmentId: string) => Promise<EnvironmentData>;
589
+ create: (sandboxId: string, data: CreateEnvironmentData) => Promise<EnvironmentData>;
590
+ delete: (environmentId: string) => Promise<DeleteResponse>;
591
+ };
592
+ /**
593
+ * Subject management
594
+ */
595
+ get subjects(): {
596
+ get: (subjectId: string) => Promise<Subject>;
597
+ listAssignments: (subjectId: string) => Promise<AssignmentListResponse>;
598
+ };
599
+ /**
600
+ * @deprecated Use recordUser() instead
601
+ */
602
+ get users(): {
603
+ create: (data: {
604
+ id: string;
605
+ name?: string;
606
+ email?: string;
607
+ }) => Promise<Subject>;
608
+ get: (id: string) => Promise<Subject>;
609
+ };
610
+ /**
611
+ * Make an authenticated API request
612
+ */
613
+ private request;
614
+ }
615
+
616
+ export { AssignmentListResponse, ConnectOptions, CreateEnvironmentData, CreatePermissionProfileData, CreateSandboxData, DefineRelationshipOptions, DeleteResponse, DomainState, Environment, EnvironmentData, Granular, GranularOptions, GraphQLResult, InstanceToolHandler, Job, ManifestContent, ModelRef, PermissionProfile, PublishToolsResult, RecordObjectOptions, RecordObjectResult, RecordUserOptions, RelationshipInfo, Sandbox, SandboxListResponse, Session, Subject, ToolHandler, ToolWithHandler, User, WSClient, WSClientOptions };