@granular-software/sdk 0.4.31 → 0.4.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -17779,7 +17779,11 @@ var WSClient = class {
17779
17779
  return null;
17780
17780
  }
17781
17781
  try {
17782
- const payloadRaw = this.decodeBase64Url(parts[1]);
17782
+ const payloadSegment = parts[1];
17783
+ if (!payloadSegment) {
17784
+ return null;
17785
+ }
17786
+ const payloadRaw = this.decodeBase64Url(payloadSegment);
17783
17787
  const payload = JSON.parse(payloadRaw);
17784
17788
  if (typeof payload.exp !== "number" || !Number.isFinite(payload.exp)) {
17785
17789
  return null;
@@ -18856,6 +18860,7 @@ import { ${allImports} } from "./sandbox-tools";
18856
18860
  this.eventListeners.set(event, []);
18857
18861
  }
18858
18862
  this.eventListeners.get(event).push(handler);
18863
+ return () => this.off(event, handler);
18859
18864
  }
18860
18865
  /**
18861
18866
  * Unsubscribe from session events
@@ -19312,6 +19317,16 @@ var JobImplementation = class {
19312
19317
  handler(message);
19313
19318
  }
19314
19319
  }
19320
+ return () => {
19321
+ const handlers = this.eventListeners.get(event);
19322
+ if (!handlers) {
19323
+ return;
19324
+ }
19325
+ this.eventListeners.set(
19326
+ event,
19327
+ handlers.filter((current) => current !== handler)
19328
+ );
19329
+ };
19315
19330
  }
19316
19331
  replayAgentMessage(message) {
19317
19332
  this.captureAgentMessage(message);
@@ -20015,7 +20030,9 @@ var Environment = class {
20015
20030
  }
20016
20031
  );
20017
20032
  if (result.errors?.length) {
20018
- throw new Error(`defineRelationship failed: ${result.errors[0].message}`);
20033
+ throw new Error(
20034
+ `defineRelationship failed: ${result.errors[0]?.message ?? "Unknown GraphQL error"}`
20035
+ );
20019
20036
  }
20020
20037
  return result.data.at.define_relationship;
20021
20038
  }
@@ -20051,7 +20068,9 @@ var Environment = class {
20051
20068
  { path: modelPath }
20052
20069
  );
20053
20070
  if (result.errors?.length) {
20054
- throw new Error(`getRelationships failed: ${result.errors[0].message}`);
20071
+ throw new Error(
20072
+ `getRelationships failed: ${result.errors[0]?.message ?? "Unknown GraphQL error"}`
20073
+ );
20055
20074
  }
20056
20075
  return result.data?.model?.relationships || [];
20057
20076
  }
@@ -20090,7 +20109,7 @@ var Environment = class {
20090
20109
  { target: targetPath }
20091
20110
  );
20092
20111
  if (result.errors?.length) {
20093
- throw new Error(`attach failed: ${result.errors[0].message}`);
20112
+ throw new Error(`attach failed: ${result.errors[0]?.message ?? "Unknown GraphQL error"}`);
20094
20113
  }
20095
20114
  }
20096
20115
  /**
@@ -20125,7 +20144,7 @@ var Environment = class {
20125
20144
  }`
20126
20145
  );
20127
20146
  if (result.errors?.length) {
20128
- throw new Error(`detach failed: ${result.errors[0].message}`);
20147
+ throw new Error(`detach failed: ${result.errors[0]?.message ?? "Unknown GraphQL error"}`);
20129
20148
  }
20130
20149
  }
20131
20150
  /**
@@ -20152,7 +20171,9 @@ var Environment = class {
20152
20171
  }`
20153
20172
  );
20154
20173
  if (result.errors?.length) {
20155
- throw new Error(`listRelated failed: ${result.errors[0].message}`);
20174
+ throw new Error(
20175
+ `listRelated failed: ${result.errors[0]?.message ?? "Unknown GraphQL error"}`
20176
+ );
20156
20177
  }
20157
20178
  return result.data?.at?.at?.list_related || [];
20158
20179
  }
@@ -20245,7 +20266,7 @@ var Environment = class {
20245
20266
  async _runGraphql(query, label) {
20246
20267
  const result = await this.graphql(query);
20247
20268
  if (result.errors?.length) {
20248
- throw new Error(`${label}: ${result.errors[0].message}`);
20269
+ throw new Error(`${label}: ${result.errors[0]?.message ?? "Unknown GraphQL error"}`);
20249
20270
  }
20250
20271
  return result.data;
20251
20272
  }
@@ -20590,7 +20611,11 @@ var Environment = class {
20590
20611
  */
20591
20612
  async recordObject(options) {
20592
20613
  const results = await this.recordObjects([options]);
20593
- return results[0];
20614
+ const result = results[0];
20615
+ if (!result) {
20616
+ throw new Error("recordObject: no result returned for record");
20617
+ }
20618
+ return result;
20594
20619
  }
20595
20620
  /**
20596
20621
  * Batch version of `recordObject()`.
@@ -20642,7 +20667,13 @@ var Environment = class {
20642
20667
  );
20643
20668
  }
20644
20669
  for (let index = 0; index < items.length; index += 1) {
20645
- results[plan.offset + index] = items[index];
20670
+ const item = items[index];
20671
+ if (!item) {
20672
+ throw new Error(
20673
+ `recordObjects: chunk ${plan.chunkIndex + 1} returned an empty result at index ${index}`
20674
+ );
20675
+ }
20676
+ results[plan.offset + index] = item;
20646
20677
  }
20647
20678
  if (onChunk) {
20648
20679
  const info2 = {
@@ -22046,7 +22077,7 @@ async function resolveEnvironmentData(granular, options) {
22046
22077
  const ontologyId = await resolveOntologyId(granular, options.ontology);
22047
22078
  const environmentName = options.environment ?? "dev";
22048
22079
  const environments = await granular.environments.list(ontologyId);
22049
- const existing = environments.find((environment2) => matchesEnvironmentName(environment2, environmentName));
22080
+ const existing = environments.find((environment) => matchesEnvironmentName(environment, environmentName));
22050
22081
  if (existing) {
22051
22082
  return existing;
22052
22083
  }
@@ -22055,13 +22086,13 @@ async function resolveEnvironmentData(granular, options) {
22055
22086
  `No environment named \`${environmentName}\` found for ontology \`${ontologyId}\`. Run \`granular connect test\` or \`granular session create\` first, or pass \`--environment-id\`.`
22056
22087
  );
22057
22088
  }
22058
- const environment = await granular.openEnvironment({
22089
+ const connection = await granular.connect({
22059
22090
  ontology: ontologyId,
22060
- tag: environmentName,
22091
+ environment: environmentName,
22061
22092
  userId: options.userId ?? "granular-cli",
22062
22093
  permissions: options.permissions ?? ["default"]
22063
22094
  });
22064
- return await granular.environments.get(environment.environmentId);
22095
+ return await granular.environments.get(connection.environmentId);
22065
22096
  }
22066
22097
  async function listSessionsForEnvironment(granular, environmentId, status) {
22067
22098
  if (status === "all") {
@@ -22078,12 +22109,12 @@ async function listSessionsForEnvironment(granular, environmentId, status) {
22078
22109
  async function connectRuntime(options) {
22079
22110
  if (options.sessionId) {
22080
22111
  const { granular: granular2 } = createGranularClient();
22081
- const session3 = await granular2["connectSession"]({ sessionId: options.sessionId });
22112
+ const environment2 = await granular2.connectSession({ sessionId: options.sessionId });
22082
22113
  return {
22083
22114
  granular: granular2,
22084
- environment: session3.environment,
22085
- session: session3,
22086
- ontologyId: session3.ontologyId || session3.sandboxId
22115
+ environment: environment2,
22116
+ session: environment2,
22117
+ ontologyId: environment2.ontologyId || environment2.sandboxId
22087
22118
  };
22088
22119
  }
22089
22120
  const { granular, config } = createGranularClient();
@@ -22091,17 +22122,17 @@ async function connectRuntime(options) {
22091
22122
  if (!ontologyId) {
22092
22123
  throw new Error("No ontology configured. Run `granular init` first or pass `--ontology`.");
22093
22124
  }
22094
- const environment = await granular.openEnvironment({
22125
+ const environmentHandle = await granular.connect({
22095
22126
  ontology: ontologyId,
22096
- tag: options.environment ?? "dev",
22127
+ environment: options.environment ?? "dev",
22097
22128
  userId: options.userId ?? "granular-cli",
22098
22129
  permissions: options.permissions ?? ["default"]
22099
22130
  });
22100
- const session2 = await environment.sessions.create();
22131
+ const environment = await environmentHandle.createSession();
22101
22132
  return {
22102
22133
  granular,
22103
22134
  environment,
22104
- session: session2,
22135
+ session: environment,
22105
22136
  ontologyId
22106
22137
  };
22107
22138
  }
@@ -22111,9 +22142,9 @@ async function withRuntimeConnection(options, callback) {
22111
22142
  return await callback(connection);
22112
22143
  } finally {
22113
22144
  try {
22114
- await connection.session.disconnect();
22145
+ await connection.environment.disconnect();
22115
22146
  } catch {
22116
- connection.session.disconnectTransport();
22147
+ connection.environment?.client?.disconnect?.();
22117
22148
  }
22118
22149
  }
22119
22150
  }
@@ -22150,14 +22181,14 @@ async function connectTestCommand(options) {
22150
22181
  userId: options.user,
22151
22182
  permissions: normalizePermissions(options.permissions)
22152
22183
  },
22153
- async ({ environment, session: session2, ontologyId }) => {
22184
+ async ({ environment, ontologyId }) => {
22154
22185
  const payload = {
22155
22186
  ok: true,
22156
22187
  ontologyId,
22157
22188
  sandboxId: environment.sandboxId,
22158
22189
  environmentId: environment.environmentId,
22159
- environment: environment.environment,
22160
- sessionId: session2.sessionId,
22190
+ environment: environment.envName,
22191
+ sessionId: environment.sessionId,
22161
22192
  subjectId: environment.subjectId,
22162
22193
  versionId: environment.versionId
22163
22194
  };
@@ -22203,12 +22234,12 @@ async function sessionHeapCommand(options) {
22203
22234
  permissions: normalizePermissions(options.permissions),
22204
22235
  sessionId: options.session
22205
22236
  },
22206
- async ({ environment, session: session2, ontologyId }) => {
22237
+ async ({ environment, ontologyId }) => {
22207
22238
  const payload = {
22208
22239
  ontologyId,
22209
- sessionId: session2.sessionId,
22240
+ sessionId: environment.sessionId,
22210
22241
  environmentId: environment.environmentId,
22211
- heap: session2.getHeap()
22242
+ heap: environment.getHeap()
22212
22243
  };
22213
22244
  if (!emitJson) {
22214
22245
  step("Session heap");
@@ -22231,12 +22262,12 @@ async function sessionDocCommand(options) {
22231
22262
  permissions: normalizePermissions(options.permissions),
22232
22263
  sessionId: options.session
22233
22264
  },
22234
- async ({ environment, session: session2, ontologyId }) => {
22265
+ async ({ environment, ontologyId }) => {
22235
22266
  const payload = {
22236
22267
  ontologyId,
22237
- sessionId: session2.sessionId,
22268
+ sessionId: environment.sessionId,
22238
22269
  environmentId: environment.environmentId,
22239
- document: documentToJson(session2.document)
22270
+ document: documentToJson(environment.document)
22240
22271
  };
22241
22272
  if (!emitJson) {
22242
22273
  step("Session document");
@@ -22261,18 +22292,18 @@ async function sessionCreateCommand(options) {
22261
22292
  permissions,
22262
22293
  createIfMissing: true
22263
22294
  });
22264
- const session2 = await granular.createSession({
22295
+ const environment = await granular.createSession({
22265
22296
  environmentId: envData.environmentId
22266
22297
  });
22267
22298
  try {
22268
22299
  const payload = {
22269
22300
  ok: true,
22270
22301
  ontologyId: envData.sandboxId,
22271
- environmentId: session2.environmentId,
22272
- environment: session2.environment.environment,
22273
- sessionId: session2.sessionId,
22274
- subjectId: session2.subjectId,
22275
- versionId: session2.versionId
22302
+ environmentId: environment.environmentId,
22303
+ environment: environment.envName,
22304
+ sessionId: environment.sessionId,
22305
+ subjectId: environment.subjectId,
22306
+ versionId: environment.versionId
22276
22307
  };
22277
22308
  if (emitJson) {
22278
22309
  console.log(JSON.stringify(payload, null, 2));
@@ -22291,9 +22322,9 @@ async function sessionCreateCommand(options) {
22291
22322
  console.log();
22292
22323
  } finally {
22293
22324
  try {
22294
- await session2.disconnect();
22325
+ await environment.disconnect();
22295
22326
  } catch {
22296
- session2.disconnectTransport();
22327
+ environment?.client?.disconnect?.();
22297
22328
  }
22298
22329
  }
22299
22330
  }
@@ -22418,12 +22449,12 @@ async function effectsListCommand(options) {
22418
22449
  permissions: normalizePermissions(options.permissions),
22419
22450
  sessionId: options.session
22420
22451
  },
22421
- async ({ environment, session: session2, ontologyId }) => {
22422
- const effects2 = sortEffects(session2.getEffects());
22452
+ async ({ environment, ontologyId }) => {
22453
+ const effects2 = sortEffects(environment.getEffects());
22423
22454
  const payload = {
22424
22455
  ontologyId,
22425
22456
  environmentId: environment.environmentId,
22426
- sessionId: session2.sessionId,
22457
+ sessionId: environment.sessionId,
22427
22458
  items: effects2
22428
22459
  };
22429
22460
  if (emitJson) {
@@ -22463,8 +22494,8 @@ async function effectsDiffCommand(options) {
22463
22494
  permissions: normalizePermissions(options.permissions),
22464
22495
  sessionId: options.session
22465
22496
  },
22466
- async ({ environment, session: session2, ontologyId }) => {
22467
- const effects2 = sortEffects(session2.getEffects());
22497
+ async ({ environment, ontologyId }) => {
22498
+ const effects2 = sortEffects(environment.getEffects());
22468
22499
  const declared = effects2.map((effect) => effect.name);
22469
22500
  const liveReady = effects2.filter((effect) => effect.ready).map((effect) => effect.name);
22470
22501
  const declaredOnly = effects2.filter((effect) => !effect.ready).map((effect) => effect.name);
@@ -22472,7 +22503,7 @@ async function effectsDiffCommand(options) {
22472
22503
  const payload = {
22473
22504
  ontologyId,
22474
22505
  environmentId: environment.environmentId,
22475
- sessionId: session2.sessionId,
22506
+ sessionId: environment.sessionId,
22476
22507
  summary: {
22477
22508
  declaredCount: declared.length,
22478
22509
  liveReadyCount: liveReady.length,
@@ -9,7 +9,7 @@ import { Doc } from '@automerge/automerge/slim';
9
9
  * Configuration for the Granular client
10
10
  */
11
11
  type AccessTokenProvider = () => Promise<string | null | undefined> | string | null | undefined;
12
- type EndpointMode = "auto" | "local" | "production";
12
+ type EndpointMode = 'auto' | 'local' | 'production';
13
13
  interface GranularOptions {
14
14
  /** Your Granular API key (for service/CLI auth; use with GRANULAR_API_KEY) */
15
15
  apiKey?: string;
@@ -86,15 +86,16 @@ interface Subject {
86
86
  updatedAt: number;
87
87
  }
88
88
  /**
89
- * Options for opening or resolving an ontology environment for one user.
89
+ * Options for opening an ontology environment for one delegated subject.
90
90
  *
91
- * This does **not** open a session. Use `environment.sessions.create()` after
92
- * opening the environment when you need a live runtime connection.
91
+ * This does not open a live runtime session. Use
92
+ * `environment.sessions.create()` or `granular.createSession({ environmentId })`
93
+ * when you need a conversation/session with jobs, prompts, heap, and effects.
93
94
  */
94
95
  interface OpenEnvironmentOptions {
95
- /** The ontology name or ID to open */
96
+ /** The ontology name or ID to open. */
96
97
  ontology: string;
97
- /** Version channel to follow, typically `dev` or `prod` */
98
+ /** Version channel to follow, typically `dev` or `prod`. */
98
99
  tag?: string;
99
100
  /**
100
101
  * External user identifier from your app.
@@ -108,9 +109,9 @@ interface OpenEnvironmentOptions {
108
109
  * Exactly one of `userId`, `granularId`, or `user` should be provided.
109
110
  */
110
111
  granularId?: string;
111
- /** Optional display name used when upserting the user */
112
+ /** Optional display name used when upserting the user. */
112
113
  name?: string;
113
- /** Optional email used when upserting the user */
114
+ /** Optional email used when upserting the user. */
114
115
  email?: string;
115
116
  /**
116
117
  * Permission profile names or IDs to ensure before opening the environment.
@@ -124,14 +125,14 @@ interface OpenEnvironmentOptions {
124
125
  * the newest tag target instead of reusing the outdated one.
125
126
  */
126
127
  createFreshIfOutdated?: boolean;
127
- /** Backwards-compatible user object returned from recordUser() */
128
+ /** Backwards-compatible user object returned from `recordUser()`. */
128
129
  user?: User;
129
130
  }
130
131
  /**
131
132
  * Deprecated compatibility alias for the legacy `connect()` entry point.
132
133
  *
133
- * `connect()` now resolves an environment handle and no longer opens a
134
- * runtime session automatically. Prefer `openEnvironment()` for new code.
134
+ * `connect()` now resolves an environment handle and no longer opens a runtime
135
+ * session automatically. Prefer `openEnvironment()` for new code.
135
136
  */
136
137
  interface ConnectOptions extends OpenEnvironmentOptions {
137
138
  /** @deprecated Legacy explicit environment slot name. Prefer `tag`. */
@@ -167,7 +168,7 @@ interface ConversationSessionInfo {
167
168
  environmentId: string;
168
169
  versionId?: string | null;
169
170
  docId: string;
170
- status: "active" | "closed" | "expired";
171
+ status: 'active' | 'closed' | 'expired';
171
172
  createdAt: string;
172
173
  lastSeenAt: string;
173
174
  summary?: string | null;
@@ -275,7 +276,7 @@ interface AssignmentListResponse {
275
276
  * pin themselves to one immutable ontology version.
276
277
  */
277
278
  interface BuildPolicy {
278
- mode: "tag" | "current" | "pinned";
279
+ mode: 'tag' | 'current' | 'pinned';
279
280
  buildId?: string;
280
281
  versionId?: string;
281
282
  tagId?: string;
@@ -286,7 +287,7 @@ interface VersionTag {
286
287
  tagId: string;
287
288
  sandboxId: string;
288
289
  name: string;
289
- kind: "channel" | "release" | "system";
290
+ kind: 'channel' | 'release' | 'system';
290
291
  targetBuildId?: string | null;
291
292
  targetVersionId?: string | null;
292
293
  description?: string | null;
@@ -311,7 +312,7 @@ interface EnvironmentData {
311
312
  tag?: VersionTag | null;
312
313
  tracking?: BuildPolicy;
313
314
  buildPolicy: BuildPolicy;
314
- updateState?: "up_to_date" | "update_available" | "upgrading" | "failed";
315
+ updateState?: 'up_to_date' | 'update_available' | 'upgrading' | 'failed';
315
316
  createdAt: number;
316
317
  updatedAt: number;
317
318
  }
@@ -360,7 +361,7 @@ interface Manifest {
360
361
  interface ManifestListResponse {
361
362
  items: Manifest[];
362
363
  }
363
- type BuildStatus = "queued" | "building" | "completed" | "failed" | "canceled";
364
+ type BuildStatus = 'queued' | 'building' | 'completed' | 'failed' | 'canceled';
364
365
  /**
365
366
  * An immutable ontology version derived from a specific manifest revision.
366
367
  *
@@ -395,8 +396,8 @@ interface BuildListResponse {
395
396
  }
396
397
  interface SemanticVersionDiffEntry {
397
398
  operationId: string;
398
- kind: "create" | "update" | "relationship" | "effect" | "eventStream" | "unknown";
399
- changeType: "added" | "removed" | "changed";
399
+ kind: 'create' | 'update' | 'relationship' | 'effect' | 'eventStream' | 'unknown';
400
+ changeType: 'added' | 'removed' | 'changed';
400
401
  label: string;
401
402
  additive: boolean;
402
403
  breaking: boolean;
@@ -458,7 +459,7 @@ interface ResolvedEffectBehaviors {
458
459
  reverse?: ResolvedEffectReverse;
459
460
  approvalRequired?: ResolvedEffectApprovalRequired;
460
461
  }
461
- type EffectInvocationMode = "execute" | "dryRun" | "reverse";
462
+ type EffectInvocationMode = 'execute' | 'dryRun' | 'reverse';
462
463
  interface EffectInvocationMetadata {
463
464
  mode?: EffectInvocationMode;
464
465
  reverseHandler?: string;
@@ -515,9 +516,9 @@ interface ToolSchema {
515
516
  * ```
516
517
  */
517
518
  outputSchema?: Record<string, unknown>;
518
- stability?: "stable" | "experimental" | "deprecated";
519
+ stability?: 'stable' | 'experimental' | 'deprecated';
519
520
  provenance?: {
520
- source: "mcp" | "custom";
521
+ source: 'mcp' | 'custom';
521
522
  };
522
523
  tags?: string[];
523
524
  /**
@@ -624,8 +625,8 @@ interface EffectsChangedEvent extends ToolsChangedEvent {
624
625
  }
625
626
  type EffectHandler = ToolHandler;
626
627
  type InstanceEffectHandler = InstanceToolHandler;
627
- type JobStatus = "queued" | "running" | "awaitingTool" | "awaitingHuman" | "succeeded" | "failed" | "timeout" | "canceled";
628
- type JobFeedbackSentiment = "good" | "bad";
628
+ type JobStatus = 'queued' | 'running' | 'awaitingTool' | 'awaitingHuman' | 'succeeded' | 'failed' | 'timeout' | 'canceled';
629
+ type JobFeedbackSentiment = 'good' | 'bad';
629
630
  interface JobFeedbackToolCall {
630
631
  callId?: string;
631
632
  toolName?: string;
@@ -637,7 +638,7 @@ interface JobFeedbackToolCall {
637
638
  durationMs?: number | null;
638
639
  }
639
640
  interface JobFeedbackMetadata {
640
- source: "sdk";
641
+ source: 'sdk';
641
642
  status: JobStatus;
642
643
  code: string;
643
644
  domainRevision?: string;
@@ -671,7 +672,7 @@ interface JobFeedbackRecord {
671
672
  updatedAt: number;
672
673
  }
673
674
  /**
674
- * Persisted feedback rows listed at the environment level.
675
+ * Persisted feedback row listed at the environment level.
675
676
  */
676
677
  interface EnvironmentFeedbackRecord {
677
678
  feedbackId: string;
@@ -701,11 +702,11 @@ interface Job {
701
702
  /** Attach user feedback to this job and persist it with job/session metadata */
702
703
  leaveFeedback(input: JobFeedbackInput): Promise<JobFeedbackRecord>;
703
704
  /** Subscribe to job events */
704
- on(event: string, handler: (data: unknown) => void): void;
705
+ on(event: string, handler: (data: unknown) => void): () => void;
705
706
  }
706
707
  interface Prompt {
707
708
  id: string;
708
- type: "confirm" | "choice" | "input";
709
+ type: 'confirm' | 'choice' | 'input';
709
710
  title: string;
710
711
  message: string;
711
712
  options?: Array<string | {
@@ -724,7 +725,7 @@ interface ConversationMessageShowRefs {
724
725
  variableNames?: string[];
725
726
  }
726
727
  interface ConversationMessageInput {
727
- role: "user" | "assistant";
728
+ role: 'user' | 'assistant';
728
729
  content?: string;
729
730
  show?: ConversationMessageShowRefs;
730
731
  jobId?: string;
@@ -740,7 +741,7 @@ interface ConversationAppendResult {
740
741
  }
741
742
  interface SessionTranscriptEntry {
742
743
  id: string;
743
- role: "user" | "assistant";
744
+ role: 'user' | 'assistant';
744
745
  content: string;
745
746
  timestamp: number;
746
747
  jobId?: string;
@@ -751,9 +752,9 @@ interface SessionTranscriptEntry {
751
752
  error?: string;
752
753
  show?: ConversationMessageShowRefs;
753
754
  historyContent?: string;
754
- source: "conversation" | "job_code" | "job_result" | "job_prompt" | "job_agent_message";
755
+ source: 'conversation' | 'job_code' | 'job_result' | 'job_prompt' | 'job_agent_message';
755
756
  }
756
- type SessionHeapFieldType = "string" | "number" | "boolean" | "null" | "unknown";
757
+ type SessionHeapFieldType = 'string' | 'number' | 'boolean' | 'null' | 'unknown';
757
758
  interface SessionHeapFieldValue {
758
759
  name: string;
759
760
  type: SessionHeapFieldType;
@@ -781,7 +782,7 @@ interface SessionHeapList {
781
782
  }
782
783
  interface SessionHeapVariable {
783
784
  name: string;
784
- kind: "entry" | "list" | "scalar";
785
+ kind: 'entry' | 'list' | 'scalar';
785
786
  entryPath?: string;
786
787
  listName?: string;
787
788
  value?: string | number | boolean | null;
@@ -818,13 +819,13 @@ interface WSClientOptions {
818
819
  onReconnectError?: (info: WSReconnectErrorInfo) => void;
819
820
  }
820
821
  interface RPCRequest {
821
- type: "rpc";
822
+ type: 'rpc';
822
823
  method: string;
823
824
  params: unknown;
824
825
  id: string;
825
826
  }
826
827
  interface RPCResponse {
827
- type: "rpc_result" | "rpc_error";
828
+ type: 'rpc_result' | 'rpc_error';
828
829
  id: string;
829
830
  result?: unknown;
830
831
  error?: {
@@ -834,12 +835,12 @@ interface RPCResponse {
834
835
  };
835
836
  }
836
837
  interface SyncMessage {
837
- type: "sync";
838
+ type: 'sync';
838
839
  message?: string | number[] | Uint8Array;
839
840
  data?: number[];
840
841
  }
841
842
  interface RPCRequestFromServer {
842
- type: "rpc";
843
+ type: 'rpc';
843
844
  method: string;
844
845
  params: unknown;
845
846
  id: string;
@@ -883,7 +884,7 @@ interface RelationshipInfo {
883
884
  /** The foreign model type */
884
885
  foreign_model: ModelRef;
885
886
  /** Computed relationship kind: "one_to_one" | "one_to_many" | "many_to_one" | "many_to_many" */
886
- relationship_kind: "one_to_one" | "one_to_many" | "many_to_one" | "many_to_many";
887
+ relationship_kind: 'one_to_one' | 'one_to_many' | 'many_to_one' | 'many_to_many';
887
888
  }
888
889
  /**
889
890
  * Options for defining a relationship between two model types
@@ -982,8 +983,8 @@ interface RecordObjectsOptions {
982
983
  */
983
984
  onChunkComplete?: (info: RecordObjectsChunkInfo) => void | Promise<void>;
984
985
  }
985
- type RecordImportStatus = "queued" | "processing" | "completed" | "failed" | "canceled";
986
- type RecordImportItemStatus = "queued" | "processing" | "completed" | "failed" | "canceled";
986
+ type RecordImportStatus = 'queued' | 'processing' | 'completed' | 'failed' | 'canceled';
987
+ type RecordImportItemStatus = 'queued' | 'processing' | 'completed' | 'failed' | 'canceled';
987
988
  interface RecordImportStats {
988
989
  totalRecords: number;
989
990
  queuedRecords: number;
@@ -1048,14 +1049,10 @@ interface ManifestPropertySpec {
1048
1049
  required?: boolean;
1049
1050
  note?: string | string[];
1050
1051
  enum?: string[] | ManifestEnumRuleSpec;
1051
- searchable?: boolean | {
1052
- enabled?: boolean;
1053
- phonetic?: boolean;
1054
- };
1055
1052
  filterBy?: boolean | string[] | ManifestFilterBySpec;
1056
1053
  validate?: ManifestValidationRuleSpec[];
1057
1054
  }
1058
- type ManifestValidationOperator = "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "true" | "false" | "regex" | "contains" | "not_contains" | "starts_with" | "ends_with";
1055
+ type ManifestValidationOperator = 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'true' | 'false' | 'regex' | 'contains' | 'not_contains' | 'starts_with' | 'ends_with';
1059
1056
  interface ManifestEnumRuleSpec {
1060
1057
  values: string[];
1061
1058
  message?: string;
@@ -1144,7 +1141,7 @@ interface ManifestEffectDeclaration {
1144
1141
  isStatic?: boolean;
1145
1142
  inputSchema: ManifestEffectSchema;
1146
1143
  outputSchema?: ManifestEffectSchema;
1147
- stability?: "stable" | "experimental" | "deprecated";
1144
+ stability?: 'stable' | 'experimental' | 'deprecated';
1148
1145
  tags?: string[];
1149
1146
  metamodels?: ManifestEffectMetamodelSpec;
1150
1147
  }
@@ -1205,7 +1202,7 @@ interface ManifestImport {
1205
1202
  }
1206
1203
  interface ManifestVolume {
1207
1204
  name: string;
1208
- scope: "sandbox" | "build" | "user";
1205
+ scope: 'sandbox' | 'build' | 'user';
1209
1206
  imports?: ManifestImport[];
1210
1207
  operations: ManifestOperation[];
1211
1208
  }
@@ -1248,7 +1245,7 @@ interface StreamEvent {
1248
1245
  environmentId: string;
1249
1246
  sessionId?: string;
1250
1247
  subjectId?: string;
1251
- source: "sandbox" | "api";
1248
+ source: 'sandbox' | 'api';
1252
1249
  isAcked: boolean;
1253
1250
  createdAt: number;
1254
1251
  }
@@ -1480,7 +1477,7 @@ declare class Session {
1480
1477
  /**
1481
1478
  * Subscribe to session events
1482
1479
  */
1483
- on(event: string, handler: (data: unknown) => void): void;
1480
+ on(event: string, handler: (data: unknown) => void): () => void;
1484
1481
  /**
1485
1482
  * Unsubscribe from session events
1486
1483
  */