@gravity-rail/cli 0.46.0 → 0.49.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-I7BMDNPO.js
3134
+ // ../sdk/dist/chunk-XQTPXOBU.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);
@@ -3665,6 +3601,8 @@ function bindTrackedLinksMethods(target, trackedLinks) {
3665
3601
  target.clearTrackedLinkDestinations = trackedLinks.clearTrackedLinkDestinations.bind(trackedLinks);
3666
3602
  }
3667
3603
  function bindDataTypesMethods(target, dataTypes) {
3604
+ target.getAnonymousFormSchema = dataTypes.getAnonymousFormSchema.bind(dataTypes);
3605
+ target.submitAnonymousForm = dataTypes.submitAnonymousForm.bind(dataTypes);
3668
3606
  target.getDataTypeDraft = dataTypes.getDataTypeDraft.bind(dataTypes);
3669
3607
  target.saveDataTypeDraft = dataTypes.saveDataTypeDraft.bind(dataTypes);
3670
3608
  target.publishDataTypeDraft = dataTypes.publishDataTypeDraft.bind(dataTypes);
@@ -4714,9 +4652,9 @@ function getRevisionState(workflow, revision) {
4714
4652
  };
4715
4653
  }
4716
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;
4717
- var init_chunk_I7BMDNPO = __esm({
4718
- "../sdk/dist/chunk-I7BMDNPO.js"() {
4719
- init_chunk_67QXTQVL();
4655
+ var init_chunk_XQTPXOBU = __esm({
4656
+ "../sdk/dist/chunk-XQTPXOBU.js"() {
4657
+ init_chunk_TGL72KPS();
4720
4658
  init_libphonenumber_js();
4721
4659
  AbilitiesApi = class extends BaseApiClient {
4722
4660
  /**
@@ -5682,18 +5620,13 @@ var init_chunk_I7BMDNPO = __esm({
5682
5620
  }
5683
5621
  return await response.json();
5684
5622
  }
5685
- /** Request a cross-domain authentication token for single sign-on across domains. */
5623
+ /** @deprecated Browser continuity uses top-level /auth/continue navigation. */
5686
5624
  async requestCrossDomainToken() {
5687
- return this.fetch("auth/cross-domain-token", {
5688
- method: "POST"
5689
- });
5625
+ throw new Error("Use top-level /auth/continue navigation. CLI login uses OAuth with PKCE.");
5690
5626
  }
5691
- /** Exchange a cross-domain token for an authenticated session token. */
5692
- async exchangeToken(token) {
5693
- return this.fetch("auth/exchange-token", {
5694
- method: "POST",
5695
- body: JSON.stringify({ token })
5696
- });
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.");
5697
5630
  }
5698
5631
  /** Exchange a global Account login for an opaque org-scoped session handle. */
5699
5632
  async exchangeSession(request) {
@@ -5874,9 +5807,17 @@ var init_chunk_I7BMDNPO = __esm({
5874
5807
  );
5875
5808
  }
5876
5809
  // ===== ORGANIZATION MEMBERSHIP METHODS =====
5877
- /** List all organizations the current account belongs to. */
5878
- async getMyOrganizations() {
5879
- 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}`);
5880
5821
  }
5881
5822
  // ===== CREDENTIAL CHANGE METHODS =====
5882
5823
  /**
@@ -6978,6 +6919,45 @@ var init_chunk_I7BMDNPO = __esm({
6978
6919
  }
6979
6920
  };
6980
6921
  DataTypesApi = class extends BaseApiClient {
6922
+ /** Read an anonymous Form's visitor-writable schema without a Member session. */
6923
+ async getAnonymousFormSchema(wid, formUuid) {
6924
+ return this.fetchPublicAnonymousForm(
6925
+ `w/${encodeURIComponent(wid)}/anonymous-forms/${encodeURIComponent(formUuid)}`
6926
+ );
6927
+ }
6928
+ /** Submit visitor-provided values. No cookie or API credential is sent. */
6929
+ async submitAnonymousForm(wid, formUuid, input2) {
6930
+ return this.fetchPublicAnonymousForm(
6931
+ `w/${encodeURIComponent(wid)}/anonymous-forms/${encodeURIComponent(formUuid)}/submissions`,
6932
+ { method: "POST", body: JSON.stringify(input2) }
6933
+ );
6934
+ }
6935
+ async fetchPublicAnonymousForm(endpoint, options = {}) {
6936
+ const headers2 = new Headers(options.headers);
6937
+ if (options.body !== void 0) headers2.set("Content-Type", "application/json");
6938
+ let response;
6939
+ try {
6940
+ response = await this.fetchFunction(`${this.baseUrl}/api/v2/${endpoint}`, {
6941
+ ...options,
6942
+ credentials: "omit",
6943
+ headers: headers2
6944
+ });
6945
+ } catch {
6946
+ throw new ApiError("Anonymous Form request failed", 0);
6947
+ }
6948
+ if (!response.ok) {
6949
+ let message = `Request failed with status ${response.status}`;
6950
+ try {
6951
+ const body = await response.json();
6952
+ if (typeof body.detail === "string" && body.detail.length > 0) {
6953
+ message = body.detail;
6954
+ }
6955
+ } catch {
6956
+ }
6957
+ throw new ApiError(message, response.status);
6958
+ }
6959
+ return await response.json();
6960
+ }
6981
6961
  /** Read the local Form's draft and optimistic publication counters. */
6982
6962
  async getDataTypeDraft(wid, id) {
6983
6963
  return this.fetch(`w/${wid}/data-types/${id}/schema-draft`);
@@ -8676,14 +8656,7 @@ var init_chunk_I7BMDNPO = __esm({
8676
8656
  }
8677
8657
  const queryString = params.toString();
8678
8658
  const url = queryString ? `inquiries/export/csv?${queryString}` : "inquiries/export/csv";
8679
- const response = await fetch(`${this.baseUrl}/api/v2/${url}`, {
8680
- method: "GET",
8681
- credentials: "include"
8682
- });
8683
- if (!response.ok) {
8684
- const error = await response.json();
8685
- throw new Error(error.detail || "Export failed");
8686
- }
8659
+ const response = await this.fetchRaw(url, { method: "GET" });
8687
8660
  return response.blob();
8688
8661
  }
8689
8662
  };
@@ -9919,8 +9892,12 @@ var init_chunk_I7BMDNPO = __esm({
9919
9892
  * figure — the caps belong to the organization, so `cap - oneWorkspace`
9920
9893
  * describes nothing.
9921
9894
  */
9922
- async getOrgWorkspaceUsage(orgIdOrUuid) {
9923
- 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}`);
9924
9901
  }
9925
9902
  /**
9926
9903
  * List members of an organization.
@@ -10044,8 +10021,14 @@ var init_chunk_I7BMDNPO = __esm({
10044
10021
  * counts. Any org member may call it — members get the workspaces they
10045
10022
  * belong to, org:read holders get all of them.
10046
10023
  */
10047
- async getOrganizationWorkspaceSummaries(orgIdOrUuid) {
10048
- 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
+ );
10049
10032
  }
10050
10033
  /**
10051
10034
  * Workspace-schema aggregates for one card, plus the caller's own member
@@ -13264,7 +13247,8 @@ var init_chunk_I7BMDNPO = __esm({
13264
13247
  /**
13265
13248
  * Classify the prompts of a Workflow's draft revision.
13266
13249
  *
13267
- * 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
13268
13252
  * prompt classifications probably apply. Each call asks the model again.
13269
13253
  */
13270
13254
  async getWorkflowPromptClassifications(wid, workflowId) {
@@ -13901,21 +13885,21 @@ var init_chunk_I7BMDNPO = __esm({
13901
13885
  }
13902
13886
  };
13903
13887
  WorkspacesApi = class extends BaseApiClient {
13904
- /** List all workspaces accessible to the current user. */
13905
- async getWorkspaces() {
13906
- 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)}`);
13907
13891
  }
13908
- /**
13909
- * Compact rows for the workspaces a companion device could enter — the
13910
- * Lantern picker. Filtered by the same admission policy a device
13911
- * credential is gated by, without needing the device credential.
13912
- */
13913
- async getDeviceAdmissibleWorkspaces() {
13914
- 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}`);
13915
13897
  }
13916
- /** List all publicly visible workspaces. */
13917
- async getPublicWorkspaces() {
13918
- 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
+ );
13919
13903
  }
13920
13904
  /** Get a single workspace by ID. */
13921
13905
  async getWorkspace(wid) {
@@ -14198,13 +14182,22 @@ var init_chunk_I7BMDNPO = __esm({
14198
14182
  * @param scope - Export scope ("workflows" for all workflows only). Cannot be combined with workflowId.
14199
14183
  * @param exclude - Comma-separated entity categories to exclude (e.g. "channels")
14200
14184
  */
14201
- async exportWorkspace(wid, workflowId, scope, exclude) {
14185
+ async exportWorkspace(wid, workflowId, scope, exclude, options) {
14202
14186
  const searchParams = new URLSearchParams();
14203
14187
  if (workflowId !== void 0) searchParams.set("workflow_id", String(workflowId));
14204
14188
  if (scope !== void 0) searchParams.set("scope", scope);
14205
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
+ }
14206
14197
  const qs = searchParams.toString();
14207
- 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;
14208
14201
  }
14209
14202
  /** Preview the result of importing workspace configuration without applying changes.
14210
14203
  *
@@ -14263,15 +14256,60 @@ var init_chunk_I7BMDNPO = __esm({
14263
14256
  * target workspace.
14264
14257
  */
14265
14258
  /** Download a workspace export ZIP (``export.json`` + file blobs). */
14266
- async exportWorkspaceZip(wid, workflowId, scope, exclude) {
14259
+ async exportWorkspaceZip(wid, workflowId, scope, exclude, options) {
14267
14260
  const searchParams = new URLSearchParams();
14268
14261
  if (workflowId !== void 0) searchParams.set("workflow_id", String(workflowId));
14269
14262
  if (scope !== void 0) searchParams.set("scope", scope);
14270
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
+ }
14271
14271
  const qs = searchParams.toString();
14272
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
+ }
14273
14287
  return response.arrayBuffer();
14274
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
+ }
14275
14313
  /** Import workspace configuration from exported JSON, or from a ZIP archive.
14276
14314
  * Pass ``archive`` (the ZIP from ``exportWorkspaceZip``) to restore file
14277
14315
  * contents. ``exportData`` may be omitted when the ZIP contains it.
@@ -15480,6 +15518,7 @@ var init_chunk_I7BMDNPO = __esm({
15480
15518
  "getAgents",
15481
15519
  "getAnonymousResolution",
15482
15520
  "getAnonymousFormSubmission",
15521
+ "getAnonymousFormSchema",
15483
15522
  "getAnonymousResolutions",
15484
15523
  "getApiKeys",
15485
15524
  "getArchiveBlockers",
@@ -15865,6 +15904,7 @@ var init_chunk_I7BMDNPO = __esm({
15865
15904
  "linkUnlinkedSalesforceMembersByIdentity",
15866
15905
  "listAbilities",
15867
15906
  "listAnonymousFormSubmissions",
15907
+ "submitAnonymousForm",
15868
15908
  "listAppConnections",
15869
15909
  "listAvailableAppConnections",
15870
15910
  "listInstallations",
@@ -16202,6 +16242,8 @@ var init_chunk_I7BMDNPO = __esm({
16202
16242
  getCelContext;
16203
16243
  validateCelExpression;
16204
16244
  // Data Types API
16245
+ getAnonymousFormSchema;
16246
+ submitAnonymousForm;
16205
16247
  getDataTypes;
16206
16248
  getDataTypeDraft;
16207
16249
  saveDataTypeDraft;
@@ -17492,9 +17534,9 @@ var init_chunk_I7BMDNPO = __esm({
17492
17534
  }
17493
17535
  });
17494
17536
 
17495
- // ../sdk/dist/chunk-72SWNLVD.js
17496
- var init_chunk_72SWNLVD = __esm({
17497
- "../sdk/dist/chunk-72SWNLVD.js"() {
17537
+ // ../sdk/dist/chunk-MMDSZ25F.js
17538
+ var init_chunk_MMDSZ25F = __esm({
17539
+ "../sdk/dist/chunk-MMDSZ25F.js"() {
17498
17540
  }
17499
17541
  });
17500
17542
 
@@ -17549,10 +17591,10 @@ var init_chunk_6KPGCPGW = __esm({
17549
17591
  var SEARCHABLE_EVENT_RULE_SOURCE_FIELDS, ActivityEventType, EntityKind;
17550
17592
  var init_dist = __esm({
17551
17593
  "../sdk/dist/index.js"() {
17552
- init_chunk_I7BMDNPO();
17553
- init_chunk_72SWNLVD();
17594
+ init_chunk_XQTPXOBU();
17595
+ init_chunk_MMDSZ25F();
17554
17596
  init_chunk_6KPGCPGW();
17555
- init_chunk_67QXTQVL();
17597
+ init_chunk_TGL72KPS();
17556
17598
  SEARCHABLE_EVENT_RULE_SOURCE_FIELDS = [
17557
17599
  "taskId",
17558
17600
  "dataTypeId",
@@ -21638,22 +21680,6 @@ var init_output = __esm({
21638
21680
  };
21639
21681
  }
21640
21682
  });
21641
- function extractOrgSessionFromSetCookies(setCookieValues, preferredCookieName) {
21642
- let fallback;
21643
- for (const value of setCookieValues) {
21644
- const nameValue = value.split(";")[0]?.trim() ?? "";
21645
- const eqIdx = nameValue.indexOf("=");
21646
- if (eqIdx === -1) continue;
21647
- const name = nameValue.slice(0, eqIdx).trim();
21648
- const credentialValue = nameValue.slice(eqIdx + 1).trim() || void 0;
21649
- if (!credentialValue) continue;
21650
- if (name === preferredCookieName) return credentialValue;
21651
- if (!fallback && (name.startsWith("orgToken") || name.startsWith("orgSession"))) {
21652
- fallback = credentialValue;
21653
- }
21654
- }
21655
- return fallback;
21656
- }
21657
21683
  async function tryDirectJoin(apiUrl, accessToken, orgAuthInfo) {
21658
21684
  const response = await fetch(`${apiUrl}/api/v2/o/${orgAuthInfo.orgUuid}/join`, {
21659
21685
  method: "POST",
@@ -21669,16 +21695,16 @@ async function tryDirectJoin(apiUrl, accessToken, orgAuthInfo) {
21669
21695
  if (!response.ok) {
21670
21696
  throw new Error(`Org join failed (HTTP ${response.status})`);
21671
21697
  }
21672
- const rawHeaders = response.headers;
21673
- const setCookies = rawHeaders.getSetCookie?.() ?? (rawHeaders.get("set-cookie") ? [rawHeaders.get("set-cookie")] : []);
21674
- if (setCookies.length === 0) {
21675
- 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");
21676
21703
  }
21677
- const orgSession = extractOrgSessionFromSetCookies(setCookies, orgAuthInfo.cookieName);
21678
- if (!orgSession) {
21679
- 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");
21680
21706
  }
21681
- return orgSession;
21707
+ return body.orgSession;
21682
21708
  }
21683
21709
  function isAllowedAuthUrl(url, apiUrl, frontendUrl) {
21684
21710
  try {
@@ -21719,62 +21745,31 @@ function isHeadless() {
21719
21745
  }
21720
21746
  return false;
21721
21747
  }
21722
- function startOrgSessionCapture(expectedState, expectedOrgUuid, allowedOrigin) {
21748
+ function startOrgSessionCapture(expectedState, expectedOrgUuid, _allowedOrigin) {
21723
21749
  let resolveSession;
21724
21750
  let rejectSession;
21725
21751
  const session = new Promise((resolve3, reject) => {
21726
21752
  resolveSession = resolve3;
21727
21753
  rejectSession = reject;
21728
21754
  });
21729
- const applyCors = (req, res) => {
21730
- if (req.headers.origin && req.headers.origin === allowedOrigin) {
21731
- res.setHeader("Access-Control-Allow-Origin", allowedOrigin);
21732
- res.setHeader("Vary", "Origin");
21733
- }
21734
- res.setHeader("Access-Control-Allow-Methods", "POST, OPTIONS");
21735
- res.setHeader("Access-Control-Allow-Headers", "Content-Type");
21736
- };
21737
21755
  const server = createServer((req, res) => {
21738
- applyCors(req, res);
21739
- if (req.method === "OPTIONS") {
21740
- res.setHeader("Access-Control-Allow-Private-Network", "true");
21741
- 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);
21742
21760
  res.end();
21743
21761
  return;
21744
21762
  }
21745
- if (req.method !== "POST") {
21746
- res.writeHead(405);
21747
- 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");
21748
21768
  return;
21749
21769
  }
21750
- let body = "";
21751
- let tooLarge = false;
21752
- req.on("data", (chunk) => {
21753
- body += chunk;
21754
- if (body.length > 16 * 1024) {
21755
- tooLarge = true;
21756
- req.destroy();
21757
- }
21758
- });
21759
- req.on("end", () => {
21760
- if (tooLarge) return;
21761
- let capturedSession;
21762
- try {
21763
- const payload = JSON.parse(body);
21764
- if (typeof payload.org_session === "string" && payload.org_session.length > 0 && payload.state === expectedState && payload.org_uuid === expectedOrgUuid) {
21765
- capturedSession = payload.org_session;
21766
- }
21767
- } catch {
21768
- }
21769
- if (capturedSession) {
21770
- res.writeHead(200, { "Content-Type": "application/json" });
21771
- res.end('{"ok":true}');
21772
- resolveSession(capturedSession);
21773
- } else {
21774
- res.writeHead(400, { "Content-Type": "application/json" });
21775
- res.end('{"ok":false}');
21776
- }
21777
- });
21770
+ res.writeHead(200, { "Content-Type": "text/plain" });
21771
+ res.end("Return to the terminal to finish sign-in.");
21772
+ resolveSession(code);
21778
21773
  });
21779
21774
  let resolveReady;
21780
21775
  let rejectReady;
@@ -21806,22 +21801,30 @@ function startOrgSessionCapture(expectedState, expectedOrgUuid, allowedOrigin) {
21806
21801
  };
21807
21802
  return { ready, session, close };
21808
21803
  }
21809
- function buildStepUpUrl(authUrl, orgUuid, port, state) {
21804
+ function buildStepUpUrl(authUrl, orgUuid, port, state, challenge) {
21810
21805
  const url = new URL(authUrl);
21811
- const bridgeQuery = new URLSearchParams({ org: orgUuid, port: String(port), state });
21806
+ const bridgeQuery = new URLSearchParams({ org: orgUuid, port: String(port), state, challenge });
21812
21807
  url.searchParams.set("return_to", `${CLI_ORG_AUTH_BRIDGE_PATH}?${bridgeQuery.toString()}`);
21813
21808
  return url.toString();
21814
21809
  }
21815
21810
  function newStateNonce() {
21816
21811
  return randomBytes(16).toString("hex");
21817
21812
  }
21818
- async function stepUpViaBrowser(orgAuthInfo) {
21813
+ async function stepUpViaBrowser(orgAuthInfo, apiUrl, accessToken) {
21819
21814
  const state = newStateNonce();
21820
- const allowedOrigin = new URL(orgAuthInfo.authUrl).origin;
21821
- 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);
21822
21819
  try {
21823
21820
  const port = await capture.ready;
21824
- 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
+ );
21825
21828
  stderr2(`
21826
21829
  This workspace requires organization SSO authentication.`);
21827
21830
  stderr2(`Opening browser to complete sign-in...`);
@@ -21829,7 +21832,19 @@ This workspace requires organization SSO authentication.`);
21829
21832
  `);
21830
21833
  stderr2(`If the browser does not open, visit the URL above manually.`);
21831
21834
  openBrowser2(stepUpUrl);
21832
- 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;
21833
21848
  } finally {
21834
21849
  capture.close();
21835
21850
  }
@@ -21875,7 +21890,7 @@ function registerOrgAuthHandler(apiClient, apiUrl, accessToken, orgAuthCtx) {
21875
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.`
21876
21891
  );
21877
21892
  }
21878
- const session = await stepUpViaBrowser(orgAuthInfo);
21893
+ const session = await stepUpViaBrowser(orgAuthInfo, apiUrl, accessToken);
21879
21894
  adopt(session);
21880
21895
  });
21881
21896
  }
@@ -24040,7 +24055,7 @@ var chatsDomain = {
24040
24055
 
24041
24056
  // ../sdk/dist/helpers.js
24042
24057
  init_chunk_6KPGCPGW();
24043
- init_chunk_67QXTQVL();
24058
+ init_chunk_TGL72KPS();
24044
24059
  new TextEncoder();
24045
24060
  var WORKSPACE_EXPORT_JSON_MEMBER = "export.json";
24046
24061
  var MAX_EXPORT_JSON_BYTES = 8 * 1024 * 1024;
@@ -26339,7 +26354,9 @@ async function exportTemplateArchive(client3, templateUuid) {
26339
26354
  return withTransferProgress(
26340
26355
  "template archive",
26341
26356
  templateUuid,
26342
- () => 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
+ })
26343
26360
  );
26344
26361
  }
26345
26362
  async function readBindingsFile(filePath, targets) {
@@ -26673,26 +26690,27 @@ var workspacesDomain = {
26673
26690
  }),
26674
26691
  {
26675
26692
  path: ["workspaces", "list"],
26676
- description: "List workspaces",
26693
+ description: "List a searchable page of workspaces",
26677
26694
  requiresWorkspace: false,
26678
26695
  columns: COLUMNS6,
26679
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" },
26680
26700
  {
26681
26701
  name: "org",
26682
26702
  aliases: ["org-uuid"],
26683
- description: "Only workspaces in this organization (UUID). Filters the list client-side on organizationUuid."
26703
+ description: "Only workspaces in this organization (UUID)."
26684
26704
  }
26685
26705
  ],
26686
26706
  examples: ["gr workspaces list --org <org-uuid> -o json"],
26687
26707
  handler: async ({ ctx, args }) => {
26688
- const result2 = await requireAuth(ctx).apiClient.getWorkspaces();
26689
- const org = typeof args.org === "string" ? args.org.trim().toLowerCase() : "";
26690
- const items = org ? unwrapItems(result2).filter(
26691
- (ws) => String(
26692
- ws.organizationUuid ?? ""
26693
- ).toLowerCase() === org
26694
- ) : result2;
26695
- 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);
26696
26714
  }
26697
26715
  },
26698
26716
  // Custom get that accepts either --id or -w as the workspace identifier
@@ -26828,6 +26846,14 @@ Provisioning started. Watch it come up with:
26828
26846
  name: "workflow-id",
26829
26847
  description: "Export a single workflow by ID"
26830
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
+ },
26831
26857
  {
26832
26858
  name: "exclude",
26833
26859
  description: 'Comma-separated categories to exclude (e.g. "channels")'
@@ -26851,6 +26877,15 @@ Provisioning started. Watch it come up with:
26851
26877
  handler: async ({ ctx, workspace, args }) => {
26852
26878
  const scope = args["scope"];
26853
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
+ }
26854
26889
  const exclude = args["exclude"];
26855
26890
  const outputPath = args["output"];
26856
26891
  const formatArg = args["format"];
@@ -26861,6 +26896,12 @@ Provisioning started. Watch it come up with:
26861
26896
  if (scope && workflowId !== void 0) {
26862
26897
  throw new CLIError("Cannot specify both --scope and --workflow-id");
26863
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 };
26864
26905
  if (scope && scope !== "workflows") {
26865
26906
  throw new CLIError('--scope must be "workflows"');
26866
26907
  }
@@ -26877,7 +26918,8 @@ Provisioning started. Watch it come up with:
26877
26918
  workspace,
26878
26919
  workflowId,
26879
26920
  scope,
26880
- exclude
26921
+ exclude,
26922
+ revisionOptions
26881
26923
  );
26882
26924
  await writeFile(outputPath, Buffer.from(zip));
26883
26925
  process.stdout.write(`Saved ZIP export to ${outputPath}
@@ -26888,7 +26930,8 @@ Provisioning started. Watch it come up with:
26888
26930
  workspace,
26889
26931
  workflowId,
26890
26932
  scope,
26891
- exclude
26933
+ exclude,
26934
+ revisionOptions
26892
26935
  );
26893
26936
  if (outputPath) {
26894
26937
  await writeFile(outputPath, `${JSON.stringify(result2, null, 2)}
@@ -28027,11 +28070,19 @@ Each entry in "fields" (a schema field)
28027
28070
  required (bool) Whether the field must be supplied
28028
28071
  description (string) Optional help text
28029
28072
  options (array) For fieldType "enum": [{"label":"\u2026","value":"\u2026"}, \u2026]
28030
- 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.
28031
28076
 
28032
28077
  Valid fieldType values
28033
28078
  text, longtext, email, phone, number, integer, boolean, date, datetime,
28034
- 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.
28035
28086
 
28036
28087
  Example
28037
28088
  gr data-types create -w $WID --allow-write --data '{"name":"Patient","fields":[
@@ -28340,8 +28391,15 @@ var ACTION_PARAM_HINTS = {
28340
28391
  },
28341
28392
  "assistant:message": {
28342
28393
  summary: "inject an assistant message into the chat",
28343
- shape: ['{"message":"Welcome! \u2026","suggestions":["Yes","No"],"waitForResponse":<bool>}'],
28344
- 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
+ ]
28345
28403
  },
28346
28404
  "chat:pause": {
28347
28405
  summary: "pause the chat for a human response",
@@ -33871,7 +33929,7 @@ var NO_UUID_LOOKUP = /* @__PURE__ */ new Set([
33871
33929
  ]);
33872
33930
  var HYDRATORS = {
33873
33931
  workspace: async ({ client: client3 }, ref) => (await client3.getWorkspace(ref.uuid)).name,
33874
- org: async ({ orgNames }, ref) => (await orgNames()).get(ref.uuid),
33932
+ org: async ({ orgNames }, ref) => (await orgNames(ref.uuid)).get(ref.uuid),
33875
33933
  workflow: async ({ client: client3 }, ref) => {
33876
33934
  const detail = await client3.getWorkflow(requireWorkspace(ref), ref.uuid);
33877
33935
  return detail.workflow?.name;
@@ -33933,7 +33991,7 @@ var ActivityRefResolver = class {
33933
33991
  inFlight = /* @__PURE__ */ new Map();
33934
33992
  fetches = 0;
33935
33993
  /** The org membership listing, fetched at most once per invocation. */
33936
- orgNamesPromise;
33994
+ orgNamesPromises = /* @__PURE__ */ new Map();
33937
33995
  /** How many API calls hydration actually made. `--ids` must keep this at 0. */
33938
33996
  get fetchCount() {
33939
33997
  return this.fetches;
@@ -34115,21 +34173,24 @@ var ActivityRefResolver = class {
34115
34173
  return resolution.label;
34116
34174
  }
34117
34175
  /**
34118
- * The caller's org memberships as uuid → name, fetched once.
34176
+ * The caller's matching organization membership, fetched once per UUID.
34119
34177
  *
34120
34178
  * The promise is cached, not its value, so N org refs resolving at once
34121
34179
  * share one request — the same rule the ref cache follows.
34122
34180
  */
34123
- orgNames() {
34124
- 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(
34125
34185
  (memberships) => new Map(
34126
- memberships.map((membership) => [
34186
+ memberships.items.map((membership) => [
34127
34187
  membership.organizationUuid,
34128
34188
  membership.organizationName
34129
34189
  ])
34130
34190
  )
34131
34191
  );
34132
- return this.orgNamesPromise;
34192
+ this.orgNamesPromises.set(uuid, pending);
34193
+ return pending;
34133
34194
  }
34134
34195
  async lookup(ref) {
34135
34196
  const hydrator = HYDRATORS[ref.kind];
@@ -34142,7 +34203,10 @@ var ActivityRefResolver = class {
34142
34203
  }
34143
34204
  this.fetches += 1;
34144
34205
  try {
34145
- 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
+ );
34146
34210
  if (!name) return { label: bareLabel(ref), status: "unresolved" };
34147
34211
  return { label: name, status: "resolved" };
34148
34212
  } catch (error) {
@@ -36924,8 +36988,21 @@ var orgDomain = {
36924
36988
  path: ["org", "list"],
36925
36989
  description: "List my organizations",
36926
36990
  requiresWorkspace: false,
36927
- handler: async ({ ctx }) => {
36928
- 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
+ });
36929
37006
  outputData(result2, ctx, ORG_COLUMNS);
36930
37007
  }
36931
37008
  },
@@ -45597,7 +45674,15 @@ init_errors();
45597
45674
  init_output();
45598
45675
  async function devImportLocalCommand(ctx, workspace) {
45599
45676
  stderr2(`Exporting workspace ${workspace}...`);
45600
- 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
+ );
45601
45686
  stderr2("Export successful!");
45602
45687
  stderr2(` Workflows: ${(exportData.workflows || []).length}`);
45603
45688
  stderr2(` Tasks: ${(exportData.tasks || []).length}`);
@@ -45952,8 +46037,8 @@ var COLUMNS36 = [
45952
46037
  { header: "UUID", getValue: (o) => o.organizationUuid },
45953
46038
  { header: "ROLE", getValue: (o) => o.role || "" }
45954
46039
  ];
45955
- async function organizationsListCommand(ctx) {
45956
- const organizations = await ctx.apiClient.getMyOrganizations();
46040
+ async function organizationsListCommand(ctx, options = {}) {
46041
+ const organizations = await ctx.apiClient.getMyOrganizations(options);
45957
46042
  outputData(organizations, ctx, COLUMNS36);
45958
46043
  }
45959
46044
 
@@ -46260,16 +46345,34 @@ var topLevelCommands = [
46260
46345
  },
46261
46346
  {
46262
46347
  path: ["organizations", "list"],
46263
- description: "List organizations",
46264
- handler: async ({ ctx }) => {
46265
- 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
+ });
46266
46360
  }
46267
46361
  },
46268
46362
  {
46269
46363
  path: ["orgs", "list"],
46270
- description: "List organizations",
46271
- handler: async ({ ctx }) => {
46272
- 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
+ });
46273
46376
  }
46274
46377
  }
46275
46378
  ];
@@ -46279,7 +46382,7 @@ init_concierge_api();
46279
46382
 
46280
46383
  // package.json
46281
46384
  var package_default = {
46282
- version: "0.46.0"};
46385
+ version: "0.49.0"};
46283
46386
 
46284
46387
  // src/gr.ts
46285
46388
  var VERSION = package_default.version;