@dench.com/cli 2.3.2 → 2.4.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/crm.ts CHANGED
@@ -88,6 +88,7 @@ type CrmCliContext = {
88
88
  * organization context.
89
89
  */
90
90
  sessionToken?: string;
91
+ runId?: string;
91
92
  enrichmentGateway?: Pick<EnrichmentGatewayOptions, "apiKey" | "baseUrl">;
92
93
  };
93
94
 
@@ -296,6 +297,7 @@ async function applyBatchOpsInChunks(
296
297
  const chunkKey = chunkIdempotencyKey(idempotencyKey, chunkIndex);
297
298
  await callMutation(ctx, api.batch.apply, {
298
299
  ops: chunk,
300
+ ...runContextArgs(ctx),
299
301
  ...(chunkKey ? { idempotencyKey: chunkKey } : {}),
300
302
  ...(allowUnknown ? { allowUnknown: true } : {}),
301
303
  });
@@ -303,6 +305,10 @@ async function applyBatchOpsInChunks(
303
305
  return chunks.length;
304
306
  }
305
307
 
308
+ function runContextArgs(ctx: CrmCliContext): Record<string, string> {
309
+ return ctx.runId ? { runId: ctx.runId } : {};
310
+ }
311
+
306
312
  /**
307
313
  * Fetch the canonical field names for an object. Best-effort: returns
308
314
  * `null` (rather than throwing) on any failure so the caller falls back
@@ -574,6 +580,11 @@ const api = {
574
580
  "functions/crm/entries:bulkDelete",
575
581
  ),
576
582
  },
583
+ history: {
584
+ listForEntry: makeFunctionReference<"query">(
585
+ "functions/crm/history:listForEntry",
586
+ ),
587
+ },
577
588
  cells: {
578
589
  get: makeFunctionReference<"query">("functions/crm/cells:get"),
579
590
  set: makeFunctionReference<"mutation">("functions/crm/cells:set"),
@@ -641,6 +652,7 @@ export async function runCrmCommand(opts: {
641
652
  args,
642
653
  jsonOutput,
643
654
  sessionToken: opts.sessionToken,
655
+ runId: process.env.DENCH_RUN_ID?.trim() || undefined,
644
656
  enrichmentGateway: opts.enrichmentGateway,
645
657
  };
646
658
  const subcommand = args.shift();
@@ -657,6 +669,8 @@ export async function runCrmCommand(opts: {
657
669
  return await runFieldsCommand(ctx);
658
670
  case "entries":
659
671
  return await runEntriesCommand(ctx);
672
+ case "history":
673
+ return await runHistoryCommand(ctx);
660
674
  case "cells":
661
675
  return await runCellsCommand(ctx);
662
676
  case "query":
@@ -1335,6 +1349,7 @@ async function runEntriesCommand(ctx: CrmCliContext): Promise<void> {
1335
1349
  await callMutation(ctx, api.entries.create, {
1336
1350
  objectName,
1337
1351
  data,
1352
+ ...runContextArgs(ctx),
1338
1353
  ...(allowUnknown ? { allowUnknown: true } : {}),
1339
1354
  }),
1340
1355
  );
@@ -1392,6 +1407,7 @@ async function runEntriesCommand(ctx: CrmCliContext): Promise<void> {
1392
1407
  objectName,
1393
1408
  entryId: entryId as any,
1394
1409
  data,
1410
+ ...runContextArgs(ctx),
1395
1411
  ...(allowUnknown ? { allowUnknown: true } : {}),
1396
1412
  }),
1397
1413
  );
@@ -1438,6 +1454,7 @@ async function runEntriesCommand(ctx: CrmCliContext): Promise<void> {
1438
1454
  ctx,
1439
1455
  await callMutation(ctx, api.entries.remove, {
1440
1456
  entryId: entryId as any,
1457
+ ...runContextArgs(ctx),
1441
1458
  }),
1442
1459
  );
1443
1460
  return;
@@ -1452,6 +1469,7 @@ async function runEntriesCommand(ctx: CrmCliContext): Promise<void> {
1452
1469
  ctx,
1453
1470
  await callMutation(ctx, api.entries.bulkDelete, {
1454
1471
  entryIds: entryIds as any,
1472
+ ...runContextArgs(ctx),
1455
1473
  }),
1456
1474
  );
1457
1475
  return;
@@ -1461,6 +1479,27 @@ async function runEntriesCommand(ctx: CrmCliContext): Promise<void> {
1461
1479
  }
1462
1480
  }
1463
1481
 
1482
+ async function runHistoryCommand(ctx: CrmCliContext): Promise<void> {
1483
+ const objectName = shift(ctx.args, "object name");
1484
+ const entryId = shift(ctx.args, "entry id");
1485
+ const includeSystem = hasFlag(ctx.args, "--include-system");
1486
+ const limit = parseInt(getFlag(ctx.args, "--limit") ?? "50", 10);
1487
+ const cursor = getFlag(ctx.args, "--cursor");
1488
+ assertNoUnknownFlags(ctx.args, "crm history");
1489
+ out(
1490
+ ctx,
1491
+ await callQuery(ctx, api.history.listForEntry, {
1492
+ objectName,
1493
+ entryId,
1494
+ includeSystem,
1495
+ paginationOpts: {
1496
+ numItems: Number.isFinite(limit) ? Math.min(Math.max(limit, 1), 100) : 50,
1497
+ cursor: cursor ?? null,
1498
+ },
1499
+ }),
1500
+ );
1501
+ }
1502
+
1464
1503
  async function runCellsCommand(ctx: CrmCliContext): Promise<void> {
1465
1504
  const verb = ctx.args.shift();
1466
1505
  switch (verb) {
@@ -1492,6 +1531,7 @@ async function runCellsCommand(ctx: CrmCliContext): Promise<void> {
1492
1531
  entryId: entryId as any,
1493
1532
  fieldName,
1494
1533
  value,
1534
+ ...runContextArgs(ctx),
1495
1535
  }),
1496
1536
  );
1497
1537
  return;
@@ -1538,6 +1578,7 @@ async function runCellsCommand(ctx: CrmCliContext): Promise<void> {
1538
1578
  entryId: entryId as any,
1539
1579
  fieldName,
1540
1580
  value,
1581
+ ...runContextArgs(ctx),
1541
1582
  }),
1542
1583
  );
1543
1584
  return;
@@ -1664,6 +1705,7 @@ async function runBatchCommand(ctx: CrmCliContext): Promise<void> {
1664
1705
  ctx,
1665
1706
  await callMutation(ctx, api.batch.apply, {
1666
1707
  ops: ops as any,
1708
+ ...runContextArgs(ctx),
1667
1709
  ...(idempotencyKey ? { idempotencyKey } : {}),
1668
1710
  } as any),
1669
1711
  );
@@ -1804,6 +1846,7 @@ async function runTransactionCommand(ctx: CrmCliContext): Promise<void> {
1804
1846
  ctx,
1805
1847
  await callMutation(ctx, api.transaction.commit, {
1806
1848
  txnId: txnId as any,
1849
+ ...runContextArgs(ctx),
1807
1850
  }),
1808
1851
  );
1809
1852
  return;
@@ -1859,6 +1902,7 @@ async function runTransactionCommand(ctx: CrmCliContext): Promise<void> {
1859
1902
  ctx,
1860
1903
  await callMutation(ctx, api.transaction.commit, {
1861
1904
  txnId: begun.txnId as any,
1905
+ ...runContextArgs(ctx),
1862
1906
  }),
1863
1907
  );
1864
1908
  } else {
@@ -2637,6 +2681,7 @@ async function runPeopleCommand(ctx: CrmCliContext): Promise<void> {
2637
2681
  await callMutation(ctx, api.entries.create, {
2638
2682
  objectName: "people",
2639
2683
  data,
2684
+ ...runContextArgs(ctx),
2640
2685
  }),
2641
2686
  );
2642
2687
  return;
@@ -2701,6 +2746,7 @@ async function runCompaniesCommand(ctx: CrmCliContext): Promise<void> {
2701
2746
  await callMutation(ctx, api.entries.create, {
2702
2747
  objectName: "company",
2703
2748
  data,
2749
+ ...runContextArgs(ctx),
2704
2750
  }),
2705
2751
  );
2706
2752
  return;
@@ -2895,6 +2941,7 @@ Fields (columns):
2895
2941
  Entries (rows):
2896
2942
  dench crm entries list <object> [--limit N] [--with-meta] [--json]
2897
2943
  dench crm entries get <object> <entryId>
2944
+ dench crm history <object> <entryId> [--include-system] [--limit N] [--cursor CURSOR] [--json]
2898
2945
  dench crm entries create <object> --data '{"Field":"Value",...}' (alias: --fields) [--allow-unknown]
2899
2946
  dench crm entries create-many <object> --data '[{"Field":"Value",...}]' [--file rows.json] [--idempotency-key <key>] [--allow-unknown]
2900
2947
  dench crm entries update <object> <entryId> --data '{...}' (alias: --fields) [--allow-unknown]
@@ -716,6 +716,37 @@ const rawApiOperations = [
716
716
  responseSchema: anyResponse,
717
717
  backend: convex("query", "functions/crm/entries:get"),
718
718
  }),
719
+ op({
720
+ id: "crm.entries.history",
721
+ group: "crm",
722
+ summary: "List a CRM entry's audit history.",
723
+ cli: "dench crm history",
724
+ method: "GET",
725
+ path: "/crm/objects/{objectName}/entries/{entryId}/history",
726
+ requestSchema: noBody,
727
+ responseSchema: anyResponse,
728
+ backend: {
729
+ ...convex("query", "functions/crm/history:listForEntry"),
730
+ transformArgs: (input) => {
731
+ const limit =
732
+ typeof input.limit === "number"
733
+ ? Math.min(Math.max(Math.floor(input.limit), 1), 100)
734
+ : 50;
735
+ return {
736
+ objectName: input.objectName,
737
+ entryId: input.entryId,
738
+ includeSystem: input.includeSystem === true,
739
+ paginationOpts: {
740
+ numItems: limit,
741
+ cursor:
742
+ typeof input.cursor === "string" && input.cursor.length > 0
743
+ ? input.cursor
744
+ : null,
745
+ },
746
+ };
747
+ },
748
+ },
749
+ }),
719
750
  op({
720
751
  id: "crm.entries.create",
721
752
  group: "crm",
@@ -725,7 +756,9 @@ const rawApiOperations = [
725
756
  path: "/crm/objects/{objectName}/entries",
726
757
  requestSchema: anyObject,
727
758
  responseSchema: anyResponse,
728
- backend: convex("mutation", "functions/crm/entries:create"),
759
+ backend: convex("mutation", "functions/crm/entries:create", "bearer", {
760
+ includeRunId: true,
761
+ }),
729
762
  }),
730
763
  op({
731
764
  id: "crm.entries.createMany",
@@ -736,7 +769,9 @@ const rawApiOperations = [
736
769
  path: "/crm/objects/{objectName}/entries/batch",
737
770
  requestSchema: anyObject,
738
771
  responseSchema: anyResponse,
739
- backend: convex("mutation", "functions/crm/entries:createMany"),
772
+ backend: convex("mutation", "functions/crm/entries:createMany", "bearer", {
773
+ includeRunId: true,
774
+ }),
740
775
  }),
741
776
  op({
742
777
  id: "crm.entries.update",
@@ -747,7 +782,9 @@ const rawApiOperations = [
747
782
  path: "/crm/objects/{objectName}/entries/{entryId}",
748
783
  requestSchema: anyObject,
749
784
  responseSchema: anyResponse,
750
- backend: convex("mutation", "functions/crm/entries:update"),
785
+ backend: convex("mutation", "functions/crm/entries:update", "bearer", {
786
+ includeRunId: true,
787
+ }),
751
788
  }),
752
789
  op({
753
790
  id: "crm.entries.updateMany",
@@ -758,7 +795,9 @@ const rawApiOperations = [
758
795
  path: "/crm/objects/{objectName}/entries/batch",
759
796
  requestSchema: anyObject,
760
797
  responseSchema: anyResponse,
761
- backend: convex("mutation", "functions/crm/batch:apply"),
798
+ backend: convex("mutation", "functions/crm/batch:apply", "bearer", {
799
+ includeRunId: true,
800
+ }),
762
801
  }),
763
802
  op({
764
803
  id: "crm.entries.delete",
@@ -769,7 +808,9 @@ const rawApiOperations = [
769
808
  path: "/crm/objects/{objectName}/entries/{entryId}",
770
809
  requestSchema: anyObject,
771
810
  responseSchema: anyResponse,
772
- backend: convex("mutation", "functions/crm/entries:remove"),
811
+ backend: convex("mutation", "functions/crm/entries:remove", "bearer", {
812
+ includeRunId: true,
813
+ }),
773
814
  }),
774
815
  op({
775
816
  id: "crm.entries.bulkDelete",
@@ -780,7 +821,9 @@ const rawApiOperations = [
780
821
  path: "/crm/objects/{objectName}/entries/delete",
781
822
  requestSchema: anyObject,
782
823
  responseSchema: anyResponse,
783
- backend: convex("mutation", "functions/crm/entries:bulkDelete"),
824
+ backend: convex("mutation", "functions/crm/entries:bulkDelete", "bearer", {
825
+ includeRunId: true,
826
+ }),
784
827
  }),
785
828
 
786
829
  op({
@@ -803,7 +846,9 @@ const rawApiOperations = [
803
846
  path: "/crm/objects/{objectName}/entries/{entryId}/fields/{fieldName}",
804
847
  requestSchema: anyObject,
805
848
  responseSchema: anyResponse,
806
- backend: convex("mutation", "functions/crm/cells:set"),
849
+ backend: convex("mutation", "functions/crm/cells:set", "bearer", {
850
+ includeRunId: true,
851
+ }),
807
852
  }),
808
853
  op({
809
854
  id: "crm.cells.setMany",
@@ -814,7 +859,9 @@ const rawApiOperations = [
814
859
  path: "/crm/cells/batch",
815
860
  requestSchema: anyObject,
816
861
  responseSchema: anyResponse,
817
- backend: convex("mutation", "functions/crm/cells:setMany"),
862
+ backend: convex("mutation", "functions/crm/cells:setMany", "bearer", {
863
+ includeRunId: true,
864
+ }),
818
865
  }),
819
866
  op({
820
867
  id: "crm.cells.append",
@@ -825,7 +872,9 @@ const rawApiOperations = [
825
872
  path: "/crm/objects/{objectName}/entries/{entryId}/fields/{fieldName}/append",
826
873
  requestSchema: anyObject,
827
874
  responseSchema: anyResponse,
828
- backend: convex("mutation", "functions/crm/cells:append"),
875
+ backend: convex("mutation", "functions/crm/cells:append", "bearer", {
876
+ includeRunId: true,
877
+ }),
829
878
  }),
830
879
 
831
880
  op({
@@ -903,7 +952,9 @@ const rawApiOperations = [
903
952
  path: "/crm/batch",
904
953
  requestSchema: anyObject,
905
954
  responseSchema: anyResponse,
906
- backend: convex("mutation", "functions/crm/batch:apply"),
955
+ backend: convex("mutation", "functions/crm/batch:apply", "bearer", {
956
+ includeRunId: true,
957
+ }),
907
958
  }),
908
959
  op({
909
960
  id: "crm.transaction.begin",
@@ -936,7 +987,9 @@ const rawApiOperations = [
936
987
  path: "/crm/transactions/{txnId}/commit",
937
988
  requestSchema: anyObject,
938
989
  responseSchema: anyResponse,
939
- backend: convex("mutation", "functions/crm/transaction:commit"),
990
+ backend: convex("mutation", "functions/crm/transaction:commit", "bearer", {
991
+ includeRunId: true,
992
+ }),
940
993
  }),
941
994
  op({
942
995
  id: "crm.transaction.abort",
@@ -1325,6 +1325,17 @@ async function buildGatewayError(
1325
1325
  { status: response.status, code },
1326
1326
  );
1327
1327
  }
1328
+ if (
1329
+ response.status === 402 ||
1330
+ code === "on_demand_disabled" ||
1331
+ code === "insufficient_credits" ||
1332
+ code === "spend_limit_reached"
1333
+ ) {
1334
+ return new EnrichmentGatewayError(
1335
+ upstreamMessage ?? "AI credits exhausted.",
1336
+ { status: response.status, code },
1337
+ );
1338
+ }
1328
1339
 
1329
1340
  const detail = upstreamMessage || rawText || response.statusText;
1330
1341
  const truncated = detail.length > 500 ? `${detail.slice(0, 500)}...` : detail;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dench.com/cli",
3
- "version": "2.3.2",
3
+ "version": "2.4.0",
4
4
  "description": "Dench agent workspace CLI. v2 unifies auth behind `dench signin`; the legacy `dench login` / `dench onboard` / `dench setup` / `dench what-can-i-do` / `dench register` commands now error with a redirect.",
5
5
  "type": "module",
6
6
  "bin": {