primitive-admin 1.1.0 → 1.2.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/README.md +14 -13
  2. package/assets/skill/skills/primitive-platform/SKILL.md +6 -0
  3. package/dist/src/commands/collections.js +20 -17
  4. package/dist/src/commands/collections.js.map +1 -1
  5. package/dist/src/commands/connections.js +1 -5
  6. package/dist/src/commands/connections.js.map +1 -1
  7. package/dist/src/commands/database-types.js +13 -313
  8. package/dist/src/commands/database-types.js.map +1 -1
  9. package/dist/src/commands/databases.js +7 -128
  10. package/dist/src/commands/databases.js.map +1 -1
  11. package/dist/src/commands/groups.js +16 -0
  12. package/dist/src/commands/groups.js.map +1 -1
  13. package/dist/src/commands/llm.js +9 -6
  14. package/dist/src/commands/llm.js.map +1 -1
  15. package/dist/src/commands/sessions.js +3 -8
  16. package/dist/src/commands/sessions.js.map +1 -1
  17. package/dist/src/commands/settings.d.ts +18 -0
  18. package/dist/src/commands/settings.js +54 -0
  19. package/dist/src/commands/settings.js.map +1 -0
  20. package/dist/src/commands/sync.d.ts +77 -7
  21. package/dist/src/commands/sync.js +368 -198
  22. package/dist/src/commands/sync.js.map +1 -1
  23. package/dist/src/commands/tokens.js +1 -6
  24. package/dist/src/commands/tokens.js.map +1 -1
  25. package/dist/src/commands/workflows.js +3 -3
  26. package/dist/src/commands/workflows.js.map +1 -1
  27. package/dist/src/lib/api-client.d.ts +3 -70
  28. package/dist/src/lib/api-client.js +20 -106
  29. package/dist/src/lib/api-client.js.map +1 -1
  30. package/dist/src/lib/app-match-guard.d.ts +44 -0
  31. package/dist/src/lib/app-match-guard.js +72 -0
  32. package/dist/src/lib/app-match-guard.js.map +1 -0
  33. package/dist/src/lib/collection-export.d.ts +37 -9
  34. package/dist/src/lib/collection-export.js +48 -12
  35. package/dist/src/lib/collection-export.js.map +1 -1
  36. package/dist/src/lib/config-object-descriptor.js +2 -3
  37. package/dist/src/lib/config-object-descriptor.js.map +1 -1
  38. package/dist/src/lib/function-triggers.d.ts +66 -0
  39. package/dist/src/lib/function-triggers.js +285 -0
  40. package/dist/src/lib/function-triggers.js.map +1 -0
  41. package/dist/src/lib/generated-allowlist.js +0 -1
  42. package/dist/src/lib/generated-allowlist.js.map +1 -1
  43. package/dist/src/lib/generated-config-surfaces.d.ts +4 -2
  44. package/dist/src/lib/generated-config-surfaces.js +138 -68
  45. package/dist/src/lib/generated-config-surfaces.js.map +1 -1
  46. package/dist/src/lib/generated-sdk-types.d.ts +1 -1
  47. package/dist/src/lib/generated-sdk-types.js +1 -1
  48. package/dist/src/lib/generated-sdk-types.js.map +1 -1
  49. package/dist/src/lib/generated-workflow-model-fields.d.ts +20 -0
  50. package/dist/src/lib/generated-workflow-model-fields.js +53 -0
  51. package/dist/src/lib/generated-workflow-model-fields.js.map +1 -0
  52. package/dist/src/lib/google-client-secret-status.d.ts +35 -0
  53. package/dist/src/lib/google-client-secret-status.js +56 -0
  54. package/dist/src/lib/google-client-secret-status.js.map +1 -0
  55. package/dist/src/lib/log-inspection.d.ts +1 -6
  56. package/dist/src/lib/log-inspection.js +5 -7
  57. package/dist/src/lib/log-inspection.js.map +1 -1
  58. package/dist/src/lib/migration-nag.d.ts +2 -2
  59. package/dist/src/lib/migration-nag.js +4 -3
  60. package/dist/src/lib/migration-nag.js.map +1 -1
  61. package/dist/src/lib/paginate.d.ts +8 -24
  62. package/dist/src/lib/paginate.js +8 -21
  63. package/dist/src/lib/paginate.js.map +1 -1
  64. package/dist/src/lib/sync-dir-selector.d.ts +1 -1
  65. package/dist/src/lib/sync-dir-selector.js +1 -1
  66. package/dist/src/lib/toml-database-config.js +2 -2
  67. package/dist/src/lib/toml-database-config.js.map +1 -1
  68. package/dist/src/lib/workflow-field-descriptor.d.ts +91 -0
  69. package/dist/src/lib/workflow-field-descriptor.js +153 -0
  70. package/dist/src/lib/workflow-field-descriptor.js.map +1 -0
  71. package/package.json +2 -2
@@ -655,8 +655,6 @@ export declare class ApiClient {
655
655
  items: any[];
656
656
  nextCursor?: string;
657
657
  hasMore?: boolean;
658
- /** @deprecated Alias of `nextCursor` (#1316). */
659
- cursor?: string;
660
658
  }>;
661
659
  createInvitation(appId: string, data: {
662
660
  email: string;
@@ -685,8 +683,6 @@ export declare class ApiClient {
685
683
  cursor?: string;
686
684
  }): Promise<{
687
685
  items: any[];
688
- /** @deprecated Read `items`; `grants` is a legacy alias of it (#1982). */
689
- grants: any[];
690
686
  nextCursor?: string | null;
691
687
  hasMore?: boolean;
692
688
  }>;
@@ -968,8 +964,6 @@ export declare class ApiClient {
968
964
  items: any[];
969
965
  hasMore?: boolean;
970
966
  nextCursor?: string | null;
971
- /** @deprecated Alias of `nextCursor` (#1316). */
972
- cursor?: string | null;
973
967
  }>;
974
968
  /**
975
969
  * List the live connections the server believes exist for exactly one of a
@@ -1354,8 +1348,6 @@ export declare class ApiClient {
1354
1348
  items: any[];
1355
1349
  hasMore?: boolean;
1356
1350
  nextCursor?: string | null;
1357
- /** @deprecated Alias of `nextCursor` (#1316). */
1358
- cursor?: string | null;
1359
1351
  /** #1969 — opaque follow checkpoint; present on `follow=true` responses. */
1360
1352
  resumeAfter?: string;
1361
1353
  /**
@@ -1380,8 +1372,6 @@ export declare class ApiClient {
1380
1372
  items: any[];
1381
1373
  hasMore?: boolean;
1382
1374
  nextCursor?: string | null;
1383
- /** @deprecated Alias of `nextCursor` (#1316). */
1384
- cursor?: string | null;
1385
1375
  /** #2237 — index rows examined; filtered reads only, `undefined` if unknown. */
1386
1376
  scanned?: number;
1387
1377
  }>;
@@ -1490,12 +1480,8 @@ export declare class ApiClient {
1490
1480
  cursor?: string;
1491
1481
  }): Promise<{
1492
1482
  items: any[];
1493
- /** @deprecated Read `items`; `admins` is a legacy alias of it (#1982). */
1494
- admins: any[];
1495
1483
  hasMore?: boolean;
1496
1484
  nextCursor: string | null;
1497
- /** @deprecated Read `nextCursor`; `cursor` is a legacy alias of it (#1316, #1982). */
1498
- cursor: string | null;
1499
1485
  }>;
1500
1486
  searchAdminByEmail(email: string): Promise<any>;
1501
1487
  getAdminApps(email: string): Promise<any>;
@@ -1664,51 +1650,14 @@ export declare class ApiClient {
1664
1650
  createDatabase(appId: string, data: {
1665
1651
  title: string;
1666
1652
  databaseType?: string;
1667
- metadata?: Record<string, any> | string;
1668
1653
  initialMetadata?: Record<string, Record<string, unknown>>;
1669
1654
  }): Promise<any>;
1670
1655
  getDatabase(appId: string, databaseId: string): Promise<any>;
1671
1656
  updateDatabase(appId: string, databaseId: string, data: Record<string, any>): Promise<any>;
1672
1657
  deleteDatabase(appId: string, databaseId: string): Promise<void>;
1673
- /**
1674
- * Read a database's CEL context dict.
1675
- *
1676
- * The HTTP path stays `/metadata` because the wire field name is still
1677
- * `metadata`; only the client/CLI-facing helper names were reframed.
1678
- *
1679
- * @deprecated Use resource metadata categories instead (`primitive metadata
1680
- * get database <id> <category>`, #1420, #1815).
1681
- */
1682
- getDatabaseCelContext(appId: string, databaseId: string): Promise<any>;
1683
- /**
1684
- * Update a database's CEL context dict (merge with existing).
1685
- *
1686
- * @deprecated Use resource metadata categories instead (`primitive metadata
1687
- * set database <id> <category>`, #1420, #1815).
1688
- */
1689
- updateDatabaseCelContext(appId: string, databaseId: string, celContext: Record<string, any>): Promise<any>;
1690
- /**
1691
- * @deprecated Database CEL context is deprecated; use resource metadata
1692
- * categories instead (`primitive metadata get database <id> <category>`,
1693
- * #1420, #1815).
1694
- */
1695
- getDatabaseMetadata(appId: string, databaseId: string): Promise<any>;
1696
- /**
1697
- * @deprecated Database CEL context is deprecated; use resource metadata
1698
- * categories instead (`primitive metadata set database <id> <category>`,
1699
- * #1420, #1815).
1700
- */
1701
- updateDatabaseMetadata(appId: string, databaseId: string, metadata: Record<string, any>): Promise<any>;
1702
1658
  listDatabasePermissions(appId: string, databaseId: string): Promise<any[]>;
1703
1659
  addDatabaseManager(appId: string, databaseId: string, userId: string): Promise<any>;
1704
1660
  removeDatabaseManager(appId: string, databaseId: string, userId: string): Promise<any>;
1705
- /** @deprecated Use {@link addDatabaseManager} instead. */
1706
- grantDatabasePermission(appId: string, databaseId: string, data: {
1707
- userId: string;
1708
- permission: "manager";
1709
- }): Promise<any>;
1710
- /** @deprecated Use {@link removeDatabaseManager} instead. */
1711
- revokeDatabasePermission(appId: string, databaseId: string, userId: string): Promise<any>;
1712
1661
  listDatabaseModels(appId: string, databaseId: string): Promise<any>;
1713
1662
  describeDatabaseModel(appId: string, databaseId: string, modelName: string): Promise<any>;
1714
1663
  /**
@@ -1924,14 +1873,13 @@ export declare class ApiClient {
1924
1873
  items: any[];
1925
1874
  nextCursor?: string;
1926
1875
  hasMore?: boolean;
1927
- /** @deprecated Alias of `nextCursor` (#1316). */
1928
- cursor?: string;
1929
1876
  }>;
1930
1877
  createGroup(appId: string, data: {
1931
1878
  groupType: string;
1932
1879
  groupId?: string;
1933
1880
  name: string;
1934
1881
  description?: string;
1882
+ initialMetadata?: Record<string, Record<string, unknown>>;
1935
1883
  }): Promise<any>;
1936
1884
  getGroup(appId: string, groupType: string, groupId: string): Promise<any>;
1937
1885
  updateGroup(appId: string, groupType: string, groupId: string, data: {
@@ -1955,8 +1903,6 @@ export declare class ApiClient {
1955
1903
  items: any[];
1956
1904
  nextCursor?: string;
1957
1905
  hasMore?: boolean;
1958
- /** @deprecated Alias of `nextCursor` (#1316). */
1959
- cursor?: string;
1960
1906
  }>;
1961
1907
  addGroupMember(appId: string, groupType: string, groupId: string, data: {
1962
1908
  userId: string;
@@ -1991,12 +1937,10 @@ export declare class ApiClient {
1991
1937
  name: string;
1992
1938
  description?: string;
1993
1939
  /**
1994
- * Which rule set governs the collection, and which context it belongs
1995
- * to. Both are immutable after creation, so a migration has to send them
1996
- * with the create or never (#3643).
1940
+ * Which rule set governs the collection. Immutable after creation, so a
1941
+ * migration has to send it with the create or never (#3643).
1997
1942
  */
1998
1943
  collectionType?: string;
1999
- contextId?: string;
2000
1944
  initialMetadata?: Record<string, Record<string, unknown>>;
2001
1945
  /**
2002
1946
  * The app user to create the collection FOR (#3641). Honored only for
@@ -2200,9 +2144,6 @@ export declare class ApiClient {
2200
2144
  * through the caller's document permission (reader+) or the app-admin arm.
2201
2145
  * Returns the unified `{ items, hasMore, nextCursor? }` envelope. The cursor
2202
2146
  * is an opaque token — feed `nextCursor` back as `cursor` for the next page.
2203
- * The server also dual-emits a deprecated `cursor` alias (#1316); the
2204
- * normalizer drops it so CLI output is already on `nextCursor` when #1982
2205
- * removes it.
2206
2147
  */
2207
2148
  queryDocumentRecords(appId: string, documentId: string, modelName: string, queryOptions?: {
2208
2149
  filter?: Record<string, any>;
@@ -2449,9 +2390,6 @@ export declare class ApiClient {
2449
2390
  * of them". `paginateAll` carries the repeat-cursor and max-page guards, so
2450
2391
  * a server handing out a non-advancing cursor fails loudly instead of
2451
2392
  * looping forever.
2452
- *
2453
- * Tolerant of a pre-contract server, which answers with a bare
2454
- * `{ documents }` array and no cursor: that reads as a single page.
2455
2393
  */
2456
2394
  listAdminDocuments(appId: string, userId: string): Promise<any[]>;
2457
2395
  /**
@@ -2461,9 +2399,6 @@ export declare class ApiClient {
2461
2399
  * `--limit`/`--cursor` asked for, with the server's own page boundary
2462
2400
  * beside it. `documents export-all`, which really does mean every document,
2463
2401
  * keeps the walking `listAdminDocuments()` above.
2464
- *
2465
- * Tolerant of a pre-contract server, which answers with a bare
2466
- * `{ documents }` array and no cursor: that reads as a single page.
2467
2402
  */
2468
2403
  listAdminDocumentsPage(appId: string, userId: string, options?: {
2469
2404
  limit?: number;
@@ -2533,8 +2468,6 @@ export declare class ApiClient {
2533
2468
  items: any[];
2534
2469
  nextCursor?: string;
2535
2470
  hasMore?: boolean;
2536
- /** @deprecated Alias of `nextCursor` (#1316). */
2537
- cursor?: string;
2538
2471
  }>;
2539
2472
  uploadBucketBlob(appId: string, bucketIdOrKey: string, data: Buffer, meta: {
2540
2473
  filename: string;
@@ -412,13 +412,10 @@ export class ApiClient {
412
412
  qs.set("cursor", params.cursor);
413
413
  const q = qs.toString();
414
414
  const resp = await this.get(`/admin/api/admins/me/apps${q ? `?${q}` : ""}`);
415
- // The server now emits `items` with `apps` as a deprecation-window alias
416
- // (#1316). Read `items` first so listings keep working once the alias is
417
- // removed; fall back to the legacy `apps` key meanwhile.
418
415
  return {
419
- items: resp?.items ?? (Array.isArray(resp?.apps) ? resp.apps : []),
416
+ items: resp?.items ?? [],
420
417
  hasMore: resp?.hasMore,
421
- nextCursor: resp?.nextCursor ?? resp?.cursor ?? null,
418
+ nextCursor: resp?.nextCursor ?? null,
422
419
  };
423
420
  }
424
421
  /**
@@ -455,15 +452,13 @@ export class ApiClient {
455
452
  if (cursor)
456
453
  qs.set("cursor", cursor);
457
454
  const resp = await this.get(`/admin/api/apps?${qs.toString()}`);
458
- // `items` first, with the `apps` alias (#1316) as the fallback,
459
- // exactly as `listApps()` reads its own envelope.
460
- const rows = resp.items ?? (Array.isArray(resp.apps) ? resp.apps : []);
455
+ const rows = resp.items ?? [];
461
456
  return {
462
457
  items: rows.map((row) => ({
463
458
  appId: String(row.appId ?? row.id ?? ""),
464
459
  name: String(row.name ?? ""),
465
460
  })),
466
- nextCursor: resp.nextCursor ?? resp.cursor,
461
+ nextCursor: resp.nextCursor,
467
462
  };
468
463
  });
469
464
  return drainAppsUntilConverged(drainOnce);
@@ -596,14 +591,11 @@ export class ApiClient {
596
591
  // ============================================
597
592
  async listInvitations(appId, params) {
598
593
  const result = await this.get(`/app/${appId}/api/invitations`, params);
599
- // #1316: prefer `nextCursor`; fall back to the deprecated `cursor` alias
600
- // so the CLI keeps paginating against pre-#1316 servers.
601
- const nextCursor = result?.nextCursor ?? result?.cursor;
594
+ const nextCursor = result?.nextCursor;
602
595
  return {
603
596
  items: result?.items ?? [],
604
597
  nextCursor,
605
598
  hasMore: result?.hasMore ?? nextCursor != null,
606
- cursor: nextCursor,
607
599
  };
608
600
  }
609
601
  async createInvitation(appId, data) {
@@ -633,12 +625,9 @@ export class ApiClient {
633
625
  // ============================================
634
626
  async listDeferredGrants(appId, params) {
635
627
  const result = await this.get(`/app/${appId}/api/deferred-grants`, params);
636
- // `items` is the key every list envelope is built from (#3646, #1982);
637
- // `grants` is the deprecated legacy name, read only as a fallback.
638
- const items = result?.items ?? result?.grants ?? [];
628
+ const items = result?.items ?? [];
639
629
  return {
640
630
  items,
641
- grants: items,
642
631
  nextCursor: result?.nextCursor ?? null,
643
632
  hasMore: result?.hasMore,
644
633
  };
@@ -1020,13 +1009,11 @@ export class ApiClient {
1020
1009
  }
1021
1010
  async listWebhookEvents(appId, webhookId, params) {
1022
1011
  const result = await this.get(`/admin/api/apps/${appId}/webhooks/${webhookId}/events`, params);
1023
- // #1316: prefer `nextCursor`; fall back to the deprecated `cursor` alias.
1024
- const nextCursor = result?.nextCursor ?? result?.cursor ?? null;
1012
+ const nextCursor = result?.nextCursor ?? null;
1025
1013
  return {
1026
1014
  items: result?.items ?? [],
1027
1015
  hasMore: result?.hasMore ?? !!nextCursor,
1028
1016
  nextCursor,
1029
- cursor: nextCursor,
1030
1017
  };
1031
1018
  }
1032
1019
  // ============================================
@@ -1576,13 +1563,11 @@ export class ApiClient {
1576
1563
  }
1577
1564
  async listWorkflowRuns(appId, workflowId, params) {
1578
1565
  const result = await this.get(`/admin/api/apps/${appId}/workflows/${workflowId}/runs`, params);
1579
- // #1316: prefer `nextCursor`; fall back to the deprecated `cursor` alias.
1580
- const nextCursor = result?.nextCursor ?? result?.cursor ?? null;
1566
+ const nextCursor = result?.nextCursor ?? null;
1581
1567
  return {
1582
1568
  items: result?.items ?? [],
1583
1569
  hasMore: result?.hasMore,
1584
1570
  nextCursor,
1585
- cursor: nextCursor,
1586
1571
  resumeAfter: result?.resumeAfter,
1587
1572
  scanned: typeof result?.scanned === "number" ? result.scanned : undefined,
1588
1573
  };
@@ -1594,12 +1579,11 @@ export class ApiClient {
1594
1579
  */
1595
1580
  async listUserWorkflowRuns(appId, userId, params) {
1596
1581
  const result = await this.get(`/admin/api/apps/${appId}/users/${encodeURIComponent(userId)}/workflow-runs`, params);
1597
- const nextCursor = result?.nextCursor ?? result?.cursor ?? null;
1582
+ const nextCursor = result?.nextCursor ?? null;
1598
1583
  return {
1599
1584
  items: result?.items ?? [],
1600
1585
  hasMore: result?.hasMore,
1601
1586
  nextCursor,
1602
- cursor: nextCursor,
1603
1587
  scanned: typeof result?.scanned === "number" ? result.scanned : undefined,
1604
1588
  };
1605
1589
  }
@@ -1707,17 +1691,12 @@ export class ApiClient {
1707
1691
  }
1708
1692
  async listAllAdmins(params) {
1709
1693
  const result = await this.get("/admin/api/admins", params);
1710
- // #1316: prefer `nextCursor`; fall back to the deprecated `cursor` alias.
1711
- const nextCursor = result?.nextCursor ?? result?.cursor ?? null;
1712
- const items = result?.items ?? result?.admins ?? [];
1694
+ const nextCursor = result?.nextCursor ?? null;
1695
+ const items = result?.items ?? [];
1713
1696
  return {
1714
- // `items` is the key every list envelope is built from (#3646, #1982);
1715
- // `admins` is the deprecated legacy name, read only as a fallback.
1716
1697
  items,
1717
- admins: items,
1718
1698
  hasMore: result?.hasMore,
1719
1699
  nextCursor,
1720
- cursor: nextCursor,
1721
1700
  };
1722
1701
  }
1723
1702
  async searchAdminByEmail(email) {
@@ -1911,43 +1890,6 @@ export class ApiClient {
1911
1890
  async deleteDatabase(appId, databaseId) {
1912
1891
  return this.delete(`/app/${appId}/api/databases/${databaseId}`);
1913
1892
  }
1914
- /**
1915
- * Read a database's CEL context dict.
1916
- *
1917
- * The HTTP path stays `/metadata` because the wire field name is still
1918
- * `metadata`; only the client/CLI-facing helper names were reframed.
1919
- *
1920
- * @deprecated Use resource metadata categories instead (`primitive metadata
1921
- * get database <id> <category>`, #1420, #1815).
1922
- */
1923
- async getDatabaseCelContext(appId, databaseId) {
1924
- return this.get(`/app/${appId}/api/databases/${databaseId}/metadata`);
1925
- }
1926
- /**
1927
- * Update a database's CEL context dict (merge with existing).
1928
- *
1929
- * @deprecated Use resource metadata categories instead (`primitive metadata
1930
- * set database <id> <category>`, #1420, #1815).
1931
- */
1932
- async updateDatabaseCelContext(appId, databaseId, celContext) {
1933
- return this.patch(`/app/${appId}/api/databases/${databaseId}/metadata`, celContext);
1934
- }
1935
- /**
1936
- * @deprecated Database CEL context is deprecated; use resource metadata
1937
- * categories instead (`primitive metadata get database <id> <category>`,
1938
- * #1420, #1815).
1939
- */
1940
- async getDatabaseMetadata(appId, databaseId) {
1941
- return this.getDatabaseCelContext(appId, databaseId);
1942
- }
1943
- /**
1944
- * @deprecated Database CEL context is deprecated; use resource metadata
1945
- * categories instead (`primitive metadata set database <id> <category>`,
1946
- * #1420, #1815).
1947
- */
1948
- async updateDatabaseMetadata(appId, databaseId, metadata) {
1949
- return this.updateDatabaseCelContext(appId, databaseId, metadata);
1950
- }
1951
1893
  // ============================================
1952
1894
  // DATABASE PERMISSIONS
1953
1895
  // ============================================
@@ -1963,14 +1905,6 @@ export class ApiClient {
1963
1905
  async removeDatabaseManager(appId, databaseId, userId) {
1964
1906
  return this.delete(`/app/${appId}/api/databases/${databaseId}/permissions/${userId}`);
1965
1907
  }
1966
- /** @deprecated Use {@link addDatabaseManager} instead. */
1967
- async grantDatabasePermission(appId, databaseId, data) {
1968
- return this.addDatabaseManager(appId, databaseId, data.userId);
1969
- }
1970
- /** @deprecated Use {@link removeDatabaseManager} instead. */
1971
- async revokeDatabasePermission(appId, databaseId, userId) {
1972
- return this.delete(`/app/${appId}/api/databases/${databaseId}/permissions/${userId}`);
1973
- }
1974
1908
  // ============================================
1975
1909
  // DATABASE RECORDS & SCHEMA
1976
1910
  // ============================================
@@ -2272,14 +2206,11 @@ export class ApiClient {
2272
2206
  // ============================================
2273
2207
  async listGroups(appId, params) {
2274
2208
  const result = await this.get(`/app/${appId}/api/groups`, params);
2275
- // #1316: prefer `nextCursor`; fall back to the deprecated `cursor` alias
2276
- // so the CLI keeps paginating against pre-#1316 servers.
2277
- const nextCursor = result?.nextCursor ?? result?.cursor;
2209
+ const nextCursor = result?.nextCursor;
2278
2210
  return {
2279
2211
  items: result?.items ?? [],
2280
2212
  nextCursor,
2281
2213
  hasMore: result?.hasMore ?? nextCursor != null,
2282
- cursor: nextCursor,
2283
2214
  };
2284
2215
  }
2285
2216
  async createGroup(appId, data) {
@@ -2311,14 +2242,11 @@ export class ApiClient {
2311
2242
  ...(options?.limit !== undefined ? { limit: options.limit } : {}),
2312
2243
  ...(options?.cursor ? { cursor: options.cursor } : {}),
2313
2244
  });
2314
- // #1316: prefer `nextCursor`; fall back to the deprecated `cursor` alias
2315
- // so the CLI keeps paginating against pre-#1316 servers.
2316
- const nextCursor = result?.nextCursor ?? result?.cursor;
2245
+ const nextCursor = result?.nextCursor;
2317
2246
  return {
2318
2247
  items: result?.items ?? [],
2319
2248
  nextCursor,
2320
2249
  hasMore: result?.hasMore ?? nextCursor != null,
2321
- cursor: nextCursor,
2322
2250
  };
2323
2251
  }
2324
2252
  async addGroupMember(appId, groupType, groupId, data) {
@@ -2365,7 +2293,7 @@ export class ApiClient {
2365
2293
  return {
2366
2294
  items: result?.items ?? [],
2367
2295
  hasMore: result?.hasMore,
2368
- nextCursor: result?.nextCursor ?? result?.cursor ?? null,
2296
+ nextCursor: result?.nextCursor ?? null,
2369
2297
  };
2370
2298
  }
2371
2299
  async listAllCollections(appId, params) {
@@ -2379,7 +2307,7 @@ export class ApiClient {
2379
2307
  return {
2380
2308
  items: result?.items ?? [],
2381
2309
  hasMore: result?.hasMore,
2382
- nextCursor: result?.nextCursor ?? result?.cursor ?? null,
2310
+ nextCursor: result?.nextCursor ?? null,
2383
2311
  };
2384
2312
  }
2385
2313
  async createCollection(appId, data) {
@@ -2408,7 +2336,7 @@ export class ApiClient {
2408
2336
  return {
2409
2337
  items: result?.items ?? [],
2410
2338
  hasMore: result?.hasMore,
2411
- nextCursor: result?.nextCursor ?? result?.cursor ?? null,
2339
+ nextCursor: result?.nextCursor ?? null,
2412
2340
  };
2413
2341
  }
2414
2342
  async addCollectionDocument(appId, collectionId, data) {
@@ -2427,7 +2355,7 @@ export class ApiClient {
2427
2355
  const result = await this.get(`/app/${appId}/api/documents/${documentId}/collections${q ? `?${q}` : ""}`);
2428
2356
  return {
2429
2357
  items: result?.items ?? [],
2430
- nextCursor: result?.nextCursor ?? result?.cursor ?? null,
2358
+ nextCursor: result?.nextCursor ?? null,
2431
2359
  };
2432
2360
  }
2433
2361
  // ============================================
@@ -2675,9 +2603,6 @@ export class ApiClient {
2675
2603
  * through the caller's document permission (reader+) or the app-admin arm.
2676
2604
  * Returns the unified `{ items, hasMore, nextCursor? }` envelope. The cursor
2677
2605
  * is an opaque token — feed `nextCursor` back as `cursor` for the next page.
2678
- * The server also dual-emits a deprecated `cursor` alias (#1316); the
2679
- * normalizer drops it so CLI output is already on `nextCursor` when #1982
2680
- * removes it.
2681
2606
  */
2682
2607
  async queryDocumentRecords(appId, documentId, modelName, queryOptions) {
2683
2608
  const query = {};
@@ -3002,9 +2927,6 @@ export class ApiClient {
3002
2927
  * of them". `paginateAll` carries the repeat-cursor and max-page guards, so
3003
2928
  * a server handing out a non-advancing cursor fails loudly instead of
3004
2929
  * looping forever.
3005
- *
3006
- * Tolerant of a pre-contract server, which answers with a bare
3007
- * `{ documents }` array and no cursor: that reads as a single page.
3008
2930
  */
3009
2931
  async listAdminDocuments(appId, userId) {
3010
2932
  return paginateAll(async (cursor) => {
@@ -3022,9 +2944,6 @@ export class ApiClient {
3022
2944
  * `--limit`/`--cursor` asked for, with the server's own page boundary
3023
2945
  * beside it. `documents export-all`, which really does mean every document,
3024
2946
  * keeps the walking `listAdminDocuments()` above.
3025
- *
3026
- * Tolerant of a pre-contract server, which answers with a bare
3027
- * `{ documents }` array and no cursor: that reads as a single page.
3028
2947
  */
3029
2948
  async listAdminDocumentsPage(appId, userId, options = {}) {
3030
2949
  const params = new URLSearchParams({ userId });
@@ -3034,11 +2953,9 @@ export class ApiClient {
3034
2953
  params.set("cursor", options.cursor);
3035
2954
  const result = await this.get(`/admin/api/apps/${appId}/documents?${params.toString()}`);
3036
2955
  return {
3037
- items: result?.items ?? result?.documents ?? [],
2956
+ items: result?.items ?? [],
3038
2957
  hasMore: result?.hasMore,
3039
- // #1316: prefer `nextCursor`; the deprecated `cursor` alias keeps a
3040
- // shipped CLI paginating against a server that still dual-emits.
3041
- nextCursor: result?.nextCursor ?? result?.cursor ?? null,
2958
+ nextCursor: result?.nextCursor ?? null,
3042
2959
  };
3043
2960
  }
3044
2961
  /**
@@ -3115,14 +3032,11 @@ export class ApiClient {
3115
3032
  }
3116
3033
  async listBucketBlobs(appId, bucketIdOrKey, params) {
3117
3034
  const result = await this.get(`/app/${appId}/api/blob-buckets/${encodeURIComponent(bucketIdOrKey)}/blobs`, params);
3118
- // #1316: prefer `nextCursor`; fall back to the deprecated `cursor` alias
3119
- // so the CLI keeps paginating against pre-#1316 servers.
3120
- const nextCursor = result?.nextCursor ?? result?.cursor;
3035
+ const nextCursor = result?.nextCursor;
3121
3036
  return {
3122
3037
  items: result?.items ?? [],
3123
3038
  nextCursor,
3124
3039
  hasMore: result?.hasMore ?? nextCursor != null,
3125
- cursor: nextCursor,
3126
3040
  };
3127
3041
  }
3128
3042
  async uploadBucketBlob(appId, bucketIdOrKey, data, meta) {