@gravity-rail/cli 0.47.0 → 0.50.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.
package/dist/gr.js CHANGED
@@ -208,22 +208,7 @@ var init_pagination = __esm({
208
208
  }
209
209
  });
210
210
 
211
- // ../sdk/dist/chunk-67QXTQVL.js
212
- function getCookieValue(name) {
213
- if (typeof document === "undefined") return void 0;
214
- const cookies = document.cookie.split(";");
215
- for (const cookie of cookies) {
216
- const trimmedCookie = cookie.trim();
217
- const eqIndex = trimmedCookie.indexOf("=");
218
- if (eqIndex === -1) continue;
219
- const cookieName = trimmedCookie.substring(0, eqIndex);
220
- const cookieValue = trimmedCookie.substring(eqIndex + 1);
221
- if (cookieName === name) {
222
- return cookieValue;
223
- }
224
- }
225
- return void 0;
226
- }
211
+ // ../sdk/dist/chunk-TGL72KPS.js
227
212
  function isApiValidationError(value) {
228
213
  if (!value || typeof value !== "object") return false;
229
214
  const v = value;
@@ -240,27 +225,16 @@ function parseOrgAuthChallenge(wwwAuthenticate) {
240
225
  if (!wwwAuthenticate) return null;
241
226
  if (!wwwAuthenticate.includes('realm="org"')) return null;
242
227
  const orgUuidMatch = wwwAuthenticate.match(/org_uuid="([^"]+)"/);
243
- const cookieNameMatch = wwwAuthenticate.match(/cookie_name="([^"]+)"/);
244
228
  const authUrlMatch = wwwAuthenticate.match(/auth_url="([^"]+)"/);
245
- if (!orgUuidMatch?.[1] || !cookieNameMatch?.[1] || !authUrlMatch?.[1]) {
229
+ if (!orgUuidMatch?.[1] || !authUrlMatch?.[1]) {
246
230
  console.warn("Invalid org auth challenge header: missing required fields");
247
231
  return null;
248
232
  }
249
233
  return {
250
234
  orgUuid: orgUuidMatch[1],
251
- cookieName: cookieNameMatch[1],
252
235
  authUrl: authUrlMatch[1]
253
236
  };
254
237
  }
255
- function getRequestOrgCookieName(cookieName) {
256
- if (cookieName.startsWith("orgToken")) {
257
- return cookieName.replace(/^orgToken/, "requestOrgToken");
258
- }
259
- if (cookieName.startsWith("orgSession")) {
260
- return cookieName.replace(/^orgSession/, "requestOrgSession");
261
- }
262
- return null;
263
- }
264
238
  function orgAuthHeaderName(token) {
265
239
  return token.startsWith("gr_sess_") ? "X-Org-Session" : "X-Org-Token";
266
240
  }
@@ -269,8 +243,8 @@ function setOrgAuthHeader(headers2, token) {
269
243
  headers2.set(orgAuthHeaderName(token), token);
270
244
  }
271
245
  var ApiError, BaseApiClient;
272
- var init_chunk_67QXTQVL = __esm({
273
- "../sdk/dist/chunk-67QXTQVL.js"() {
246
+ var init_chunk_TGL72KPS = __esm({
247
+ "../sdk/dist/chunk-TGL72KPS.js"() {
274
248
  ApiError = class extends Error {
275
249
  statusCode;
276
250
  /** Legacy string-array errors — kept for non-validation callers. */
@@ -344,7 +318,7 @@ var init_chunk_67QXTQVL = __esm({
344
318
  this.apiKey = newApiKey;
345
319
  }
346
320
  /**
347
- * Set the opaque org session credential for cross-domain requests.
321
+ * Set the opaque org session credential a bearer client sends as `X-Org-Session`.
348
322
  * Opaque gr_sess_ values use X-Org-Session. Legacy orgToken JWE values still
349
323
  * use X-Org-Token through setOrgToken() during the migration window.
350
324
  *
@@ -364,7 +338,42 @@ var init_chunk_67QXTQVL = __esm({
364
338
  setOrgToken(token, orgUuid) {
365
339
  this.setOrgSession(token, orgUuid);
366
340
  }
367
- async fetch(endpoint, options) {
341
+ /**
342
+ * The `credentials` a request carries: none for a bearer client (the fetch
343
+ * default), the page's own-origin cookies for a same-origin session.
344
+ */
345
+ credentialsInit() {
346
+ return this.apiKey ? {} : { credentials: "same-origin" };
347
+ }
348
+ /**
349
+ * Run the org-auth handler once for concurrent challenges. A bearer client's
350
+ * handler sets the org session with `setOrgSession`; a same-origin session's
351
+ * handler leaves an httpOnly org-session cookie on the page's origin instead,
352
+ * which the retry presents. A bearer client whose handler issued nothing has
353
+ * nothing to retry with.
354
+ */
355
+ async answerOrgAuthChallenge(orgAuthInfo) {
356
+ const handler = this.orgAuthHandler;
357
+ if (!handler) return;
358
+ if (!this.orgAuthInProgress) {
359
+ this.orgAuthInProgress = (async () => {
360
+ try {
361
+ await handler(orgAuthInfo);
362
+ } finally {
363
+ this.orgAuthInProgress = null;
364
+ }
365
+ })();
366
+ }
367
+ await this.orgAuthInProgress;
368
+ if (this.orgSession) {
369
+ this.orgSessionOrgUuid = orgAuthInfo.orgUuid;
370
+ return;
371
+ }
372
+ if (this.apiKey) {
373
+ throw new ApiError("Organization authentication did not issue a session", 401);
374
+ }
375
+ }
376
+ async fetch(endpoint, options, orgAuthRetry = false) {
368
377
  try {
369
378
  const headers2 = new Headers({
370
379
  // Don't set Content-Type for FormData — the browser must set it
@@ -374,17 +383,12 @@ var init_chunk_67QXTQVL = __esm({
374
383
  });
375
384
  if (this.apiKey) {
376
385
  headers2.set("Authorization", `Bearer ${this.apiKey}`);
377
- } else if (this.isCrossDomain) {
378
- const requestToken = getCookieValue("requestToken");
379
- if (requestToken) {
380
- headers2.set("Authorization", `Bearer ${requestToken}`);
381
- }
382
386
  }
383
387
  setOrgAuthHeader(headers2, this.orgSession);
384
388
  const fullUrl = `${this.baseUrl}/api/v2/${endpoint}`;
385
389
  const response = await this.fetchFunction(fullUrl, {
386
390
  ...options,
387
- ...this.apiKey ? {} : { credentials: "include" },
391
+ ...this.credentialsInit(),
388
392
  ...this.isCrossDomain ? { mode: "cors" } : {},
389
393
  headers: headers2
390
394
  });
@@ -415,48 +419,14 @@ var init_chunk_67QXTQVL = __esm({
415
419
  this.orgSession = void 0;
416
420
  this.orgSessionOrgUuid = void 0;
417
421
  }
418
- if (orgAuthInfo && !this.orgSession) {
419
- const requestCookieName = getRequestOrgCookieName(orgAuthInfo.cookieName);
420
- const cachedOrgSession = requestCookieName ? getCookieValue(requestCookieName) : void 0;
421
- if (cachedOrgSession) {
422
- this.orgSession = cachedOrgSession;
423
- this.orgSessionOrgUuid = orgAuthInfo.orgUuid;
424
- try {
425
- return await this.fetch(endpoint, options);
426
- } catch (retryError) {
427
- this.orgSession = void 0;
428
- this.orgSessionOrgUuid = void 0;
429
- throw retryError;
430
- }
431
- }
432
- if (this.orgAuthHandler) {
433
- if (!this.orgAuthInProgress) {
434
- const handler = this.orgAuthHandler;
435
- this.orgAuthInProgress = (async () => {
436
- try {
437
- await handler(orgAuthInfo);
438
- } finally {
439
- this.orgAuthInProgress = null;
440
- }
441
- })();
442
- }
443
- await this.orgAuthInProgress;
444
- const postHandlerSession = (requestCookieName ? getCookieValue(requestCookieName) : void 0) ?? this.orgSession;
445
- if (!postHandlerSession) {
446
- throw new ApiError(
447
- "Organization authentication did not issue a session",
448
- 401
449
- );
450
- }
451
- this.orgSession = postHandlerSession;
452
- this.orgSessionOrgUuid = orgAuthInfo.orgUuid;
453
- try {
454
- return await this.fetch(endpoint, options);
455
- } catch (retryError) {
456
- this.orgSession = void 0;
457
- this.orgSessionOrgUuid = void 0;
458
- throw retryError;
459
- }
422
+ if (orgAuthInfo && !this.orgSession && !orgAuthRetry && this.orgAuthHandler) {
423
+ await this.answerOrgAuthChallenge(orgAuthInfo);
424
+ try {
425
+ return await this.fetch(endpoint, options, true);
426
+ } catch (retryError) {
427
+ this.orgSession = void 0;
428
+ this.orgSessionOrgUuid = void 0;
429
+ throw retryError;
460
430
  }
461
431
  }
462
432
  }
@@ -518,23 +488,18 @@ ${formattedErrors}`, response.status);
518
488
  throw error;
519
489
  }
520
490
  }
521
- async fetchRaw(endpoint, options, allowedErrorStatuses = []) {
491
+ async fetchRaw(endpoint, options, allowedErrorStatuses = [], orgAuthRetry = false) {
522
492
  try {
523
493
  const headers2 = new Headers({
524
494
  ...options?.headers || {}
525
495
  });
526
496
  if (this.apiKey) {
527
497
  headers2.set("Authorization", `Bearer ${this.apiKey}`);
528
- } else if (this.isCrossDomain) {
529
- const requestToken = getCookieValue("requestToken");
530
- if (requestToken) {
531
- headers2.set("Authorization", `Bearer ${requestToken}`);
532
- }
533
498
  }
534
499
  setOrgAuthHeader(headers2, this.orgSession);
535
500
  const response = await this.fetchFunction(`${this.baseUrl}/api/v2/${endpoint}`, {
536
501
  ...options,
537
- ...this.apiKey ? {} : { credentials: "include" },
502
+ ...this.credentialsInit(),
538
503
  ...this.isCrossDomain ? { mode: "cors" } : {},
539
504
  headers: headers2
540
505
  });
@@ -565,48 +530,14 @@ ${formattedErrors}`, response.status);
565
530
  this.orgSession = void 0;
566
531
  this.orgSessionOrgUuid = void 0;
567
532
  }
568
- if (orgAuthInfo && !this.orgSession) {
569
- const requestCookieName = getRequestOrgCookieName(orgAuthInfo.cookieName);
570
- const cachedOrgSession = requestCookieName ? getCookieValue(requestCookieName) : void 0;
571
- if (cachedOrgSession) {
572
- this.orgSession = cachedOrgSession;
573
- this.orgSessionOrgUuid = orgAuthInfo.orgUuid;
574
- try {
575
- return await this.fetchRaw(endpoint, options, allowedErrorStatuses);
576
- } catch (retryError) {
577
- this.orgSession = void 0;
578
- this.orgSessionOrgUuid = void 0;
579
- throw retryError;
580
- }
581
- }
582
- if (this.orgAuthHandler) {
583
- if (!this.orgAuthInProgress) {
584
- const handler = this.orgAuthHandler;
585
- this.orgAuthInProgress = (async () => {
586
- try {
587
- await handler(orgAuthInfo);
588
- } finally {
589
- this.orgAuthInProgress = null;
590
- }
591
- })();
592
- }
593
- await this.orgAuthInProgress;
594
- const postHandlerSession = (requestCookieName ? getCookieValue(requestCookieName) : void 0) ?? this.orgSession;
595
- if (!postHandlerSession) {
596
- throw new ApiError(
597
- "Organization authentication did not issue a session",
598
- 401
599
- );
600
- }
601
- this.orgSession = postHandlerSession;
602
- this.orgSessionOrgUuid = orgAuthInfo.orgUuid;
603
- try {
604
- return await this.fetchRaw(endpoint, options, allowedErrorStatuses);
605
- } catch (retryError) {
606
- this.orgSession = void 0;
607
- this.orgSessionOrgUuid = void 0;
608
- throw retryError;
609
- }
533
+ if (orgAuthInfo && !this.orgSession && !orgAuthRetry && this.orgAuthHandler) {
534
+ await this.answerOrgAuthChallenge(orgAuthInfo);
535
+ try {
536
+ return await this.fetchRaw(endpoint, options, allowedErrorStatuses, true);
537
+ } catch (retryError) {
538
+ this.orgSession = void 0;
539
+ this.orgSessionOrgUuid = void 0;
540
+ throw retryError;
610
541
  }
611
542
  }
612
543
  }
@@ -634,17 +565,12 @@ ${formattedErrors}`, response.status);
634
565
  });
635
566
  if (this.apiKey) {
636
567
  headers2.set("Authorization", `Bearer ${this.apiKey}`);
637
- } else if (this.isCrossDomain) {
638
- const requestToken = getCookieValue("requestToken");
639
- if (requestToken) {
640
- headers2.set("Authorization", `Bearer ${requestToken}`);
641
- }
642
568
  }
643
569
  setOrgAuthHeader(headers2, this.orgSession);
644
570
  const fullUrl = `${this.baseUrl}/${path4}`;
645
571
  const response = await this.fetchFunction(fullUrl, {
646
572
  ...options,
647
- ...this.apiKey ? {} : { credentials: "include" },
573
+ ...this.credentialsInit(),
648
574
  ...this.isCrossDomain ? { mode: "cors" } : {},
649
575
  headers: headers2
650
576
  });
@@ -3205,7 +3131,7 @@ var init_libphonenumber_js = __esm({
3205
3131
  }
3206
3132
  });
3207
3133
 
3208
- // ../sdk/dist/chunk-N4GQWNGU.js
3134
+ // ../sdk/dist/chunk-QRZVXPR4.js
3209
3135
  function resourceWorkflowsPath(wid, ...segments) {
3210
3136
  const tail = segments.map((segment) => encodeURIComponent(String(segment))).join("/");
3211
3137
  const base = `w/${encodeURIComponent(wid)}/resource-workflows`;
@@ -3311,18 +3237,18 @@ function businessProfilePath(orgUuid, legalEntityUuid) {
3311
3237
  }
3312
3238
  function getOAuthPath(providerSlug, action) {
3313
3239
  if (providerSlug === "google_calendar") {
3314
- return `oauth/google/calendar/${action}`;
3240
+ return `api/v2/oauth/google/calendar/${action}`;
3315
3241
  }
3316
3242
  if (providerSlug === "gmail") {
3317
- return `oauth/google/gmail/${action}`;
3243
+ return `api/v2/oauth/google/gmail/${action}`;
3318
3244
  }
3319
3245
  if (providerSlug === "gdrive") {
3320
- return `oauth/google/drive/${action}`;
3246
+ return `api/v2/oauth/google/drive/${action}`;
3321
3247
  }
3322
3248
  if (providerSlug === "gsheets") {
3323
- return `oauth/google/sheets/${action}`;
3249
+ return `api/v2/oauth/google/sheets/${action}`;
3324
3250
  }
3325
- return `oauth/${providerSlug}/${action}`;
3251
+ return `api/v2/oauth/${providerSlug}/${action}`;
3326
3252
  }
3327
3253
  function buildAuthorizeQuery(options) {
3328
3254
  if (!options) return "";
@@ -3392,6 +3318,16 @@ function planFields(options) {
3392
3318
  }
3393
3319
  return fields;
3394
3320
  }
3321
+ function workspaceDirectoryParams(options = {}) {
3322
+ const params = new URLSearchParams();
3323
+ if (options.page !== void 0) params.set("page", String(options.page));
3324
+ if (options.pageSize !== void 0) params.set("pageSize", String(options.pageSize));
3325
+ if (options.search) params.set("search", options.search);
3326
+ if (options.organizationUuid) params.set("organizationUuid", options.organizationUuid);
3327
+ for (const uuid of options.workspaceUuids ?? []) params.append("workspaceUuids", uuid);
3328
+ for (const id of options.workspaceIds ?? []) params.append("workspaceIds", String(id));
3329
+ return params;
3330
+ }
3395
3331
  function withFilters(params, options) {
3396
3332
  if (options.dateFrom) params.append("dateFrom", options.dateFrom);
3397
3333
  if (options.dateTo) params.append("dateTo", options.dateTo);
@@ -4716,9 +4652,9 @@ function getRevisionState(workflow, revision) {
4716
4652
  };
4717
4653
  }
4718
4654
  var AbilitiesApi, ResourceWorkflowsApi, BundlesApi, InstallationsApi, AccessGrantsApi, AgentTasksApi, AgentsApi, AIModelsApi, ApiKeysApi, AppsApi, AssignmentsApi, VoiceApi, AuthApi, BuildersApi, CalendarsApi, CallsApi, CELApi, ChatsApi, ConfluenceApi, CustomToolkitsApi, DataTypesApi, DiscordBotsApi, SlackAppsApi, EventsApi, FeaturesApi, FhirConnectionsApi, InboundFaxStatus, DocumoFaxApi, HealthieApi, FilesApi, InboxesApi, InquiriesApi, AppConnectionsApi, McpServersApi, MemberImportValidationError, MembersApi, MondayIntegrationApi, NotificationRulesApi, OperatorApi, OrgApi, OAuthConnectionsApi, OAuthApi, PhoneNumbersApi, PronunciationsApi, PromptsApi, PersonasApi, QueriesApi, QualificationsApi, ReportsApi, RoutingRulesApi, SalesforceApi, ConnectionSyncApi, HubspotApi, SitesApi, SubscriptionsApi, SupportRequestsApi, CustomersApi, ResellersApi, SupervisorsApi, TasksApi, TemplatesApi, ToolkitsApi, JourneysApi, WorkflowsApi, WorkflowNotesApi, EventRuleObjectType, EventRuleEventType, EventRuleActionType, DriverMode, MEMBER_RELATIONSHIP_KINDS, WorkspaceInvitationsApi, WorkspacesApi, DashboardsApi, DevicesApi, TeamsAppsApi, ExperimentsApi, PatientSyncConnectionsApi, ActivityApi, MotdApi, InterventionRequestsApi, MetricsApi, ProjectsApi, TrackedLinksApi, WORKSPACE_METHOD_NAMES, WORKSPACE_METHOD_NAME_SET, GravityRailClient, WIDGET_SLUGS, CHAT_TYPES, BUILTIN_ASSISTANT_CHAT_TYPES, MEMBER_AGENT_CHAT_TYPES, ActivityGrain, ActivityGroupBy, ActivityOpenItemOrder, ActivityWindowBasis;
4719
- var init_chunk_N4GQWNGU = __esm({
4720
- "../sdk/dist/chunk-N4GQWNGU.js"() {
4721
- init_chunk_67QXTQVL();
4655
+ var init_chunk_QRZVXPR4 = __esm({
4656
+ "../sdk/dist/chunk-QRZVXPR4.js"() {
4657
+ init_chunk_TGL72KPS();
4722
4658
  init_libphonenumber_js();
4723
4659
  AbilitiesApi = class extends BaseApiClient {
4724
4660
  /**
@@ -5684,18 +5620,13 @@ var init_chunk_N4GQWNGU = __esm({
5684
5620
  }
5685
5621
  return await response.json();
5686
5622
  }
5687
- /** Request a cross-domain authentication token for single sign-on across domains. */
5623
+ /** @deprecated Browser continuity uses top-level /auth/continue navigation. */
5688
5624
  async requestCrossDomainToken() {
5689
- return this.fetch("auth/cross-domain-token", {
5690
- method: "POST"
5691
- });
5625
+ throw new Error("Use top-level /auth/continue navigation. CLI login uses OAuth with PKCE.");
5692
5626
  }
5693
- /** Exchange a cross-domain token for an authenticated session token. */
5694
- async exchangeToken(token) {
5695
- return this.fetch("auth/exchange-token", {
5696
- method: "POST",
5697
- body: JSON.stringify({ token })
5698
- });
5627
+ /** @deprecated Browser handoffs redeem only at the destination Next server. */
5628
+ async exchangeToken(_token) {
5629
+ throw new Error("Use top-level /auth/continue navigation. CLI login uses OAuth with PKCE.");
5699
5630
  }
5700
5631
  /** Exchange a global Account login for an opaque org-scoped session handle. */
5701
5632
  async exchangeSession(request) {
@@ -5876,9 +5807,17 @@ var init_chunk_N4GQWNGU = __esm({
5876
5807
  );
5877
5808
  }
5878
5809
  // ===== ORGANIZATION MEMBERSHIP METHODS =====
5879
- /** List all organizations the current account belongs to. */
5880
- async getMyOrganizations() {
5881
- return this.fetch("o/mine");
5810
+ /** A searchable page of the current account's organizations. */
5811
+ async getMyOrganizations(options) {
5812
+ const params = new URLSearchParams();
5813
+ if (options?.page) params.set("page", String(options.page));
5814
+ if (options?.pageSize) params.set("pageSize", String(options.pageSize));
5815
+ if (options?.canCreateWorkspace) params.set("canCreateWorkspace", "true");
5816
+ if (options?.search) params.set("search", options.search);
5817
+ if (options?.organizationSlug !== void 0)
5818
+ params.set("organizationSlug", options.organizationSlug);
5819
+ for (const uuid of options?.organizationUuids ?? []) params.append("organizationUuids", uuid);
5820
+ return this.fetch(`o/mine?${params}`);
5882
5821
  }
5883
5822
  // ===== CREDENTIAL CHANGE METHODS =====
5884
5823
  /**
@@ -8717,14 +8656,7 @@ var init_chunk_N4GQWNGU = __esm({
8717
8656
  }
8718
8657
  const queryString = params.toString();
8719
8658
  const url = queryString ? `inquiries/export/csv?${queryString}` : "inquiries/export/csv";
8720
- const response = await fetch(`${this.baseUrl}/api/v2/${url}`, {
8721
- method: "GET",
8722
- credentials: "include"
8723
- });
8724
- if (!response.ok) {
8725
- const error = await response.json();
8726
- throw new Error(error.detail || "Export failed");
8727
- }
8659
+ const response = await this.fetchRaw(url, { method: "GET" });
8728
8660
  return response.blob();
8729
8661
  }
8730
8662
  };
@@ -9960,8 +9892,12 @@ var init_chunk_N4GQWNGU = __esm({
9960
9892
  * figure — the caps belong to the organization, so `cap - oneWorkspace`
9961
9893
  * describes nothing.
9962
9894
  */
9963
- async getOrgWorkspaceUsage(orgIdOrUuid) {
9964
- return this.fetch(`o/${orgIdOrUuid}/usage/workspaces`);
9895
+ async getOrgWorkspaceUsage(orgIdOrUuid, options) {
9896
+ const params = new URLSearchParams();
9897
+ if (options?.page) params.set("page", String(options.page));
9898
+ if (options?.pageSize) params.set("pageSize", String(options.pageSize));
9899
+ if (options?.search) params.set("search", options.search);
9900
+ return this.fetch(`o/${orgIdOrUuid}/usage/workspaces?${params}`);
9965
9901
  }
9966
9902
  /**
9967
9903
  * List members of an organization.
@@ -10085,8 +10021,14 @@ var init_chunk_N4GQWNGU = __esm({
10085
10021
  * counts. Any org member may call it — members get the workspaces they
10086
10022
  * belong to, org:read holders get all of them.
10087
10023
  */
10088
- async getOrganizationWorkspaceSummaries(orgIdOrUuid) {
10089
- return this.fetch(`o/${orgIdOrUuid}/workspaces/summary`);
10024
+ async getOrganizationWorkspaceSummaries(orgIdOrUuid, options) {
10025
+ const params = new URLSearchParams();
10026
+ if (options?.page) params.set("page", String(options.page));
10027
+ if (options?.pageSize) params.set("pageSize", String(options.pageSize));
10028
+ if (options?.search) params.set("search", options.search);
10029
+ return this.fetch(
10030
+ `o/${orgIdOrUuid}/workspaces/summary?${params}`
10031
+ );
10090
10032
  }
10091
10033
  /**
10092
10034
  * Workspace-schema aggregates for one card, plus the caller's own member
@@ -13305,7 +13247,8 @@ var init_chunk_N4GQWNGU = __esm({
13305
13247
  /**
13306
13248
  * Classify the prompts of a Workflow's draft revision.
13307
13249
  *
13308
- * A decision model reads each Task that has a prompt and reports which
13250
+ * A decision model reads each live Task with Workflow or Task instructions
13251
+ * and reports which
13309
13252
  * prompt classifications probably apply. Each call asks the model again.
13310
13253
  */
13311
13254
  async getWorkflowPromptClassifications(wid, workflowId) {
@@ -13942,21 +13885,21 @@ var init_chunk_N4GQWNGU = __esm({
13942
13885
  }
13943
13886
  };
13944
13887
  WorkspacesApi = class extends BaseApiClient {
13945
- /** List all workspaces accessible to the current user. */
13946
- async getWorkspaces() {
13947
- return this.fetch("w/");
13888
+ /** A bounded page of workspaces accessible to the current account. */
13889
+ async getWorkspaces(options) {
13890
+ return this.fetch(`w/?${workspaceDirectoryParams(options)}`);
13948
13891
  }
13949
- /**
13950
- * Compact rows for the workspaces a companion device could enter — the
13951
- * Lantern picker. Filtered by the same admission policy a device
13952
- * credential is gated by, without needing the device credential.
13953
- */
13954
- async getDeviceAdmissibleWorkspaces() {
13955
- return this.fetch("w/?can_use_device=1");
13892
+ /** A bounded page of companion-device candidates, with admission checked per row. */
13893
+ async getDeviceAdmissibleWorkspaces(options) {
13894
+ const params = workspaceDirectoryParams(options);
13895
+ params.set("can_use_device", "1");
13896
+ return this.fetch(`w/?${params}`);
13956
13897
  }
13957
- /** List all publicly visible workspaces. */
13958
- async getPublicWorkspaces() {
13959
- return this.fetch("w/public");
13898
+ /** A bounded page of publicly visible workspaces. */
13899
+ async getPublicWorkspaces(options) {
13900
+ return this.fetch(
13901
+ `w/public?${workspaceDirectoryParams(options)}`
13902
+ );
13960
13903
  }
13961
13904
  /** Get a single workspace by ID. */
13962
13905
  async getWorkspace(wid) {
@@ -14239,13 +14182,22 @@ var init_chunk_N4GQWNGU = __esm({
14239
14182
  * @param scope - Export scope ("workflows" for all workflows only). Cannot be combined with workflowId.
14240
14183
  * @param exclude - Comma-separated entity categories to exclude (e.g. "channels")
14241
14184
  */
14242
- async exportWorkspace(wid, workflowId, scope, exclude) {
14185
+ async exportWorkspace(wid, workflowId, scope, exclude, options) {
14243
14186
  const searchParams = new URLSearchParams();
14244
14187
  if (workflowId !== void 0) searchParams.set("workflow_id", String(workflowId));
14245
14188
  if (scope !== void 0) searchParams.set("scope", scope);
14246
14189
  if (exclude !== void 0) searchParams.set("exclude", exclude);
14190
+ if (options?.revisionId !== void 0)
14191
+ searchParams.set("revision_id", String(options.revisionId));
14192
+ if (options?.revisionMode !== void 0) {
14193
+ searchParams.set("revision_mode", options.revisionMode);
14194
+ } else if (options?.revisionId === void 0) {
14195
+ searchParams.set("revision_mode", "active");
14196
+ }
14247
14197
  const qs = searchParams.toString();
14248
- return this.fetch(`w/${wid}/export${qs ? `?${qs}` : ""}`);
14198
+ const data = await this.fetch(`w/${wid}/export${qs ? `?${qs}` : ""}`);
14199
+ this.verifyExportSelection(data, workflowId, options);
14200
+ return data;
14249
14201
  }
14250
14202
  /** Preview the result of importing workspace configuration without applying changes.
14251
14203
  *
@@ -14304,15 +14256,60 @@ var init_chunk_N4GQWNGU = __esm({
14304
14256
  * target workspace.
14305
14257
  */
14306
14258
  /** Download a workspace export ZIP (``export.json`` + file blobs). */
14307
- async exportWorkspaceZip(wid, workflowId, scope, exclude) {
14259
+ async exportWorkspaceZip(wid, workflowId, scope, exclude, options) {
14308
14260
  const searchParams = new URLSearchParams();
14309
14261
  if (workflowId !== void 0) searchParams.set("workflow_id", String(workflowId));
14310
14262
  if (scope !== void 0) searchParams.set("scope", scope);
14311
14263
  if (exclude !== void 0) searchParams.set("exclude", exclude);
14264
+ if (options?.revisionId !== void 0)
14265
+ searchParams.set("revision_id", String(options.revisionId));
14266
+ if (options?.revisionMode !== void 0) {
14267
+ searchParams.set("revision_mode", options.revisionMode);
14268
+ } else if (options?.revisionId === void 0) {
14269
+ searchParams.set("revision_mode", "active");
14270
+ }
14312
14271
  const qs = searchParams.toString();
14313
14272
  const response = await this.fetchRaw(`w/${wid}/export.zip${qs ? `?${qs}` : ""}`);
14273
+ if (options?.revisionId !== void 0 || options?.revisionMode === "all") {
14274
+ const version = response.headers.get("X-Gravityrail-Export-Version");
14275
+ const selection = response.headers.get("X-Gravityrail-Export-Selection");
14276
+ const selected = options?.revisionId !== void 0;
14277
+ if (version !== (selected ? "1.0" : "2.0") || selection !== (selected ? "selected" : "all") || selected && (workflowId === void 0 || !response.headers.get("X-Gravityrail-Export-Revision-Uuid")?.trim() || !response.headers.get("X-Gravityrail-Export-Workflow-Uuid")?.trim())) {
14278
+ try {
14279
+ await response.body?.cancel();
14280
+ } catch {
14281
+ }
14282
+ throw new Error(
14283
+ "Server did not return verified Workflow revision export headers. Request an explicit active snapshot or use a server that supports export provenance."
14284
+ );
14285
+ }
14286
+ }
14314
14287
  return response.arrayBuffer();
14315
14288
  }
14289
+ // Compatibility shape check only. The backend WorkspaceExportData
14290
+ // _validate_revision_archive owns full graph/publication invariants.
14291
+ verifyExportSelection(data, workflowId, options) {
14292
+ const hasUuid = (value) => typeof value === "string" && value.trim().length > 0;
14293
+ if (options?.revisionId !== void 0) {
14294
+ const revisions = data?.workflowRevisions;
14295
+ if (workflowId === void 0 || data?.version !== "1.0" || data.workflowRevisionSelection !== "selected" || !Array.isArray(revisions) || revisions.length !== 1) {
14296
+ throw new Error(
14297
+ "Server did not return the requested Workflow revision. Use a server that supports revision selection."
14298
+ );
14299
+ }
14300
+ if (!hasUuid(revisions[0]?.uuid) || !hasUuid(revisions[0]?.workflow?.uuid) || !hasUuid(data.workflows?.[0]?.uuid) || data.workflows?.length !== 1 || revisions[0]?.workflow?.uuid !== data.workflows[0]?.uuid) {
14301
+ throw new Error("Server export does not match the requested Workflow revision.");
14302
+ }
14303
+ } else if (options?.revisionMode === "all" && (data?.version !== "2.0" || data.workflowRevisionSelection !== "all" || !Array.isArray(data.workflowRevisions) || !Array.isArray(data.workflows) || data.workflows.some(
14304
+ (workflow) => !hasUuid(workflow?.uuid) || !data.workflowRevisions?.some(
14305
+ (revision) => hasUuid(revision?.uuid) && revision?.workflow?.uuid === workflow.uuid
14306
+ )
14307
+ ))) {
14308
+ throw new Error(
14309
+ "Server did not return all Workflow revisions. Request an explicit active snapshot or use a server that supports revision archives."
14310
+ );
14311
+ }
14312
+ }
14316
14313
  /** Import workspace configuration from exported JSON, or from a ZIP archive.
14317
14314
  * Pass ``archive`` (the ZIP from ``exportWorkspaceZip``) to restore file
14318
14315
  * contents. ``exportData`` may be omitted when the ZIP contains it.
@@ -17537,9 +17534,9 @@ var init_chunk_N4GQWNGU = __esm({
17537
17534
  }
17538
17535
  });
17539
17536
 
17540
- // ../sdk/dist/chunk-72SWNLVD.js
17541
- var init_chunk_72SWNLVD = __esm({
17542
- "../sdk/dist/chunk-72SWNLVD.js"() {
17537
+ // ../sdk/dist/chunk-MMDSZ25F.js
17538
+ var init_chunk_MMDSZ25F = __esm({
17539
+ "../sdk/dist/chunk-MMDSZ25F.js"() {
17543
17540
  }
17544
17541
  });
17545
17542
 
@@ -17594,10 +17591,10 @@ var init_chunk_6KPGCPGW = __esm({
17594
17591
  var SEARCHABLE_EVENT_RULE_SOURCE_FIELDS, ActivityEventType, EntityKind;
17595
17592
  var init_dist = __esm({
17596
17593
  "../sdk/dist/index.js"() {
17597
- init_chunk_N4GQWNGU();
17598
- init_chunk_72SWNLVD();
17594
+ init_chunk_QRZVXPR4();
17595
+ init_chunk_MMDSZ25F();
17599
17596
  init_chunk_6KPGCPGW();
17600
- init_chunk_67QXTQVL();
17597
+ init_chunk_TGL72KPS();
17601
17598
  SEARCHABLE_EVENT_RULE_SOURCE_FIELDS = [
17602
17599
  "taskId",
17603
17600
  "dataTypeId",
@@ -21683,22 +21680,6 @@ var init_output = __esm({
21683
21680
  };
21684
21681
  }
21685
21682
  });
21686
- function extractOrgSessionFromSetCookies(setCookieValues, preferredCookieName) {
21687
- let fallback;
21688
- for (const value of setCookieValues) {
21689
- const nameValue = value.split(";")[0]?.trim() ?? "";
21690
- const eqIdx = nameValue.indexOf("=");
21691
- if (eqIdx === -1) continue;
21692
- const name = nameValue.slice(0, eqIdx).trim();
21693
- const credentialValue = nameValue.slice(eqIdx + 1).trim() || void 0;
21694
- if (!credentialValue) continue;
21695
- if (name === preferredCookieName) return credentialValue;
21696
- if (!fallback && (name.startsWith("orgToken") || name.startsWith("orgSession"))) {
21697
- fallback = credentialValue;
21698
- }
21699
- }
21700
- return fallback;
21701
- }
21702
21683
  async function tryDirectJoin(apiUrl, accessToken, orgAuthInfo) {
21703
21684
  const response = await fetch(`${apiUrl}/api/v2/o/${orgAuthInfo.orgUuid}/join`, {
21704
21685
  method: "POST",
@@ -21714,16 +21695,16 @@ async function tryDirectJoin(apiUrl, accessToken, orgAuthInfo) {
21714
21695
  if (!response.ok) {
21715
21696
  throw new Error(`Org join failed (HTTP ${response.status})`);
21716
21697
  }
21717
- const rawHeaders = response.headers;
21718
- const setCookies = rawHeaders.getSetCookie?.() ?? (rawHeaders.get("set-cookie") ? [rawHeaders.get("set-cookie")] : []);
21719
- if (setCookies.length === 0) {
21720
- throw new Error("Org join succeeded but no Set-Cookie header returned");
21698
+ let body;
21699
+ try {
21700
+ body = await response.json();
21701
+ } catch {
21702
+ throw new Error("Org join succeeded but returned an invalid response");
21721
21703
  }
21722
- const orgSession = extractOrgSessionFromSetCookies(setCookies, orgAuthInfo.cookieName);
21723
- if (!orgSession) {
21724
- throw new Error("Org join succeeded but org session cookie not found in Set-Cookie");
21704
+ if (typeof body.orgSession !== "string" || !body.orgSession) {
21705
+ throw new Error("Org join succeeded but returned no org session");
21725
21706
  }
21726
- return orgSession;
21707
+ return body.orgSession;
21727
21708
  }
21728
21709
  function isAllowedAuthUrl(url, apiUrl, frontendUrl) {
21729
21710
  try {
@@ -21764,62 +21745,31 @@ function isHeadless() {
21764
21745
  }
21765
21746
  return false;
21766
21747
  }
21767
- function startOrgSessionCapture(expectedState, expectedOrgUuid, allowedOrigin) {
21748
+ function startOrgSessionCapture(expectedState, expectedOrgUuid, _allowedOrigin) {
21768
21749
  let resolveSession;
21769
21750
  let rejectSession;
21770
21751
  const session = new Promise((resolve3, reject) => {
21771
21752
  resolveSession = resolve3;
21772
21753
  rejectSession = reject;
21773
21754
  });
21774
- const applyCors = (req, res) => {
21775
- if (req.headers.origin && req.headers.origin === allowedOrigin) {
21776
- res.setHeader("Access-Control-Allow-Origin", allowedOrigin);
21777
- res.setHeader("Vary", "Origin");
21778
- }
21779
- res.setHeader("Access-Control-Allow-Methods", "POST, OPTIONS");
21780
- res.setHeader("Access-Control-Allow-Headers", "Content-Type");
21781
- };
21782
21755
  const server = createServer((req, res) => {
21783
- applyCors(req, res);
21784
- if (req.method === "OPTIONS") {
21785
- res.setHeader("Access-Control-Allow-Private-Network", "true");
21786
- res.writeHead(204);
21756
+ res.setHeader("Cache-Control", "no-store");
21757
+ res.setHeader("Referrer-Policy", "no-referrer");
21758
+ if (req.method !== "GET") {
21759
+ res.writeHead(405);
21787
21760
  res.end();
21788
21761
  return;
21789
21762
  }
21790
- if (req.method !== "POST") {
21791
- res.writeHead(405);
21792
- res.end();
21763
+ const callback = new URL(req.url ?? "/", "http://127.0.0.1");
21764
+ const code = callback.searchParams.get("code");
21765
+ if (callback.pathname !== "/" || !code?.startsWith("gr_cli_org_") || callback.searchParams.get("state") !== expectedState || callback.searchParams.get("org_uuid") !== expectedOrgUuid) {
21766
+ res.writeHead(400);
21767
+ res.end("Invalid sign-in callback");
21793
21768
  return;
21794
21769
  }
21795
- let body = "";
21796
- let tooLarge = false;
21797
- req.on("data", (chunk) => {
21798
- body += chunk;
21799
- if (body.length > 16 * 1024) {
21800
- tooLarge = true;
21801
- req.destroy();
21802
- }
21803
- });
21804
- req.on("end", () => {
21805
- if (tooLarge) return;
21806
- let capturedSession;
21807
- try {
21808
- const payload = JSON.parse(body);
21809
- if (typeof payload.org_session === "string" && payload.org_session.length > 0 && payload.state === expectedState && payload.org_uuid === expectedOrgUuid) {
21810
- capturedSession = payload.org_session;
21811
- }
21812
- } catch {
21813
- }
21814
- if (capturedSession) {
21815
- res.writeHead(200, { "Content-Type": "application/json" });
21816
- res.end('{"ok":true}');
21817
- resolveSession(capturedSession);
21818
- } else {
21819
- res.writeHead(400, { "Content-Type": "application/json" });
21820
- res.end('{"ok":false}');
21821
- }
21822
- });
21770
+ res.writeHead(200, { "Content-Type": "text/plain" });
21771
+ res.end("Return to the terminal to finish sign-in.");
21772
+ resolveSession(code);
21823
21773
  });
21824
21774
  let resolveReady;
21825
21775
  let rejectReady;
@@ -21851,22 +21801,30 @@ function startOrgSessionCapture(expectedState, expectedOrgUuid, allowedOrigin) {
21851
21801
  };
21852
21802
  return { ready, session, close };
21853
21803
  }
21854
- function buildStepUpUrl(authUrl, orgUuid, port, state) {
21804
+ function buildStepUpUrl(authUrl, orgUuid, port, state, challenge) {
21855
21805
  const url = new URL(authUrl);
21856
- const bridgeQuery = new URLSearchParams({ org: orgUuid, port: String(port), state });
21806
+ const bridgeQuery = new URLSearchParams({ org: orgUuid, port: String(port), state, challenge });
21857
21807
  url.searchParams.set("return_to", `${CLI_ORG_AUTH_BRIDGE_PATH}?${bridgeQuery.toString()}`);
21858
21808
  return url.toString();
21859
21809
  }
21860
21810
  function newStateNonce() {
21861
21811
  return randomBytes(16).toString("hex");
21862
21812
  }
21863
- async function stepUpViaBrowser(orgAuthInfo) {
21813
+ async function stepUpViaBrowser(orgAuthInfo, apiUrl, accessToken) {
21864
21814
  const state = newStateNonce();
21865
- const allowedOrigin = new URL(orgAuthInfo.authUrl).origin;
21866
- const capture = startOrgSessionCapture(state, orgAuthInfo.orgUuid, allowedOrigin);
21815
+ const verifier = randomBytes(32).toString("base64url");
21816
+ const challenge = createHash("sha256").update(verifier).digest("base64url");
21817
+ new URL(orgAuthInfo.authUrl).origin;
21818
+ const capture = startOrgSessionCapture(state, orgAuthInfo.orgUuid);
21867
21819
  try {
21868
21820
  const port = await capture.ready;
21869
- const stepUpUrl = buildStepUpUrl(orgAuthInfo.authUrl, orgAuthInfo.orgUuid, port, state);
21821
+ const stepUpUrl = buildStepUpUrl(
21822
+ orgAuthInfo.authUrl,
21823
+ orgAuthInfo.orgUuid,
21824
+ port,
21825
+ state,
21826
+ challenge
21827
+ );
21870
21828
  stderr2(`
21871
21829
  This workspace requires organization SSO authentication.`);
21872
21830
  stderr2(`Opening browser to complete sign-in...`);
@@ -21874,7 +21832,19 @@ This workspace requires organization SSO authentication.`);
21874
21832
  `);
21875
21833
  stderr2(`If the browser does not open, visit the URL above manually.`);
21876
21834
  openBrowser2(stepUpUrl);
21877
- return await capture.session;
21835
+ const code = await capture.session;
21836
+ const response = await fetch(`${apiUrl}/api/v2/auth/cli-org-handoff/redeem`, {
21837
+ method: "POST",
21838
+ headers: { "Content-Type": "application/json", Authorization: `Bearer ${accessToken}` },
21839
+ body: JSON.stringify({ orgUuid: orgAuthInfo.orgUuid, code, verifier })
21840
+ });
21841
+ if (!response.ok)
21842
+ throw new Error(`Could not finish organization sign-in (${response.status}).`);
21843
+ const result2 = await response.json();
21844
+ if (typeof result2.orgSession !== "string" || !result2.orgSession.startsWith("gr_sess_")) {
21845
+ throw new Error("Invalid organization sign-in response.");
21846
+ }
21847
+ return result2.orgSession;
21878
21848
  } finally {
21879
21849
  capture.close();
21880
21850
  }
@@ -21920,7 +21890,7 @@ function registerOrgAuthHandler(apiClient, apiUrl, accessToken, orgAuthCtx) {
21920
21890
  `Refusing to open organization auth URL: host does not match the configured API/frontend host. Re-run with the expected --api-url, or contact support.`
21921
21891
  );
21922
21892
  }
21923
- const session = await stepUpViaBrowser(orgAuthInfo);
21893
+ const session = await stepUpViaBrowser(orgAuthInfo, apiUrl, accessToken);
21924
21894
  adopt(session);
21925
21895
  });
21926
21896
  }
@@ -24085,7 +24055,7 @@ var chatsDomain = {
24085
24055
 
24086
24056
  // ../sdk/dist/helpers.js
24087
24057
  init_chunk_6KPGCPGW();
24088
- init_chunk_67QXTQVL();
24058
+ init_chunk_TGL72KPS();
24089
24059
  new TextEncoder();
24090
24060
  var WORKSPACE_EXPORT_JSON_MEMBER = "export.json";
24091
24061
  var MAX_EXPORT_JSON_BYTES = 8 * 1024 * 1024;
@@ -26384,7 +26354,9 @@ async function exportTemplateArchive(client3, templateUuid) {
26384
26354
  return withTransferProgress(
26385
26355
  "template archive",
26386
26356
  templateUuid,
26387
- () => client3.exportWorkspaceZip(templateUuid, void 0, void 0, REAPPLY_EXPORT_EXCLUDE)
26357
+ () => client3.exportWorkspaceZip(templateUuid, void 0, void 0, REAPPLY_EXPORT_EXCLUDE, {
26358
+ revisionMode: "active"
26359
+ })
26388
26360
  );
26389
26361
  }
26390
26362
  async function readBindingsFile(filePath, targets) {
@@ -26718,26 +26690,27 @@ var workspacesDomain = {
26718
26690
  }),
26719
26691
  {
26720
26692
  path: ["workspaces", "list"],
26721
- description: "List workspaces",
26693
+ description: "List a searchable page of workspaces",
26722
26694
  requiresWorkspace: false,
26723
26695
  columns: COLUMNS6,
26724
26696
  args: [
26697
+ { name: "page", description: "Page number" },
26698
+ { name: "page-size", description: "Page size (at most 100)" },
26699
+ { name: "search", description: "Search name, slug or UUID" },
26725
26700
  {
26726
26701
  name: "org",
26727
26702
  aliases: ["org-uuid"],
26728
- description: "Only workspaces in this organization (UUID). Filters the list client-side on organizationUuid."
26703
+ description: "Only workspaces in this organization (UUID)."
26729
26704
  }
26730
26705
  ],
26731
26706
  examples: ["gr workspaces list --org <org-uuid> -o json"],
26732
26707
  handler: async ({ ctx, args }) => {
26733
- const result2 = await requireAuth(ctx).apiClient.getWorkspaces();
26734
- const org = typeof args.org === "string" ? args.org.trim().toLowerCase() : "";
26735
- const items = org ? unwrapItems(result2).filter(
26736
- (ws) => String(
26737
- ws.organizationUuid ?? ""
26738
- ).toLowerCase() === org
26739
- ) : result2;
26740
- outputData(listResult(items, false), ctx, COLUMNS6);
26708
+ const result2 = await requireAuth(ctx).apiClient.getWorkspaces({
26709
+ ...parsePaginationArgs(args),
26710
+ search: typeof args.search === "string" ? args.search : void 0,
26711
+ organizationUuid: typeof args.org === "string" ? args.org.trim() : void 0
26712
+ });
26713
+ outputData(listResult(result2, false), ctx, COLUMNS6);
26741
26714
  }
26742
26715
  },
26743
26716
  // Custom get that accepts either --id or -w as the workspace identifier
@@ -26873,6 +26846,14 @@ Provisioning started. Watch it come up with:
26873
26846
  name: "workflow-id",
26874
26847
  description: "Export a single workflow by ID"
26875
26848
  },
26849
+ {
26850
+ name: "revision-id",
26851
+ description: "Export one revision ID. Requires --workflow-id; import updates an editable draft."
26852
+ },
26853
+ {
26854
+ name: "revision-mode",
26855
+ description: "active (default, current snapshot only) or all (history including drafts)"
26856
+ },
26876
26857
  {
26877
26858
  name: "exclude",
26878
26859
  description: 'Comma-separated categories to exclude (e.g. "channels")'
@@ -26896,6 +26877,15 @@ Provisioning started. Watch it come up with:
26896
26877
  handler: async ({ ctx, workspace, args }) => {
26897
26878
  const scope = args["scope"];
26898
26879
  const workflowIdStr = args["workflow-id"];
26880
+ const revisionIdStr = args["revision-id"];
26881
+ const revisionId = revisionIdStr === void 0 ? void 0 : Number(revisionIdStr);
26882
+ const revisionMode = args["revision-mode"] ?? (revisionId !== void 0 ? "all" : "active");
26883
+ if (revisionId !== void 0 && (!Number.isSafeInteger(revisionId) || revisionId <= 0)) {
26884
+ throw new CLIError("--revision-id must be a positive integer");
26885
+ }
26886
+ if (revisionMode !== "all" && revisionMode !== "active") {
26887
+ throw new CLIError('--revision-mode must be "all" or "active"');
26888
+ }
26899
26889
  const exclude = args["exclude"];
26900
26890
  const outputPath = args["output"];
26901
26891
  const formatArg = args["format"];
@@ -26906,6 +26896,12 @@ Provisioning started. Watch it come up with:
26906
26896
  if (scope && workflowId !== void 0) {
26907
26897
  throw new CLIError("Cannot specify both --scope and --workflow-id");
26908
26898
  }
26899
+ if (revisionId !== void 0 && (workflowId === void 0 || revisionMode !== "all")) {
26900
+ throw new CLIError(
26901
+ "--revision-id requires --workflow-id and cannot be combined with active mode"
26902
+ );
26903
+ }
26904
+ const revisionOptions = { revisionId, revisionMode };
26909
26905
  if (scope && scope !== "workflows") {
26910
26906
  throw new CLIError('--scope must be "workflows"');
26911
26907
  }
@@ -26922,7 +26918,8 @@ Provisioning started. Watch it come up with:
26922
26918
  workspace,
26923
26919
  workflowId,
26924
26920
  scope,
26925
- exclude
26921
+ exclude,
26922
+ revisionOptions
26926
26923
  );
26927
26924
  await writeFile(outputPath, Buffer.from(zip));
26928
26925
  process.stdout.write(`Saved ZIP export to ${outputPath}
@@ -26933,7 +26930,8 @@ Provisioning started. Watch it come up with:
26933
26930
  workspace,
26934
26931
  workflowId,
26935
26932
  scope,
26936
- exclude
26933
+ exclude,
26934
+ revisionOptions
26937
26935
  );
26938
26936
  if (outputPath) {
26939
26937
  await writeFile(outputPath, `${JSON.stringify(result2, null, 2)}
@@ -28072,11 +28070,19 @@ Each entry in "fields" (a schema field)
28072
28070
  required (bool) Whether the field must be supplied
28073
28071
  description (string) Optional help text
28074
28072
  options (array) For fieldType "enum": [{"label":"\u2026","value":"\u2026"}, \u2026]
28075
- referencedTypeId (number) For reference fields: target data type id
28073
+ referencedTypeId (number) For reference fields: target Form integer id
28074
+ referenceFieldId (number) Server-issued reference identity. Preserve on update;
28075
+ omit for a new reference field.
28076
28076
 
28077
28077
  Valid fieldType values
28078
28078
  text, longtext, email, phone, number, integer, boolean, date, datetime,
28079
- time_of_day, us_zip_code, enum, array, object, function
28079
+ time_of_day, us_zip_code, enum, array, object, function, reference
28080
+
28081
+ Record references
28082
+ {"slug":"customer","name":"Customer","fieldType":"reference","referencedTypeId":8}
28083
+ Record fieldValues use a positive existing integer record id, or null to clear.
28084
+ Reference fields require authenticated reads/writes. Portable transfer and CSV
28085
+ import/export for Forms with references are unsupported.
28080
28086
 
28081
28087
  Example
28082
28088
  gr data-types create -w $WID --allow-write --data '{"name":"Patient","fields":[
@@ -28385,8 +28391,15 @@ var ACTION_PARAM_HINTS = {
28385
28391
  },
28386
28392
  "assistant:message": {
28387
28393
  summary: "inject an assistant message into the chat",
28388
- shape: ['{"message":"Welcome! \u2026","suggestions":["Yes","No"],"waitForResponse":<bool>}'],
28389
- notes: ['message is required. The key is "message", not "messageTemplate".']
28394
+ shape: [
28395
+ '{"message":"Welcome! \u2026","suggestions":["Yes","No"],"waitForResponse":<bool>,"allowInterrupt":<bool>}'
28396
+ ],
28397
+ notes: [
28398
+ 'message is required. The key is "message", not "messageTemplate".',
28399
+ "allowInterrupt (default true) is barge-in; waitForResponse (default true) is turn",
28400
+ "ownership. They are independent \u2014 do not derive one from the other. allowInterrupt=false",
28401
+ "is honoured only on a native canned-speech voice provider (xAI force_message)."
28402
+ ]
28390
28403
  },
28391
28404
  "chat:pause": {
28392
28405
  summary: "pause the chat for a human response",
@@ -33916,7 +33929,7 @@ var NO_UUID_LOOKUP = /* @__PURE__ */ new Set([
33916
33929
  ]);
33917
33930
  var HYDRATORS = {
33918
33931
  workspace: async ({ client: client3 }, ref) => (await client3.getWorkspace(ref.uuid)).name,
33919
- org: async ({ orgNames }, ref) => (await orgNames()).get(ref.uuid),
33932
+ org: async ({ orgNames }, ref) => (await orgNames(ref.uuid)).get(ref.uuid),
33920
33933
  workflow: async ({ client: client3 }, ref) => {
33921
33934
  const detail = await client3.getWorkflow(requireWorkspace(ref), ref.uuid);
33922
33935
  return detail.workflow?.name;
@@ -33978,7 +33991,7 @@ var ActivityRefResolver = class {
33978
33991
  inFlight = /* @__PURE__ */ new Map();
33979
33992
  fetches = 0;
33980
33993
  /** The org membership listing, fetched at most once per invocation. */
33981
- orgNamesPromise;
33994
+ orgNamesPromises = /* @__PURE__ */ new Map();
33982
33995
  /** How many API calls hydration actually made. `--ids` must keep this at 0. */
33983
33996
  get fetchCount() {
33984
33997
  return this.fetches;
@@ -34160,21 +34173,24 @@ var ActivityRefResolver = class {
34160
34173
  return resolution.label;
34161
34174
  }
34162
34175
  /**
34163
- * The caller's org memberships as uuid → name, fetched once.
34176
+ * The caller's matching organization membership, fetched once per UUID.
34164
34177
  *
34165
34178
  * The promise is cached, not its value, so N org refs resolving at once
34166
34179
  * share one request — the same rule the ref cache follows.
34167
34180
  */
34168
- orgNames() {
34169
- this.orgNamesPromise ??= this.client.getMyOrganizations().then(
34181
+ orgNames(uuid) {
34182
+ const cached = this.orgNamesPromises.get(uuid);
34183
+ if (cached) return cached;
34184
+ const pending = this.client.getMyOrganizations({ search: uuid, pageSize: 1 }).then(
34170
34185
  (memberships) => new Map(
34171
- memberships.map((membership) => [
34186
+ memberships.items.map((membership) => [
34172
34187
  membership.organizationUuid,
34173
34188
  membership.organizationName
34174
34189
  ])
34175
34190
  )
34176
34191
  );
34177
- return this.orgNamesPromise;
34192
+ this.orgNamesPromises.set(uuid, pending);
34193
+ return pending;
34178
34194
  }
34179
34195
  async lookup(ref) {
34180
34196
  const hydrator = HYDRATORS[ref.kind];
@@ -34187,7 +34203,10 @@ var ActivityRefResolver = class {
34187
34203
  }
34188
34204
  this.fetches += 1;
34189
34205
  try {
34190
- const name = await hydrator({ client: this.client, orgNames: () => this.orgNames() }, ref);
34206
+ const name = await hydrator(
34207
+ { client: this.client, orgNames: (uuid) => this.orgNames(uuid) },
34208
+ ref
34209
+ );
34191
34210
  if (!name) return { label: bareLabel(ref), status: "unresolved" };
34192
34211
  return { label: name, status: "resolved" };
34193
34212
  } catch (error) {
@@ -36969,8 +36988,21 @@ var orgDomain = {
36969
36988
  path: ["org", "list"],
36970
36989
  description: "List my organizations",
36971
36990
  requiresWorkspace: false,
36972
- handler: async ({ ctx }) => {
36973
- const result2 = await requireAuth(ctx).apiClient.getMyOrganizations();
36991
+ args: [
36992
+ { name: "page", description: "Page number", default: "1" },
36993
+ {
36994
+ name: "page-size",
36995
+ description: "Entries per page (maximum 100)",
36996
+ default: "25"
36997
+ },
36998
+ { name: "search", description: "Search organization name or slug" }
36999
+ ],
37000
+ handler: async ({ ctx, args }) => {
37001
+ const result2 = await requireAuth(ctx).apiClient.getMyOrganizations({
37002
+ page: Number(args.page ?? 1),
37003
+ pageSize: Number(args["page-size"] ?? 25),
37004
+ search: args.search
37005
+ });
36974
37006
  outputData(result2, ctx, ORG_COLUMNS);
36975
37007
  }
36976
37008
  },
@@ -45642,7 +45674,15 @@ init_errors();
45642
45674
  init_output();
45643
45675
  async function devImportLocalCommand(ctx, workspace) {
45644
45676
  stderr2(`Exporting workspace ${workspace}...`);
45645
- const exportData = await ctx.apiClient.exportWorkspace(workspace);
45677
+ const exportData = await ctx.apiClient.exportWorkspace(
45678
+ workspace,
45679
+ void 0,
45680
+ void 0,
45681
+ void 0,
45682
+ {
45683
+ revisionMode: "active"
45684
+ }
45685
+ );
45646
45686
  stderr2("Export successful!");
45647
45687
  stderr2(` Workflows: ${(exportData.workflows || []).length}`);
45648
45688
  stderr2(` Tasks: ${(exportData.tasks || []).length}`);
@@ -45997,8 +46037,8 @@ var COLUMNS36 = [
45997
46037
  { header: "UUID", getValue: (o) => o.organizationUuid },
45998
46038
  { header: "ROLE", getValue: (o) => o.role || "" }
45999
46039
  ];
46000
- async function organizationsListCommand(ctx) {
46001
- const organizations = await ctx.apiClient.getMyOrganizations();
46040
+ async function organizationsListCommand(ctx, options = {}) {
46041
+ const organizations = await ctx.apiClient.getMyOrganizations(options);
46002
46042
  outputData(organizations, ctx, COLUMNS36);
46003
46043
  }
46004
46044
 
@@ -46305,16 +46345,34 @@ var topLevelCommands = [
46305
46345
  },
46306
46346
  {
46307
46347
  path: ["organizations", "list"],
46308
- description: "List organizations",
46309
- handler: async ({ ctx }) => {
46310
- await organizationsListCommand(requireAuth(ctx));
46348
+ description: "List a searchable page of organizations",
46349
+ args: [
46350
+ { name: "page", description: "Page number", default: "1" },
46351
+ { name: "page-size", description: "Entries per page (maximum 100)", default: "25" },
46352
+ { name: "search", description: "Search organization name or slug" }
46353
+ ],
46354
+ handler: async ({ ctx, args }) => {
46355
+ await organizationsListCommand(requireAuth(ctx), {
46356
+ page: Number(args.page ?? 1),
46357
+ pageSize: Number(args["page-size"] ?? 25),
46358
+ search: args.search
46359
+ });
46311
46360
  }
46312
46361
  },
46313
46362
  {
46314
46363
  path: ["orgs", "list"],
46315
- description: "List organizations",
46316
- handler: async ({ ctx }) => {
46317
- await organizationsListCommand(requireAuth(ctx));
46364
+ description: "List a searchable page of organizations",
46365
+ args: [
46366
+ { name: "page", description: "Page number", default: "1" },
46367
+ { name: "page-size", description: "Entries per page (maximum 100)", default: "25" },
46368
+ { name: "search", description: "Search organization name or slug" }
46369
+ ],
46370
+ handler: async ({ ctx, args }) => {
46371
+ await organizationsListCommand(requireAuth(ctx), {
46372
+ page: Number(args.page ?? 1),
46373
+ pageSize: Number(args["page-size"] ?? 25),
46374
+ search: args.search
46375
+ });
46318
46376
  }
46319
46377
  }
46320
46378
  ];
@@ -46324,7 +46382,7 @@ init_concierge_api();
46324
46382
 
46325
46383
  // package.json
46326
46384
  var package_default = {
46327
- version: "0.47.0"};
46385
+ version: "0.50.0"};
46328
46386
 
46329
46387
  // src/gr.ts
46330
46388
  var VERSION = package_default.version;