@claypi/cli 0.0.4 → 0.1.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/index.js CHANGED
@@ -47835,7 +47835,7 @@ var require_lodash = __commonJS({
47835
47835
  function object() {
47836
47836
  }
47837
47837
  return function(proto) {
47838
- if (!isObject6(proto)) {
47838
+ if (!isObject7(proto)) {
47839
47839
  return {};
47840
47840
  }
47841
47841
  if (objectCreate) {
@@ -48237,7 +48237,7 @@ var require_lodash = __commonJS({
48237
48237
  if (result2 !== undefined2) {
48238
48238
  return result2;
48239
48239
  }
48240
- if (!isObject6(value)) {
48240
+ if (!isObject7(value)) {
48241
48241
  return value;
48242
48242
  }
48243
48243
  var isArr = isArray4(value);
@@ -48584,7 +48584,7 @@ var require_lodash = __commonJS({
48584
48584
  return true;
48585
48585
  }
48586
48586
  function baseIsNative(value) {
48587
- if (!isObject6(value) || isMasked(value)) {
48587
+ if (!isObject7(value) || isMasked(value)) {
48588
48588
  return false;
48589
48589
  }
48590
48590
  var pattern = isFunction4(value) ? reIsNative : reIsHostCtor;
@@ -48624,7 +48624,7 @@ var require_lodash = __commonJS({
48624
48624
  return result2;
48625
48625
  }
48626
48626
  function baseKeysIn(object) {
48627
- if (!isObject6(object)) {
48627
+ if (!isObject7(object)) {
48628
48628
  return nativeKeysIn(object);
48629
48629
  }
48630
48630
  var isProto = isPrototype(object), result2 = [];
@@ -48669,7 +48669,7 @@ var require_lodash = __commonJS({
48669
48669
  }
48670
48670
  baseFor(source, function(srcValue, key) {
48671
48671
  stack || (stack = new Stack());
48672
- if (isObject6(srcValue)) {
48672
+ if (isObject7(srcValue)) {
48673
48673
  baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
48674
48674
  } else {
48675
48675
  var newValue = customizer ? customizer(safeGet(object, key), srcValue, key + "", object, source, stack) : undefined2;
@@ -48709,7 +48709,7 @@ var require_lodash = __commonJS({
48709
48709
  newValue = objValue;
48710
48710
  if (isArguments(objValue)) {
48711
48711
  newValue = toPlainObject(objValue);
48712
- } else if (!isObject6(objValue) || isFunction4(objValue)) {
48712
+ } else if (!isObject7(objValue) || isFunction4(objValue)) {
48713
48713
  newValue = initCloneObject(srcValue);
48714
48714
  }
48715
48715
  } else {
@@ -48848,7 +48848,7 @@ var require_lodash = __commonJS({
48848
48848
  return shuffleSelf(array, baseClamp(n, 0, array.length));
48849
48849
  }
48850
48850
  function baseSet(object, path7, value, customizer) {
48851
- if (!isObject6(object)) {
48851
+ if (!isObject7(object)) {
48852
48852
  return object;
48853
48853
  }
48854
48854
  path7 = castPath(path7, object);
@@ -48862,7 +48862,7 @@ var require_lodash = __commonJS({
48862
48862
  var objValue = nested[key];
48863
48863
  newValue = customizer ? customizer(objValue, key, nested) : undefined2;
48864
48864
  if (newValue === undefined2) {
48865
- newValue = isObject6(objValue) ? objValue : isIndex(path7[index + 1]) ? [] : {};
48865
+ newValue = isObject7(objValue) ? objValue : isIndex(path7[index + 1]) ? [] : {};
48866
48866
  }
48867
48867
  }
48868
48868
  assignValue(nested, key, newValue);
@@ -49332,7 +49332,7 @@ var require_lodash = __commonJS({
49332
49332
  return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
49333
49333
  }
49334
49334
  var thisBinding = baseCreate(Ctor.prototype), result2 = Ctor.apply(thisBinding, args);
49335
- return isObject6(result2) ? result2 : thisBinding;
49335
+ return isObject7(result2) ? result2 : thisBinding;
49336
49336
  };
49337
49337
  }
49338
49338
  function createCurry(func, bitmask, arity) {
@@ -49668,7 +49668,7 @@ var require_lodash = __commonJS({
49668
49668
  return objValue;
49669
49669
  }
49670
49670
  function customDefaultsMerge(objValue, srcValue, key, object, source, stack) {
49671
- if (isObject6(objValue) && isObject6(srcValue)) {
49671
+ if (isObject7(objValue) && isObject7(srcValue)) {
49672
49672
  stack.set(srcValue, objValue);
49673
49673
  baseMerge(objValue, srcValue, undefined2, customDefaultsMerge, stack);
49674
49674
  stack["delete"](srcValue);
@@ -50016,7 +50016,7 @@ var require_lodash = __commonJS({
50016
50016
  return !!length && (type == "number" || type != "symbol" && reIsUint.test(value)) && (value > -1 && value % 1 == 0 && value < length);
50017
50017
  }
50018
50018
  function isIterateeCall(value, index, object) {
50019
- if (!isObject6(object)) {
50019
+ if (!isObject7(object)) {
50020
50020
  return false;
50021
50021
  }
50022
50022
  var type = typeof index;
@@ -50059,7 +50059,7 @@ var require_lodash = __commonJS({
50059
50059
  return value === proto;
50060
50060
  }
50061
50061
  function isStrictComparable(value) {
50062
- return value === value && !isObject6(value);
50062
+ return value === value && !isObject7(value);
50063
50063
  }
50064
50064
  function matchesStrictComparable(key, srcValue) {
50065
50065
  return function(object) {
@@ -50941,7 +50941,7 @@ var require_lodash = __commonJS({
50941
50941
  throw new TypeError2(FUNC_ERROR_TEXT);
50942
50942
  }
50943
50943
  wait = toNumber(wait) || 0;
50944
- if (isObject6(options)) {
50944
+ if (isObject7(options)) {
50945
50945
  leading = !!options.leading;
50946
50946
  maxing = "maxWait" in options;
50947
50947
  maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
@@ -51111,7 +51111,7 @@ var require_lodash = __commonJS({
51111
51111
  if (typeof func != "function") {
51112
51112
  throw new TypeError2(FUNC_ERROR_TEXT);
51113
51113
  }
51114
- if (isObject6(options)) {
51114
+ if (isObject7(options)) {
51115
51115
  leading = "leading" in options ? !!options.leading : leading;
51116
51116
  trailing = "trailing" in options ? !!options.trailing : trailing;
51117
51117
  }
@@ -51219,7 +51219,7 @@ var require_lodash = __commonJS({
51219
51219
  return typeof value == "number" && nativeIsFinite(value);
51220
51220
  }
51221
51221
  function isFunction4(value) {
51222
- if (!isObject6(value)) {
51222
+ if (!isObject7(value)) {
51223
51223
  return false;
51224
51224
  }
51225
51225
  var tag = baseGetTag4(value);
@@ -51231,7 +51231,7 @@ var require_lodash = __commonJS({
51231
51231
  function isLength(value) {
51232
51232
  return typeof value == "number" && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
51233
51233
  }
51234
- function isObject6(value) {
51234
+ function isObject7(value) {
51235
51235
  var type = typeof value;
51236
51236
  return value != null && (type == "object" || type == "function");
51237
51237
  }
@@ -51338,9 +51338,9 @@ var require_lodash = __commonJS({
51338
51338
  if (isSymbol(value)) {
51339
51339
  return NAN;
51340
51340
  }
51341
- if (isObject6(value)) {
51341
+ if (isObject7(value)) {
51342
51342
  var other = typeof value.valueOf == "function" ? value.valueOf() : value;
51343
- value = isObject6(other) ? other + "" : other;
51343
+ value = isObject7(other) ? other + "" : other;
51344
51344
  }
51345
51345
  if (typeof value != "string") {
51346
51346
  return value === 0 ? value : +value;
@@ -51561,7 +51561,7 @@ var require_lodash = __commonJS({
51561
51561
  var Ctor = object && object.constructor;
51562
51562
  if (isArrLike) {
51563
51563
  accumulator = isArr ? new Ctor() : [];
51564
- } else if (isObject6(object)) {
51564
+ } else if (isObject7(object)) {
51565
51565
  accumulator = isFunction4(Ctor) ? baseCreate(getPrototype(object)) : {};
51566
51566
  } else {
51567
51567
  accumulator = {};
@@ -51846,7 +51846,7 @@ var require_lodash = __commonJS({
51846
51846
  }
51847
51847
  function truncate3(string, options) {
51848
51848
  var length = DEFAULT_TRUNC_LENGTH, omission = DEFAULT_TRUNC_OMISSION;
51849
- if (isObject6(options)) {
51849
+ if (isObject7(options)) {
51850
51850
  var separator = "separator" in options ? options.separator : separator;
51851
51851
  length = "length" in options ? toInteger(options.length) : length;
51852
51852
  omission = "omission" in options ? baseToString(options.omission) : omission;
@@ -51976,13 +51976,13 @@ var require_lodash = __commonJS({
51976
51976
  });
51977
51977
  function mixin(object, source, options) {
51978
51978
  var props = keys(source), methodNames = baseFunctions(source, props);
51979
- if (options == null && !(isObject6(source) && (methodNames.length || !props.length))) {
51979
+ if (options == null && !(isObject7(source) && (methodNames.length || !props.length))) {
51980
51980
  options = source;
51981
51981
  source = object;
51982
51982
  object = this;
51983
51983
  methodNames = baseFunctions(source, keys(source));
51984
51984
  }
51985
- var chain2 = !(isObject6(options) && "chain" in options) || !!options.chain, isFunc = isFunction4(object);
51985
+ var chain2 = !(isObject7(options) && "chain" in options) || !!options.chain, isFunc = isFunction4(object);
51986
51986
  arrayEach(methodNames, function(methodName) {
51987
51987
  var func = source[methodName];
51988
51988
  object[methodName] = func;
@@ -52328,7 +52328,7 @@ var require_lodash = __commonJS({
52328
52328
  lodash.isNil = isNil;
52329
52329
  lodash.isNull = isNull;
52330
52330
  lodash.isNumber = isNumber;
52331
- lodash.isObject = isObject6;
52331
+ lodash.isObject = isObject7;
52332
52332
  lodash.isObjectLike = isObjectLike4;
52333
52333
  lodash.isPlainObject = isPlainObject5;
52334
52334
  lodash.isRegExp = isRegExp2;
@@ -56770,7 +56770,7 @@ function withLoginHint(message) {
56770
56770
  }
56771
56771
  var MissingApiKeyError = class extends Error {
56772
56772
  constructor() {
56773
- super("No API key configured. Run `clay login` to set one.");
56773
+ super("No API key configured. Run `clay login` to set one, or set the CLAY_API_KEY environment variable.");
56774
56774
  this.name = "MissingApiKeyError";
56775
56775
  }
56776
56776
  };
@@ -56816,6 +56816,12 @@ var UploadFailedError = class extends Error {
56816
56816
  this.name = "UploadFailedError";
56817
56817
  }
56818
56818
  };
56819
+ var FileWriteError = class extends Error {
56820
+ constructor(message) {
56821
+ super(message);
56822
+ this.name = "FileWriteError";
56823
+ }
56824
+ };
56819
56825
  var HttpStatusError = class extends Error {
56820
56826
  status;
56821
56827
  retryAfter;
@@ -56839,6 +56845,12 @@ function mapError(err) {
56839
56845
  exitCode: EXIT_CODES.VALIDATION
56840
56846
  };
56841
56847
  }
56848
+ if (err instanceof FileWriteError) {
56849
+ return {
56850
+ envelope: { code: "validation_error", message: err.message },
56851
+ exitCode: EXIT_CODES.VALIDATION
56852
+ };
56853
+ }
56842
56854
  if (err instanceof ApiKeyInvalidCharactersError) {
56843
56855
  return {
56844
56856
  envelope: { code: "validation_error", message: err.message },
@@ -61378,11 +61390,15 @@ function clearDefaultProfile() {
61378
61390
  // src/auth/api-key-provider.ts
61379
61391
  var ApiKeyProvider = class {
61380
61392
  getApiKey() {
61381
- const key = getDefaultApiKey();
61382
- if (key === void 0 || key === "") {
61383
- return Promise.reject(new MissingApiKeyError());
61393
+ const stored = getDefaultApiKey();
61394
+ if (stored !== void 0 && stored !== "") {
61395
+ return Promise.resolve(stored);
61396
+ }
61397
+ const fromEnv = process.env.CLAY_API_KEY?.trim();
61398
+ if (fromEnv !== void 0 && fromEnv !== "") {
61399
+ return Promise.resolve(fromEnv);
61384
61400
  }
61385
- return Promise.resolve(key);
61401
+ return Promise.reject(new MissingApiKeyError());
61386
61402
  }
61387
61403
  };
61388
61404
 
@@ -61451,6 +61467,13 @@ var timeoutApiFetcher = (args) => tsRestFetchApi({
61451
61467
  signal: withTimeoutSignal(requestTimeoutMs(), args.fetchOptions?.signal)
61452
61468
  }
61453
61469
  });
61470
+ var largeTransferTimeoutApiFetcher = (args) => tsRestFetchApi({
61471
+ ...args,
61472
+ fetchOptions: {
61473
+ ...args.fetchOptions,
61474
+ signal: withTimeoutSignal(uploadTimeoutMs(), args.fetchOptions?.signal)
61475
+ }
61476
+ });
61454
61477
  async function fetchWithTimeout(input, init3, timeoutMs = requestTimeoutMs()) {
61455
61478
  return fetch(input, { ...init3, signal: withTimeoutSignal(timeoutMs, init3?.signal) });
61456
61479
  }
@@ -61460,7 +61483,7 @@ var PUBLIC_API_V0_PREFIX = "/public/v0";
61460
61483
  var cache = /* @__PURE__ */ new Map();
61461
61484
  function createPublicApiClient(contract, apiKey) {
61462
61485
  return initClient(contract, {
61463
- baseUrl: `${normalizeBaseUrl(process.env.CLAY_BASE_URL)}${PUBLIC_API_V0_PREFIX}`,
61486
+ baseUrl: `${normalizeBaseUrl(process.env.CLAY_API_URL)}${PUBLIC_API_V0_PREFIX}`,
61464
61487
  baseHeaders: {
61465
61488
  [CLAY_API_KEY_HEADER]: apiKey,
61466
61489
  ...cliAttributionHeaders()
@@ -61485,26 +61508,30 @@ function invalidatePublicApiClient() {
61485
61508
 
61486
61509
  // src/clients/v3-client.ts
61487
61510
  var cache2 = /* @__PURE__ */ new Map();
61488
- async function v3Client(contract) {
61489
- const cached2 = cache2.get(contract);
61511
+ var largeTransferCache = /* @__PURE__ */ new Map();
61512
+ async function v3Client(contract, options = {}) {
61513
+ const useLargeTransfer = options.timeout === "large-transfer";
61514
+ const store = useLargeTransfer ? largeTransferCache : cache2;
61515
+ const cached2 = store.get(contract);
61490
61516
  if (cached2 !== void 0) {
61491
61517
  return cached2;
61492
61518
  }
61493
61519
  const apiKey = await tokenProvider.getApiKey();
61494
61520
  const client = initClient(contract, {
61495
- baseUrl: `${normalizeBaseUrl(process.env.CLAY_BASE_URL)}/v3`,
61521
+ baseUrl: `${normalizeBaseUrl(process.env.CLAY_API_URL)}/v3`,
61496
61522
  baseHeaders: {
61497
61523
  [CLAY_API_KEY_HEADER]: apiKey,
61498
61524
  ...cliAttributionHeaders()
61499
61525
  },
61500
61526
  validateResponse: true,
61501
- api: timeoutApiFetcher
61527
+ api: useLargeTransfer ? largeTransferTimeoutApiFetcher : timeoutApiFetcher
61502
61528
  });
61503
- cache2.set(contract, client);
61529
+ store.set(contract, client);
61504
61530
  return client;
61505
61531
  }
61506
61532
  function invalidateV3Client() {
61507
61533
  cache2.clear();
61534
+ largeTransferCache.clear();
61508
61535
  }
61509
61536
 
61510
61537
  // ../../node_modules/@sentry/node/build/esm/integrations/http.js
@@ -82695,7 +82722,7 @@ Examples:
82695
82722
  // src/commands/logout.ts
82696
82723
  function registerLogout(program3) {
82697
82724
  program3.command("logout").description(
82698
- "Remove the saved API key from the config file. Idempotent \u2014 succeeds even if no key is currently saved. Subsequent authenticated commands will fail with auth_missing_api_key (exit 3) until you run `clay login` again."
82725
+ "Remove the saved API key from the config file. Idempotent \u2014 succeeds even if no key is currently saved. Subsequent authenticated commands will fail with auth_missing_api_key (exit 3) until you run `clay login` again \u2014 unless CLAY_API_KEY is set in the environment, which logout cannot remove and which keeps the CLI authenticated."
82699
82726
  ).addHelpText(
82700
82727
  "after",
82701
82728
  `
@@ -82703,10 +82730,11 @@ Output (success, exit 0):
82703
82730
  { "ok": true }
82704
82731
  Removes only the "default" profile; other profiles in the file are preserved.
82705
82732
  Idempotent \u2014 if no key is saved (or the config file is missing), the command is a no-op and still exits 0.
82733
+ Does not unset the CLAY_API_KEY environment variable; if it is set, the CLI stays authenticated via that fallback after logout.
82706
82734
 
82707
82735
  Examples:
82708
82736
  $ clay logout
82709
- $ clay logout && clay whoami # confirms the key was removed (whoami \u2192 auth_missing_api_key, exit 3)
82737
+ $ clay logout && clay whoami # confirms the key was removed (whoami \u2192 auth_missing_api_key, exit 3, when CLAY_API_KEY is unset)
82710
82738
  `
82711
82739
  ).action(() => {
82712
82740
  clearDefaultProfile();
@@ -83819,6 +83847,18 @@ var FetchSmartleadCampaignDayWiseAnalyticsRequest = external_exports.object({
83819
83847
  campaign_ids: external_exports.string().optional()
83820
83848
  })
83821
83849
  });
83850
+ var FetchSmartleadCampaignsForClientIdRequest = external_exports.object({});
83851
+ var SmartleadCampaignListItem = external_exports.object({
83852
+ id: external_exports.number(),
83853
+ name: external_exports.string(),
83854
+ status: SmartleadCampaignStatusSchema,
83855
+ created_at: external_exports.string(),
83856
+ updated_at: external_exports.string(),
83857
+ send_as_plain_text: external_exports.boolean()
83858
+ });
83859
+ var FetchSmartleadCampaignsForClientIdResponse = external_exports.object({
83860
+ campaigns: external_exports.array(SmartleadCampaignListItem)
83861
+ });
83822
83862
  var SmartleadMasterInboxReply = external_exports.object({
83823
83863
  // An ID used to identify a specific email reply for a lead (e.g. to mark Unread/Read).
83824
83864
  // This is the unique ID for a given reply in the master inbox.
@@ -84693,6 +84733,7 @@ var ConditionalBinaryOperator = /* @__PURE__ */ ((ConditionalBinaryOperator2) =>
84693
84733
  ConditionalBinaryOperator2["Before"] = "Before";
84694
84734
  ConditionalBinaryOperator2["After"] = "After";
84695
84735
  ConditionalBinaryOperator2["On"] = "On";
84736
+ ConditionalBinaryOperator2["SimilarTo"] = "SimilarTo";
84696
84737
  ConditionalBinaryOperator2["Empty"] = "Empty";
84697
84738
  ConditionalBinaryOperator2["NotEmpty"] = "NotEmpty";
84698
84739
  return ConditionalBinaryOperator2;
@@ -85192,6 +85233,7 @@ var SchedulePeriodUnit = /* @__PURE__ */ ((SchedulePeriodUnit2) => {
85192
85233
  SchedulePeriodUnit2["Quarter"] = "quarterly";
85193
85234
  return SchedulePeriodUnit2;
85194
85235
  })(SchedulePeriodUnit || {});
85236
+ var SCHEDULE_PERIOD_UNITS = Object.values(SchedulePeriodUnit);
85195
85237
  var ScheduleSettings = external_exports.object({
85196
85238
  periodUnit: external_exports.nativeEnum(SchedulePeriodUnit),
85197
85239
  periodAmount: external_exports.number().int().positive()
@@ -85850,6 +85892,15 @@ var FunctionUpdateToolInput = FunctionUpdateToolRequest.extend({
85850
85892
  toolId: external_exports.string(),
85851
85893
  outputFormat: MCPOutputFormat.optional()
85852
85894
  });
85895
+ var EnrichmentUpsertToolRequest = UpsertToolBase.extend({
85896
+ type: external_exports.literal("enrichment"),
85897
+ actionPackageId: external_exports.string(),
85898
+ actionKey: external_exports.string(),
85899
+ appAccountId: external_exports.string().nullable().optional()
85900
+ });
85901
+ var EnrichmentUpdateToolRequest = UpdateToolBase.extend({
85902
+ type: external_exports.literal("enrichment")
85903
+ });
85853
85904
  var EnrichmentCreateToolInput = external_exports.object({
85854
85905
  workspaceId: external_exports.number(),
85855
85906
  type: external_exports.literal("enrichment"),
@@ -85858,13 +85909,17 @@ var EnrichmentCreateToolInput = external_exports.object({
85858
85909
  description: external_exports.string().max(500).nullable().optional(),
85859
85910
  access: ToolAccess
85860
85911
  });
85861
- var EnrichmentUpdateToolInput = UpdateToolBase.extend({
85912
+ var EnrichmentUpsertToolInput = UpsertToolBase.extend({
85913
+ type: external_exports.literal("enrichment"),
85862
85914
  workspaceId: external_exports.number(),
85863
- toolId: external_exports.string(),
85864
- type: external_exports.literal("enrichment")
85915
+ id: external_exports.string()
85916
+ });
85917
+ var EnrichmentUpdateToolInput = EnrichmentUpdateToolRequest.extend({
85918
+ workspaceId: external_exports.number(),
85919
+ toolId: external_exports.string()
85865
85920
  });
85866
85921
  var CreateToolInputSchema = external_exports.discriminatedUnion("type", [FunctionCreateToolInput, EnrichmentCreateToolInput]);
85867
- var UpsertToolInputSchema = external_exports.discriminatedUnion("type", [FunctionUpsertToolInput]);
85922
+ var UpsertToolInputSchema = external_exports.discriminatedUnion("type", [FunctionUpsertToolInput, EnrichmentUpsertToolInput]);
85868
85923
  var UpdateToolInputSchema = external_exports.discriminatedUnion("type", [FunctionUpdateToolInput, EnrichmentUpdateToolInput]);
85869
85924
 
85870
85925
  // ../../libs/api-contract/src/public-api-v0/tools-contract.ts
@@ -85875,8 +85930,10 @@ var RunToolItemSchema = external_exports.object({
85875
85930
  inputs: external_exports.record(external_exports.unknown())
85876
85931
  });
85877
85932
  var MAX_RUN_ITEMS = 100;
85933
+ var WEBHOOK_ID_DESCRIPTION = "ID of a registered Clay webhook to notify when the run finishes.";
85878
85934
  var RunToolRequestSchema = external_exports.object({
85879
- items: external_exports.array(RunToolItemSchema).min(1).max(MAX_RUN_ITEMS)
85935
+ items: external_exports.array(RunToolItemSchema).min(1).max(MAX_RUN_ITEMS),
85936
+ webhook_id: external_exports.string().min(1).max(MAX_ID_LENGTH).optional().describe(WEBHOOK_ID_DESCRIPTION)
85880
85937
  });
85881
85938
  var RunToolResponseSchema = external_exports.object({
85882
85939
  tool_run_id: external_exports.string(),
@@ -85910,7 +85967,8 @@ var BatchUploadUrlResponseSchema = external_exports.object({
85910
85967
  file_id: external_exports.string()
85911
85968
  });
85912
85969
  var StartBatchRequestSchema = external_exports.object({
85913
- file_id: external_exports.string()
85970
+ file_id: external_exports.string(),
85971
+ webhook_id: external_exports.string().min(1).max(MAX_ID_LENGTH).optional().describe(WEBHOOK_ID_DESCRIPTION)
85914
85972
  });
85915
85973
  var StartBatchResponseSchema = external_exports.object({
85916
85974
  tool_run_id: external_exports.string(),
@@ -86041,8 +86099,14 @@ var ToolAccess2 = external_exports.object({
86041
86099
  integrations: external_exports.array(ToolSurface).transform((arr) => [...new Set(arr)])
86042
86100
  });
86043
86101
  var CreateToolRequestSchema = external_exports.discriminatedUnion("type", [FunctionCreateToolRequest]);
86044
- var UpsertToolRequestSchema = external_exports.discriminatedUnion("type", [FunctionUpsertToolRequest]);
86045
- var UpdateToolRequestSchema = external_exports.discriminatedUnion("type", [FunctionUpdateToolRequest]);
86102
+ var UpsertToolRequestSchema = external_exports.discriminatedUnion("type", [
86103
+ FunctionUpsertToolRequest,
86104
+ EnrichmentUpsertToolRequest
86105
+ ]);
86106
+ var UpdateToolRequestSchema = external_exports.discriminatedUnion("type", [
86107
+ FunctionUpdateToolRequest,
86108
+ EnrichmentUpdateToolRequest
86109
+ ]);
86046
86110
  var ToolResponse = external_exports.object({
86047
86111
  id: external_exports.string(),
86048
86112
  type: ToolType,
@@ -86610,7 +86674,7 @@ function readRunToolRequest(source) {
86610
86674
  } catch (err) {
86611
86675
  throw new InvalidArgumentError(`--input: not valid JSON (${err.message})`);
86612
86676
  }
86613
- const request2 = RunToolRequestSchema.safeParse(parsed);
86677
+ const request2 = RunToolRequestSchema.pick({ items: true }).safeParse(parsed);
86614
86678
  if (!request2.success) {
86615
86679
  const issue = request2.error.issues[0];
86616
86680
  const path7 = issue?.path.length ? ` at ${issue.path.join(".")}` : "";
@@ -86676,7 +86740,7 @@ function buildStartCommand() {
86676
86740
  const cmd = new Command("start");
86677
86741
  cmd.description(
86678
86742
  "Start an async tool run through the API & CLI integration. Returns immediately; this command does not poll or wait."
86679
- ).argument("<toolId>", "Tool id, e.g. function:tbl_abc123").option("--input <file|->", "Inline run body JSON. Use - to read from stdin.").option("--bulk <file.jsonl>", 'Batch run input JSONL file. Each line is { "id": <string>, "inputs": <object> }.').addHelpText(
86743
+ ).argument("<toolId>", "Tool id, e.g. function:tbl_abc123").option("--input <file|->", "Inline run body JSON. Use - to read from stdin.").option("--bulk <file.jsonl>", 'Batch run input JSONL file. Each line is { "id": <string>, "inputs": <object> }.').option("--webhook-id <id>", "Registered webhook id (wh_...) to notify when the run finishes.").addHelpText(
86680
86744
  "after",
86681
86745
  `
86682
86746
  Output (success, exit 0):
@@ -86700,7 +86764,9 @@ Examples:
86700
86764
  $ clay tools update function:tbl_x --integrations api
86701
86765
  $ cat input.json | clay tools runs start function:tbl_x --input -
86702
86766
  $ clay tools runs start function:tbl_x --input input.json | jq -r '.toolRunId'
86767
+ $ clay tools runs start function:tbl_x --input input.json --webhook-id wh_abc123 | jq -r '.toolRunId'
86703
86768
  $ clay tools runs start function:tbl_x --bulk rows.jsonl
86769
+ $ clay tools runs start function:tbl_x --bulk rows.jsonl --webhook-id wh_abc123
86704
86770
  `
86705
86771
  ).action(async (toolId, opts) => {
86706
86772
  const hasInput = opts.input !== void 0;
@@ -86711,6 +86777,7 @@ Examples:
86711
86777
  const client = await publicApiClient(publicApiToolsContract);
86712
86778
  if (opts.input !== void 0) {
86713
86779
  const body2 = readRunToolRequest(opts.input);
86780
+ body2.webhook_id = opts.webhookId;
86714
86781
  const response2 = await unwrap(client.runTool({ params: { tool_id: toolId }, body: body2 }));
86715
86782
  writeJson(projectInlineStart(response2));
86716
86783
  return;
@@ -86722,7 +86789,10 @@ Examples:
86722
86789
  const upload = await unwrap(client.runToolBatchUploadUrl({ params: { tool_id: toolId } }));
86723
86790
  await uploadJsonl(upload.upload_url, body);
86724
86791
  const response = await unwrap(
86725
- client.startToolRunBatch({ params: { tool_id: toolId }, body: { file_id: upload.file_id } })
86792
+ client.startToolRunBatch({
86793
+ params: { tool_id: toolId },
86794
+ body: { file_id: upload.file_id, webhook_id: opts.webhookId }
86795
+ })
86726
86796
  );
86727
86797
  writeJson(projectBulkStart(response, upload.file_id));
86728
86798
  });
@@ -86851,6 +86921,9 @@ Subcommands:
86851
86921
  update Update name, description, entity-type, or integrations.
86852
86922
  runs Start async tool runs and fetch run status/results.
86853
86923
 
86924
+ These are workspace function tools. For workflow building blocks (actions you add
86925
+ to a node\u2019s "tools"), see \`clay workflows actions\` instead.
86926
+
86854
86927
  See \`clay tools <subcommand> --help\` for per-subcommand JSON shape, error codes, and examples.
86855
86928
  `
86856
86929
  );
@@ -86861,6 +86934,277 @@ See \`clay tools <subcommand> --help\` for per-subcommand JSON shape, error code
86861
86934
  program3.addCommand(tools);
86862
86935
  }
86863
86936
 
86937
+ // ../../libs/api-contract/src/webhooks/contract.ts
86938
+ var WebhookSummary = external_exports.object({
86939
+ id: external_exports.string(),
86940
+ url: external_exports.string(),
86941
+ createdAt: external_exports.string()
86942
+ });
86943
+ var WebhookCreatedResponse = WebhookSummary.extend({
86944
+ signingSecret: external_exports.string()
86945
+ });
86946
+ var ListWebhooksResponse = external_exports.object({
86947
+ data: external_exports.array(WebhookSummary),
86948
+ cursor: external_exports.string().nullable()
86949
+ });
86950
+ var WebhookTestResult = external_exports.object({
86951
+ id: external_exports.string(),
86952
+ status: external_exports.enum(["success", "failed"]),
86953
+ statusCode: external_exports.number().int().optional()
86954
+ });
86955
+ var CreateWebhookBody = external_exports.object({
86956
+ url: external_exports.string().url()
86957
+ });
86958
+ var webhooksContract = {
86959
+ createWebhook: {
86960
+ method: "POST",
86961
+ path: "/workspaces/:workspaceId/webhooks",
86962
+ pathParams: external_exports.object({
86963
+ workspaceId: external_exports.string()
86964
+ }),
86965
+ body: CreateWebhookBody,
86966
+ responses: {
86967
+ 201: WebhookCreatedResponse
86968
+ },
86969
+ summary: "Create a webhook for a workspace; returns the signing secret once",
86970
+ metadata: { team: "rep-tools" /* RepTools */ }
86971
+ },
86972
+ listWebhooks: {
86973
+ method: "GET",
86974
+ path: "/workspaces/:workspaceId/webhooks",
86975
+ pathParams: external_exports.object({
86976
+ workspaceId: external_exports.string()
86977
+ }),
86978
+ query: external_exports.object({
86979
+ cursor: external_exports.string().optional(),
86980
+ limit: external_exports.coerce.number().int().positive().max(200).optional()
86981
+ }),
86982
+ responses: {
86983
+ 200: ListWebhooksResponse
86984
+ },
86985
+ summary: "List active webhooks for a workspace (cursor-paginated, newest first)",
86986
+ metadata: { team: "rep-tools" /* RepTools */ }
86987
+ },
86988
+ deleteWebhook: {
86989
+ method: "DELETE",
86990
+ path: "/workspaces/:workspaceId/webhooks/:webhookId",
86991
+ pathParams: external_exports.object({
86992
+ workspaceId: external_exports.string(),
86993
+ webhookId: external_exports.string()
86994
+ }),
86995
+ body: external_exports.object({}),
86996
+ responses: {
86997
+ 200: external_exports.object({ success: external_exports.literal(true) }),
86998
+ 404: external_exports.object({ message: external_exports.string() })
86999
+ },
87000
+ summary: "Soft-delete a webhook",
87001
+ metadata: { team: "rep-tools" /* RepTools */ }
87002
+ },
87003
+ testWebhook: {
87004
+ method: "POST",
87005
+ path: "/workspaces/:workspaceId/webhooks/:webhookId/test",
87006
+ pathParams: external_exports.object({
87007
+ workspaceId: external_exports.string(),
87008
+ webhookId: external_exports.string()
87009
+ }),
87010
+ body: external_exports.object({}),
87011
+ responses: {
87012
+ 200: WebhookTestResult,
87013
+ 404: external_exports.object({ message: external_exports.string() })
87014
+ },
87015
+ summary: "Send a signed test event to a webhook and report the delivery outcome",
87016
+ metadata: { team: "rep-tools" /* RepTools */ }
87017
+ }
87018
+ };
87019
+
87020
+ // src/commands/webhooks/create.ts
87021
+ function buildCreateCommand() {
87022
+ const cmd = new Command("create");
87023
+ cmd.description(
87024
+ "Create a webhook. The signing secret is returned exactly once \u2014 capture it now; it can never be read again."
87025
+ ).argument("<url>", "HTTPS endpoint that will receive signed webhook deliveries.").addHelpText(
87026
+ "after",
87027
+ `
87028
+ Output (success, exit 0):
87029
+ {
87030
+ "id": <string>,
87031
+ "url": <string>,
87032
+ "createdAt": <string>,
87033
+ "signingSecret": <string>
87034
+ }
87035
+
87036
+ Common errors:
87037
+ validation_error (exit 2) <url> is not a valid URL.
87038
+ auth_forbidden (exit 3) Key lacks permission to manage webhooks.
87039
+ not_found (exit 6) Webhooks are not enabled for this workspace.
87040
+
87041
+ Examples:
87042
+ $ clay webhooks create https://example.com/hooks/clay
87043
+ $ clay webhooks create https://example.com/hooks/clay | jq -r '.signingSecret'
87044
+ `
87045
+ ).action(async (url) => {
87046
+ const workspaceId = await currentWorkspaceId();
87047
+ const client = await v3Client(webhooksContract);
87048
+ const webhook = await unwrap(client.createWebhook({ params: { workspaceId }, body: { url } }));
87049
+ writeJson({
87050
+ id: webhook.id,
87051
+ url: webhook.url,
87052
+ createdAt: webhook.createdAt,
87053
+ signingSecret: webhook.signingSecret
87054
+ });
87055
+ });
87056
+ return cmd;
87057
+ }
87058
+
87059
+ // src/commands/webhooks/delete.ts
87060
+ function buildDeleteCommand() {
87061
+ const cmd = new Command("delete");
87062
+ cmd.description("Delete a webhook by id").argument("<webhookId>", "Webhook id, e.g. the `id` returned by `clay webhooks list`.").addHelpText(
87063
+ "after",
87064
+ `
87065
+ Output (success, exit 0):
87066
+ { "ok": true }
87067
+
87068
+ Common errors:
87069
+ auth_forbidden (exit 3) Key lacks permission to manage webhooks.
87070
+ not_found (exit 6) No webhook with that id in this workspace.
87071
+
87072
+ Examples:
87073
+ $ clay webhooks delete whk_abc123
87074
+ $ clay webhooks list | jq -r '.data[0].id' | xargs clay webhooks delete
87075
+ `
87076
+ ).action(async (webhookId) => {
87077
+ const workspaceId = await currentWorkspaceId();
87078
+ const client = await v3Client(webhooksContract);
87079
+ await unwrap(client.deleteWebhook({ params: { workspaceId, webhookId }, body: {} }));
87080
+ writeJson({ ok: true });
87081
+ });
87082
+ return cmd;
87083
+ }
87084
+
87085
+ // src/commands/webhooks/list.ts
87086
+ function buildListCommand4() {
87087
+ const cmd = new Command("list");
87088
+ cmd.description("List active webhooks with the most recently created first").option("--limit <n>", "Max webhooks to return per page (1-200, default 50).", parseLimitFlag).option("--cursor <token>", "Resume from a previous response's `cursor` to fetch the next page.").addHelpText(
87089
+ "after",
87090
+ `
87091
+ Output (success, exit 0):
87092
+ {
87093
+ "data": [
87094
+ {
87095
+ "id": <string>,
87096
+ "url": <string>,
87097
+ "createdAt": <string>
87098
+ }
87099
+ ],
87100
+ "cursor": <string|undefined>
87101
+ }
87102
+
87103
+ Pagination:
87104
+ Page size and position are flags:
87105
+ --limit <n> max webhooks per call (1-200, default 50)
87106
+ --cursor <token> resume from a previous response's \`cursor\`
87107
+ When more results exist, the response includes a top-level \`cursor\`; pass it back via
87108
+ --cursor to fetch the next page.
87109
+
87110
+ Common errors:
87111
+ validation_error (exit 2) --limit is not a positive integer.
87112
+ auth_forbidden (exit 3) Key lacks permission to manage webhooks.
87113
+ not_found (exit 6) Webhooks are not enabled for this workspace.
87114
+
87115
+ Examples:
87116
+ $ clay webhooks list
87117
+ $ clay webhooks list --limit 100 | jq -r '.data[].url'
87118
+ $ clay webhooks list --limit 100 --cursor "$CURSOR"
87119
+ `
87120
+ ).action(async (opts) => {
87121
+ const workspaceId = await currentWorkspaceId();
87122
+ const client = await v3Client(webhooksContract);
87123
+ const page = await unwrap(
87124
+ client.listWebhooks({
87125
+ params: { workspaceId },
87126
+ query: {
87127
+ limit: opts.limit,
87128
+ cursor: opts.cursor
87129
+ }
87130
+ })
87131
+ );
87132
+ writeJson({
87133
+ data: page.data.map((w) => ({
87134
+ id: w.id,
87135
+ url: w.url,
87136
+ createdAt: w.createdAt
87137
+ })),
87138
+ ...page.cursor === null ? {} : { cursor: page.cursor }
87139
+ });
87140
+ });
87141
+ return cmd;
87142
+ }
87143
+
87144
+ // src/commands/webhooks/test.ts
87145
+ function buildTestCommand() {
87146
+ const cmd = new Command("test");
87147
+ cmd.description("Send a signed test event to a webhook and report the delivery outcome.").argument("<webhookId>", "Webhook id, e.g. the `id` returned by `clay webhooks list`.").addHelpText(
87148
+ "after",
87149
+ `
87150
+ Output (success, exit 0):
87151
+ {
87152
+ "id": <string>,
87153
+ "status": "success" | "failed",
87154
+ "statusCode": <number|undefined>
87155
+ }
87156
+
87157
+ status values:
87158
+ success The endpoint accepted the delivery (2xx response).
87159
+ failed The endpoint rejected the delivery or was unreachable.
87160
+
87161
+ Common errors:
87162
+ auth_forbidden (exit 3) Key lacks permission to manage webhooks.
87163
+ not_found (exit 6) No webhook with that id in this workspace.
87164
+
87165
+ Examples:
87166
+ $ clay webhooks test whk_abc123
87167
+ $ clay webhooks test whk_abc123 | jq -r '.status'
87168
+ `
87169
+ ).action(async (webhookId) => {
87170
+ const workspaceId = await currentWorkspaceId();
87171
+ const client = await v3Client(webhooksContract);
87172
+ const result = await unwrap(client.testWebhook({ params: { workspaceId, webhookId }, body: {} }));
87173
+ writeJson({
87174
+ id: result.id,
87175
+ status: result.status,
87176
+ ...result.statusCode === void 0 ? {} : { statusCode: result.statusCode }
87177
+ });
87178
+ });
87179
+ return cmd;
87180
+ }
87181
+
87182
+ // src/commands/webhooks/index.ts
87183
+ function registerWebhooks(program3) {
87184
+ const webhooks = applyClaySettings(
87185
+ new Command("webhooks").description(
87186
+ "Manage webhooks in the authenticated workspace. Subcommands: create, list, delete, test."
87187
+ )
87188
+ );
87189
+ webhooks.addHelpText(
87190
+ "after",
87191
+ `
87192
+ Subcommands:
87193
+ create Create a webhook; returns the signing secret exactly once.
87194
+ list List active webhooks in the workspace (newest first).
87195
+ delete Delete a webhook by id.
87196
+ test Send a signed test event to a webhook and report the outcome.
87197
+
87198
+ See \`clay webhooks <subcommand> --help\` for per-subcommand JSON shape, error codes, and examples.
87199
+ `
87200
+ );
87201
+ webhooks.addCommand(applyClaySettings(buildCreateCommand()));
87202
+ webhooks.addCommand(applyClaySettings(buildListCommand4()));
87203
+ webhooks.addCommand(applyClaySettings(buildDeleteCommand()));
87204
+ webhooks.addCommand(applyClaySettings(buildTestCommand()));
87205
+ program3.addCommand(webhooks);
87206
+ }
87207
+
86864
87208
  // src/commands/whoami.ts
86865
87209
  function registerWhoami(program3) {
86866
87210
  program3.command("whoami").description(
@@ -86898,6 +87242,204 @@ Examples:
86898
87242
  });
86899
87243
  }
86900
87244
 
87245
+ // ../../libs/api-contract/src/terracotta/clay-actions/contract.ts
87246
+ var terracottaClayActionsContract = {
87247
+ getClayActions: {
87248
+ method: "GET",
87249
+ path: "/workspaces/:workspaceId/tc-clay-actions",
87250
+ pathParams: external_exports.object({
87251
+ workspaceId: external_exports.string()
87252
+ }),
87253
+ responses: {
87254
+ // Returns raw JSON array of action objects — no strict schema since
87255
+ // the shape comes from the clay_actions.json catalog file
87256
+ 200: external_exports.unknown()
87257
+ },
87258
+ summary: "Get filtered and annotated Clay actions catalog for a workspace",
87259
+ metadata: { team: "workflows" /* Workflows */ }
87260
+ },
87261
+ getClayActionSchema: {
87262
+ method: "GET",
87263
+ path: "/workspaces/:workspaceId/tc-clay-action-schemas/:packageId/:actionKey",
87264
+ pathParams: external_exports.object({
87265
+ workspaceId: external_exports.string(),
87266
+ packageId: external_exports.string(),
87267
+ actionKey: external_exports.string()
87268
+ }),
87269
+ responses: {
87270
+ 200: external_exports.unknown(),
87271
+ 404: external_exports.object({ error: external_exports.string() })
87272
+ },
87273
+ summary: "Get input schema for a specific Clay action by packageId and actionKey",
87274
+ metadata: { team: "workflows" /* Workflows */ }
87275
+ }
87276
+ };
87277
+
87278
+ // src/commands/workflows/actions/projection.ts
87279
+ var ACTION_FIELDS = [
87280
+ "type",
87281
+ "actionKey",
87282
+ "functionId",
87283
+ "name",
87284
+ "displayName",
87285
+ "description",
87286
+ "packageId",
87287
+ "packageDisplayName",
87288
+ "packageDescription",
87289
+ "documentationUri",
87290
+ "categories",
87291
+ "actionLabels",
87292
+ "creditCost",
87293
+ "usesPrivateKeyCost",
87294
+ "paymentType",
87295
+ "outputParameters",
87296
+ "dataStrengths",
87297
+ "whyUseful",
87298
+ "useCaseExamples",
87299
+ "providerDescription",
87300
+ "clayUseCase",
87301
+ "configuredTools",
87302
+ "availableAppAccounts",
87303
+ "priorityTier"
87304
+ ];
87305
+ function isObject6(value) {
87306
+ return typeof value === "object" && value !== null && !Array.isArray(value);
87307
+ }
87308
+ function projectAction(entry) {
87309
+ if (!isObject6(entry)) {
87310
+ throw new IncompatibleApiServerError("Clay actions catalog entry was not an object.");
87311
+ }
87312
+ const projected = {};
87313
+ for (const field of ACTION_FIELDS) {
87314
+ if (entry[field] !== void 0) {
87315
+ projected[field] = entry[field];
87316
+ }
87317
+ }
87318
+ return projected;
87319
+ }
87320
+ function projectActions(body) {
87321
+ if (!Array.isArray(body)) {
87322
+ throw new IncompatibleApiServerError("Clay actions catalog was not a JSON array.");
87323
+ }
87324
+ return body.map(projectAction);
87325
+ }
87326
+ function projectActionSchema(body) {
87327
+ if (!isObject6(body)) {
87328
+ throw new IncompatibleApiServerError("Clay action schema response was not an object.");
87329
+ }
87330
+ if (typeof body.packageId !== "string" || typeof body.actionKey !== "string" || typeof body.displayName !== "string" || !Array.isArray(body.inputParameters)) {
87331
+ throw new IncompatibleApiServerError("Clay action schema response is missing required fields.");
87332
+ }
87333
+ return {
87334
+ packageId: body.packageId,
87335
+ actionKey: body.actionKey,
87336
+ displayName: body.displayName,
87337
+ inputParameters: body.inputParameters
87338
+ };
87339
+ }
87340
+
87341
+ // src/commands/workflows/actions/list.ts
87342
+ function buildListCommand5() {
87343
+ const cmd = new Command("list");
87344
+ cmd.description('Dump the Clay action catalog \u2014 the building blocks for a workflow node\u2019s "tools".').addHelpText(
87345
+ "after",
87346
+ `
87347
+ Output (success, exit 0):
87348
+ { "data": [ <action>, ... ] }
87349
+
87350
+ Each action carries its full documented field set so the catalog stays
87351
+ greppable: "type", "actionKey", "functionId", "name", "displayName",
87352
+ "description", "packageId", "packageDisplayName", "packageDescription",
87353
+ "documentationUri", "categories", "actionLabels", "creditCost",
87354
+ "usesPrivateKeyCost", "paymentType", "outputParameters", "dataStrengths",
87355
+ "whyUseful", "useCaseExamples", "providerDescription", "clayUseCase",
87356
+ "configuredTools", "availableAppAccounts", "priorityTier" (lower ranks higher).
87357
+ Fields are present only when the catalog supplies them.
87358
+
87359
+ The catalog is large (~1.5k entries). The intended flow is dump-then-filter:
87360
+ write it to a file once, then grep/jq it repeatedly. To *use* an action in a
87361
+ node\u2019s tools, take its "packageId" + "actionKey" (or reuse a
87362
+ "configuredTools[].toolId"); fetch its inputs with \`workflows actions schema\`.
87363
+
87364
+ Not to be confused with \`clay tools\`, which lists workspace *function tools* \u2014
87365
+ a different concept. Use this command for workflow building blocks.
87366
+
87367
+ Common errors:
87368
+ auth_forbidden (exit 3) API key lacks permission for this command (insufficient scope).
87369
+
87370
+ Examples:
87371
+ $ clay workflows actions list > catalog.json
87372
+ $ jq -r '.data[] | select(.name | test("email";"i")) | "\\(.packageId) \\(.actionKey)"' catalog.json
87373
+ $ clay workflows actions list | jq '.data | length'
87374
+ `
87375
+ ).action(async () => {
87376
+ const workspaceId = await currentWorkspaceId();
87377
+ const client = await v3Client(terracottaClayActionsContract);
87378
+ const result = await unwrap(client.getClayActions({ params: { workspaceId } }));
87379
+ writeJson({ data: projectActions(result) });
87380
+ });
87381
+ return cmd;
87382
+ }
87383
+
87384
+ // src/commands/workflows/actions/schema.ts
87385
+ function buildSchemaCommand() {
87386
+ const cmd = new Command("schema");
87387
+ cmd.description("Fetch the input schema for one Clay action, to wire it into a node\u2019s tools.").argument("<packageId>", "Action package id, from `workflows actions list`").argument("<actionKey>", "Action key, from `workflows actions list`").addHelpText(
87388
+ "after",
87389
+ `
87390
+ Output (success, exit 0):
87391
+ {
87392
+ "packageId": <string>,
87393
+ "actionKey": <string>,
87394
+ "displayName": <string>,
87395
+ "inputParameters": [ <parameter>, ... ]
87396
+ }
87397
+
87398
+ "inputParameters" is an array of the action\u2019s input parameters \u2014 one entry per
87399
+ field you can pass when adding this action to a node\u2019s "tools" (each typically
87400
+ has name/displayName/type/required/description).
87401
+
87402
+ Common errors:
87403
+ validation_error (exit 2) packageId and actionKey arguments are required.
87404
+ not_found (exit 6) No action with that packageId/actionKey.
87405
+ auth_forbidden (exit 3) API key lacks permission for this command (insufficient scope).
87406
+
87407
+ Examples:
87408
+ $ clay workflows actions schema 56058efe-4757-4fe7-a44b-39c2d730c47a find-email-from-name
87409
+ $ clay workflows actions schema <packageId> <actionKey> | jq '.inputParameters'
87410
+ `
87411
+ ).action(async (packageId, actionKey) => {
87412
+ const workspaceId = await currentWorkspaceId();
87413
+ const client = await v3Client(terracottaClayActionsContract);
87414
+ const result = await unwrap(client.getClayActionSchema({ params: { workspaceId, packageId, actionKey } }));
87415
+ writeJson(projectActionSchema(result));
87416
+ });
87417
+ return cmd;
87418
+ }
87419
+
87420
+ // src/commands/workflows/actions/index.ts
87421
+ function buildActionsCommand() {
87422
+ const cmd = new Command("actions");
87423
+ cmd.description("Browse the Clay action catalog \u2014 the building blocks for a workflow node\u2019s tools.").addHelpText(
87424
+ "after",
87425
+ `
87426
+ Subcommands:
87427
+ list Dump the full action catalog (greppable JSON).
87428
+ schema Fetch one action\u2019s input schema by packageId + actionKey.
87429
+
87430
+ These are workflow building blocks (actions you add to a node\u2019s "tools"). For
87431
+ workspace *function tools*, a different concept, see \`clay tools\`.
87432
+
87433
+ Examples:
87434
+ $ clay workflows actions list > catalog.json
87435
+ $ clay workflows actions schema <packageId> <actionKey> | jq '.inputParameters'
87436
+ `
87437
+ );
87438
+ cmd.addCommand(applyClaySettings(buildListCommand5()));
87439
+ cmd.addCommand(applyClaySettings(buildSchemaCommand()));
87440
+ return cmd;
87441
+ }
87442
+
86901
87443
  // ../../libs/shared/src/agents/json-schema-validation.ts
86902
87444
  var JSONSchemaType = external_exports.enum(["string", "number", "integer", "boolean", "array", "object"]);
86903
87445
  var BaseJSONSchemaProperty = external_exports.object({
@@ -88362,6 +88904,15 @@ var SerializedWorkflow = external_exports.object({
88362
88904
  var SerializedWorkflows = external_exports.object({
88363
88905
  workflows: external_exports.array(SerializedWorkflow)
88364
88906
  });
88907
+ var WORKFLOW_LIST_MAX_PAGE_SIZE = 200;
88908
+ var ListWorkflowsQuerySchema = external_exports.object({
88909
+ cursor: external_exports.string().optional(),
88910
+ limit: external_exports.coerce.number().int().positive().max(WORKFLOW_LIST_MAX_PAGE_SIZE).optional()
88911
+ });
88912
+ var ListWorkflowsResponseSchema = external_exports.object({
88913
+ workflows: external_exports.array(SerializedWorkflow),
88914
+ nextCursor: external_exports.string().nullable()
88915
+ });
88365
88916
 
88366
88917
  // ../../libs/api-contract/src/terracotta/workflows/contract.ts
88367
88918
  var terracottaWorkflowsContract = {
@@ -88377,6 +88928,19 @@ var terracottaWorkflowsContract = {
88377
88928
  summary: "Get workflows for workspace",
88378
88929
  metadata: { team: "workflows" /* Workflows */ }
88379
88930
  },
88931
+ listWorkflows: {
88932
+ method: "GET",
88933
+ path: "/workspaces/:workspaceId/tc-workflows-paginated",
88934
+ pathParams: external_exports.object({
88935
+ workspaceId: external_exports.string()
88936
+ }),
88937
+ query: ListWorkflowsQuerySchema.optional(),
88938
+ responses: {
88939
+ 200: ListWorkflowsResponseSchema
88940
+ },
88941
+ summary: "List workflows for workspace (paginated)",
88942
+ metadata: { team: "workflows" /* Workflows */ }
88943
+ },
88380
88944
  getWorkflow: {
88381
88945
  method: "GET",
88382
88946
  path: "/workspaces/:workspaceId/tc-workflows/:workflowId",
@@ -88496,8 +89060,7 @@ var terracottaWorkflowsContract = {
88496
89060
  workflowId: external_exports.string()
88497
89061
  }),
88498
89062
  body: external_exports.object({
88499
- name: external_exports.string().max(255).optional(),
88500
- lastRunAt: external_exports.string().datetime().optional()
89063
+ name: external_exports.string().max(255).optional()
88501
89064
  }),
88502
89065
  responses: {
88503
89066
  200: external_exports.object({ workflow: SerializedWorkflow })
@@ -88576,7 +89139,7 @@ function parseNameFlag(value) {
88576
89139
  }
88577
89140
  return trimmed;
88578
89141
  }
88579
- function buildCreateCommand() {
89142
+ function buildCreateCommand2() {
88580
89143
  const cmd = new Command("create");
88581
89144
  cmd.description("Create a new empty workflow.").requiredOption("--name <name>", "Workflow name.", parseNameFlag).addHelpText(
88582
89145
  "after",
@@ -88639,7 +89202,7 @@ Examples:
88639
89202
  }
88640
89203
 
88641
89204
  // src/commands/workflows/list.ts
88642
- function buildListCommand4() {
89205
+ function buildListCommand6() {
88643
89206
  const cmd = new Command("list");
88644
89207
  cmd.description("List workflows in the workspace.").option(
88645
89208
  "--limit <n>",
@@ -88678,6 +89241,130 @@ Examples:
88678
89241
  return cmd;
88679
89242
  }
88680
89243
 
89244
+ // src/commands/workflows/runs/download-file.ts
89245
+ var import_node_fs10 = require("fs");
89246
+ var import_node_path7 = require("path");
89247
+
89248
+ // ../../libs/api-contract/src/terracotta/code-tool/interfaces.ts
89249
+ var ToolExecutionRequest = external_exports.object({
89250
+ toolId: external_exports.string().describe('Tool ID in format "actionPackageId:actionKey"'),
89251
+ inputs: external_exports.record(external_exports.unknown()).describe("Tool input parameters")
89252
+ });
89253
+ var ToolExecutionResponse = external_exports.object({
89254
+ success: external_exports.boolean(),
89255
+ result: external_exports.unknown().optional(),
89256
+ error: external_exports.string().optional()
89257
+ });
89258
+ var ToolExecutionErrorResponse = external_exports.object({
89259
+ error: external_exports.string()
89260
+ });
89261
+ var SandboxFileDownloadRequest = external_exports.object({
89262
+ filePath: external_exports.string().describe("Path to the file in the sandbox filesystem")
89263
+ });
89264
+ var SandboxFileDownloadErrorResponse = external_exports.object({
89265
+ error: external_exports.string()
89266
+ });
89267
+
89268
+ // ../../libs/api-contract/src/terracotta/code-tool/contract.ts
89269
+ var terracottaCodeToolContract = {
89270
+ executeToolFromCode: {
89271
+ method: "POST",
89272
+ path: "/terracotta/internal/workflow-run/:workflowRunId/step/:stepId/execute-tool",
89273
+ pathParams: external_exports.object({
89274
+ workflowRunId: external_exports.string(),
89275
+ stepId: external_exports.string()
89276
+ }),
89277
+ responses: {
89278
+ 200: ToolExecutionResponse,
89279
+ 401: ToolExecutionErrorResponse,
89280
+ 403: ToolExecutionErrorResponse,
89281
+ 422: ToolExecutionErrorResponse,
89282
+ 500: ToolExecutionErrorResponse
89283
+ },
89284
+ body: ToolExecutionRequest,
89285
+ summary: "Execute a tool from code node",
89286
+ description: "Internal endpoint for executing Clay actions from Python code running in Daytona sandboxes",
89287
+ metadata: { team: "workflows" /* Workflows */ }
89288
+ },
89289
+ downloadFileFromSandbox: {
89290
+ method: "POST",
89291
+ path: "/terracotta/internal/workflow-run/:workflowRunId/download-file",
89292
+ pathParams: external_exports.object({
89293
+ workflowRunId: external_exports.string()
89294
+ }),
89295
+ responses: {
89296
+ 200: external_exports.object({
89297
+ success: external_exports.literal(true),
89298
+ fileData: external_exports.string().describe("Base64-encoded file contents"),
89299
+ filename: external_exports.string().describe("Basename of the file")
89300
+ }),
89301
+ 401: SandboxFileDownloadErrorResponse,
89302
+ 403: SandboxFileDownloadErrorResponse,
89303
+ 404: SandboxFileDownloadErrorResponse,
89304
+ 500: SandboxFileDownloadErrorResponse
89305
+ },
89306
+ body: SandboxFileDownloadRequest,
89307
+ summary: "Download a file from a workflow run sandbox",
89308
+ description: "Downloads a file from the Daytona sandbox associated with a workflow run. Returns the raw file contents as a binary response.",
89309
+ metadata: { team: "workflows" /* Workflows */ }
89310
+ }
89311
+ };
89312
+
89313
+ // src/commands/workflows/runs/download-file.ts
89314
+ function buildDownloadFileCommand() {
89315
+ const cmd = new Command("download-file");
89316
+ cmd.description("Download a file written by a code node from a workflow run sandbox onto local disk.").argument("<workflowId>", "Workflow id, e.g. wf_abc123").argument("<runId>", "Run id, e.g. wfr_xyz789").requiredOption(
89317
+ "--path <sandbox-path>",
89318
+ "Absolute path of the file inside the run sandbox, e.g. /home/daytona/report.csv"
89319
+ ).option(
89320
+ "--output <local>",
89321
+ "Local path to write the file to. Defaults to the basename of --path in the current directory."
89322
+ ).addHelpText(
89323
+ "after",
89324
+ `
89325
+ Output (success, exit 0):
89326
+ { "path": <string>, "size": <number> }
89327
+
89328
+ "path" is the local path the file was written to; "size" is its size in bytes.
89329
+ The file contents are written to disk only \u2014 never to stdout \u2014 so the JSON
89330
+ envelope stays clean for piping. Code nodes run in an ephemeral per-run sandbox
89331
+ (cwd /home/daytona) that is torn down after the run, so download artifacts
89332
+ before the run is archived.
89333
+
89334
+ The run is resolved by runId alone \u2014 workflowId is positional only for parity
89335
+ with the other "runs" subcommands and is NOT validated against the run. Passing
89336
+ a runId that belongs to a different workflow still downloads from that run, so
89337
+ make sure the runId is correct (e.g. from "runs get"/"runs start" output).
89338
+
89339
+ Common errors:
89340
+ validation_error (exit 2) workflowId, runId, or --path is missing, or --output could not be written.
89341
+ not_found (exit 6) No run with that runId, or no file at --path in its sandbox.
89342
+ auth_forbidden (exit 3) API key lacks permission for this command (insufficient scope).
89343
+
89344
+ Examples:
89345
+ $ clay workflows runs download-file wf_abc123 wfr_xyz789 --path /home/daytona/report.csv
89346
+ $ clay workflows runs download-file wf_abc123 wfr_xyz789 --path /home/daytona/out.json --output ./out.json
89347
+ $ clay workflows runs download-file wf_abc123 wfr_xyz789 --path /home/daytona/report.csv | jq -r '.size'
89348
+ `
89349
+ ).action(async (_workflowId, runId, opts) => {
89350
+ const client = await v3Client(terracottaCodeToolContract, { timeout: "large-transfer" });
89351
+ const result = await unwrap(
89352
+ client.downloadFileFromSandbox({ params: { workflowRunId: runId }, body: { filePath: opts.path } })
89353
+ );
89354
+ const outputPath = opts.output ?? (0, import_node_path7.basename)(opts.path);
89355
+ const bytes = Buffer.from(result.fileData, "base64");
89356
+ try {
89357
+ (0, import_node_fs10.writeFileSync)(outputPath, bytes);
89358
+ } catch (err) {
89359
+ throw new FileWriteError(
89360
+ `Could not write to ${outputPath}: ${err instanceof Error ? err.message : String(err)}`
89361
+ );
89362
+ }
89363
+ writeJson({ path: outputPath, size: bytes.length });
89364
+ });
89365
+ return cmd;
89366
+ }
89367
+
88681
89368
  // ../../libs/shared/src/agents/human-feedback.ts
88682
89369
  var ApproveContinuation = external_exports.object({
88683
89370
  type: external_exports.literal("ApproveContinuation")
@@ -89426,11 +90113,12 @@ function buildRunsCommand2() {
89426
90113
  "after",
89427
90114
  `
89428
90115
  Subcommands:
89429
- start Start a workflow run.
89430
- get Fetch status, progress, and per-node summary for a run.
89431
- steps List the individual execution steps of a run, with filters.
89432
- pause Pause an active run.
89433
- resume Resume a paused run.
90116
+ start Start a workflow run.
90117
+ get Fetch status, progress, and per-node summary for a run.
90118
+ steps List the individual execution steps of a run, with filters.
90119
+ pause Pause an active run.
90120
+ resume Resume a paused run.
90121
+ download-file Download a file written by a code node from a run sandbox.
89434
90122
 
89435
90123
  Examples:
89436
90124
  $ clay workflows runs start wf_abc123 | jq -r '.runId'
@@ -89443,6 +90131,224 @@ Examples:
89443
90131
  cmd.addCommand(applyClaySettings(buildStepsCommand()));
89444
90132
  cmd.addCommand(applyClaySettings(buildPauseCommand()));
89445
90133
  cmd.addCommand(applyClaySettings(buildResumeCommand()));
90134
+ cmd.addCommand(applyClaySettings(buildDownloadFileCommand()));
90135
+ return cmd;
90136
+ }
90137
+
90138
+ // src/commands/workflows/snapshots/projection.ts
90139
+ function projectSnapshotSummary(snapshot) {
90140
+ return {
90141
+ id: snapshot.id,
90142
+ hash: snapshot.hash,
90143
+ createdAt: snapshot.createdAt,
90144
+ nodeCount: snapshot.content.nodes.length,
90145
+ edgeCount: snapshot.content.edges.length
90146
+ };
90147
+ }
90148
+ function projectNode(n) {
90149
+ return {
90150
+ id: n.id,
90151
+ name: n.name,
90152
+ description: n.description,
90153
+ nodeType: n.nodeType,
90154
+ isInitial: n.isInitial,
90155
+ isTerminal: n.isTerminal,
90156
+ tools: n.tools,
90157
+ position: n.position,
90158
+ // Coalesce null → undefined so absent optional fields are omitted from the
90159
+ // JSON (matching the help's <object|undefined>) rather than emitted as null.
90160
+ nodeConfig: n.nodeConfig ?? void 0,
90161
+ retryConfig: n.retryConfig ?? void 0,
90162
+ scriptVersionId: n.scriptVersionId ?? void 0,
90163
+ currentScriptVersion: n.currentScriptVersion ?? void 0,
90164
+ claygentSnapshot: n.claygentSnapshot ?? void 0
90165
+ };
90166
+ }
90167
+ function projectEdge(e) {
90168
+ return {
90169
+ id: e.id,
90170
+ sourceNodeId: e.sourceNodeId,
90171
+ targetNodeId: e.targetNodeId,
90172
+ // Rebuild rather than pass through by reference so a future field on the
90173
+ // server edge type does not silently leak into the CLI output.
90174
+ metadata: e.metadata ? { conditionalSourceHandle: e.metadata.conditionalSourceHandle } : null
90175
+ };
90176
+ }
90177
+ function projectSnapshotGraph(snapshot, options = {}) {
90178
+ const { nodeId } = options;
90179
+ const nodes = nodeId === void 0 ? snapshot.content.nodes : snapshot.content.nodes.filter((n) => n.id === nodeId);
90180
+ return {
90181
+ id: snapshot.id,
90182
+ workflowId: snapshot.workflowId,
90183
+ hash: snapshot.hash,
90184
+ createdAt: snapshot.createdAt,
90185
+ containsCycles: snapshot.content.containsCycles,
90186
+ nodes: nodes.map(projectNode),
90187
+ edges: snapshot.content.edges.map(projectEdge)
90188
+ };
90189
+ }
90190
+
90191
+ // src/commands/workflows/snapshots/get.ts
90192
+ function buildGetCommand5() {
90193
+ const cmd = new Command("get");
90194
+ cmd.description("Fetch a single snapshot\u2019s full workflow graph (nodes, edges, agent prompts, code).").argument("<workflowId>", "Workflow id, e.g. wf_abc123").argument("<snapshotId>", "Snapshot id, from `snapshots list`").option("--node-id <id>", 'Only include the node with this id in "nodes" (edges are left intact).').addHelpText(
90195
+ "after",
90196
+ `
90197
+ Output (success, exit 0):
90198
+ {
90199
+ "id": <string>,
90200
+ "workflowId": <string>,
90201
+ "hash": <string>,
90202
+ "createdAt": <string>,
90203
+ "containsCycles": <boolean>,
90204
+ "nodes": [ { "id": <string>, "name": <string>, "description": <string|null>,
90205
+ "nodeType": <string>, "isInitial": <boolean>, "isTerminal": <boolean>,
90206
+ "tools": <array>, "position": { "x": <number>, "y": <number> },
90207
+ "nodeConfig": <object|undefined>, "retryConfig": <object|undefined>,
90208
+ "scriptVersionId": <string|undefined>, "currentScriptVersion": <object|undefined>,
90209
+ "claygentSnapshot": <object|undefined> } ],
90210
+ "edges": [ { "id": <string>, "sourceNodeId": <string>, "targetNodeId": <string>,
90211
+ "metadata": { "conditionalSourceHandle": <string|undefined> } | null } ]
90212
+ }
90213
+
90214
+ "nodes"/"edges" are the captured graph (the documented fields above) \u2014 stable
90215
+ for diffing two \`snapshots get\` outputs with jq (there is no built-in diff).
90216
+ "claygentSnapshot" holds the agent prompt and model/tool settings on agent
90217
+ nodes. An edge's "metadata.conditionalSourceHandle" names the branch handle on
90218
+ a "conditional" source node, so it identifies which branch the edge routes from.
90219
+ A --node-id that matches no node yields "nodes": [] with exit 0 (not an error);
90220
+ "edges" are still returned in full.
90221
+
90222
+ Node type values:
90223
+ agent Claygent (LLM) node
90224
+ code Python code node
90225
+ tool Single-tool action node
90226
+ conditional Branches on a condition expression
90227
+ fork Splits execution into parallel branches
90228
+ join Merges parallel branches
90229
+ map Fans out over a list
90230
+ reduce Aggregates map results
90231
+ collect Collects streamed outputs into a list
90232
+ trigger Workflow entry-point node
90233
+
90234
+ Common errors:
90235
+ validation_error (exit 2) workflowId and snapshotId arguments are required.
90236
+ not_found (exit 6) No workflow or snapshot with that id in this workspace.
90237
+ auth_forbidden (exit 3) API key lacks permission for this command (insufficient scope).
90238
+
90239
+ Examples:
90240
+ $ clay workflows snapshots get wf_abc123 snap_xyz
90241
+ $ clay workflows snapshots get wf_abc123 snap_xyz --node-id node_3 | jq '.nodes[0]'
90242
+ $ clay workflows snapshots get wf_abc123 snap_xyz | jq -r '.nodes[].name'
90243
+ `
90244
+ ).action(async (workflowId, snapshotId, opts) => {
90245
+ const workspaceId = await currentWorkspaceId();
90246
+ const client = await v3Client(terracottaWorkflowsContract);
90247
+ const result = await unwrap(client.getWorkflowSnapshot({ params: { workspaceId, workflowId, snapshotId } }));
90248
+ writeJson(projectSnapshotGraph(result.snapshot, { nodeId: opts.nodeId }));
90249
+ });
90250
+ return cmd;
90251
+ }
90252
+
90253
+ // src/commands/workflows/snapshots/list.ts
90254
+ function buildListCommand7() {
90255
+ const cmd = new Command("list");
90256
+ cmd.description("List a workflow\u2019s snapshots (automatic version history), newest first.").argument("<workflowId>", "Workflow id, e.g. wf_abc123").addHelpText(
90257
+ "after",
90258
+ `
90259
+ Output (success, exit 0):
90260
+ { "data": [ { "id": <string>, "hash": <string>, "createdAt": <string>,
90261
+ "nodeCount": <number>, "edgeCount": <number> } ] }
90262
+
90263
+ Snapshots are an immutable, content-addressed capture of the whole workflow
90264
+ graph, auto-created before every node edit and at run start. They are returned
90265
+ newest-first, so data[0] is the most recent. This is the undo log: find the
90266
+ snapshot from just before a bad change, then \`snapshots get\` to inspect it or
90267
+ \`snapshots restore\` to roll back to it.
90268
+
90269
+ Common errors:
90270
+ validation_error (exit 2) workflowId argument is required.
90271
+ not_found (exit 6) No workflow with that id in this workspace.
90272
+ auth_forbidden (exit 3) API key lacks permission for this command (insufficient scope).
90273
+
90274
+ Examples:
90275
+ $ clay workflows snapshots list wf_abc123
90276
+ $ clay workflows snapshots list wf_abc123 | jq -r '.data[0].id'
90277
+ $ clay workflows snapshots list wf_abc123 | jq '.data | length'
90278
+ `
90279
+ ).action(async (workflowId) => {
90280
+ const workspaceId = await currentWorkspaceId();
90281
+ const client = await v3Client(terracottaWorkflowsContract);
90282
+ const result = await unwrap(client.getWorkflowSnapshots({ params: { workspaceId, workflowId } }));
90283
+ writeJson({ data: result.snapshots.map(projectSnapshotSummary) });
90284
+ });
90285
+ return cmd;
90286
+ }
90287
+
90288
+ // src/commands/workflows/snapshots/restore.ts
90289
+ function buildRestoreCommand() {
90290
+ const cmd = new Command("restore");
90291
+ cmd.description("Restore a workflow to a previous snapshot, replacing its current graph.").argument("<workflowId>", "Workflow id, e.g. wf_abc123").argument("<snapshotId>", "Snapshot id to restore to, from `snapshots list`").addHelpText(
90292
+ "after",
90293
+ `
90294
+ Output (success, exit 0):
90295
+ { "ok": true }
90296
+
90297
+ Overwrites the workflow\u2019s current graph with the snapshot\u2019s. This is the undo
90298
+ action \u2014 pair it with \`snapshots list\` to find the snapshot from just before
90299
+ an unwanted edit. Restore is destructive and does NOT itself snapshot the
90300
+ current graph; the pre-restore state is recoverable only if it was already
90301
+ captured (snapshots are taken automatically before each edit and at run
90302
+ start). Check \`snapshots list\` first if you might need the current graph back.
90303
+
90304
+ Common errors:
90305
+ validation_error (exit 2) workflowId and snapshotId arguments are required.
90306
+ not_found (exit 6) No workflow or snapshot with that id in this workspace.
90307
+ auth_forbidden (exit 3) API key lacks permission for this command (insufficient scope).
90308
+
90309
+ Examples:
90310
+ $ clay workflows snapshots restore wf_abc123 snap_xyz
90311
+ $ clay workflows snapshots list wf_abc123 | jq -r '.data[0].id' | xargs clay workflows snapshots restore wf_abc123
90312
+ `
90313
+ ).action(async (workflowId, snapshotId) => {
90314
+ const workspaceId = await currentWorkspaceId();
90315
+ const client = await v3Client(terracottaWorkflowsContract);
90316
+ const result = await unwrap(
90317
+ client.restoreWorkflowFromSnapshot({ params: { workspaceId, workflowId, snapshotId }, body: {} })
90318
+ );
90319
+ if (!result.success) {
90320
+ throw new IncompatibleApiServerError("Workflow snapshot restore returned success: false.");
90321
+ }
90322
+ writeJson({ ok: true });
90323
+ });
90324
+ return cmd;
90325
+ }
90326
+
90327
+ // src/commands/workflows/snapshots/index.ts
90328
+ function buildSnapshotsCommand() {
90329
+ const cmd = new Command("snapshots");
90330
+ cmd.description("Inspect and restore a workflow\u2019s automatic version history (snapshots).").addHelpText(
90331
+ "after",
90332
+ `
90333
+ Subcommands:
90334
+ list List a workflow\u2019s snapshots, newest first.
90335
+ get Fetch one snapshot\u2019s full graph (with optional --node-id).
90336
+ restore Roll a workflow back to a snapshot.
90337
+
90338
+ Snapshots are git-style autosaves: an immutable, content-addressed capture of the
90339
+ entire workflow graph, taken before every node edit and at run start. They are the
90340
+ undo button for agent-driven editing \u2014 \`list\` to find the snapshot before a bad
90341
+ change, then \`restore\`. There is no built-in diff; compare two \`get\` outputs with jq.
90342
+
90343
+ Examples:
90344
+ $ clay workflows snapshots list wf_abc123 | jq -r '.data[0].id'
90345
+ $ clay workflows snapshots get wf_abc123 snap_xyz | jq '.nodes | length'
90346
+ $ clay workflows snapshots restore wf_abc123 snap_xyz
90347
+ `
90348
+ );
90349
+ cmd.addCommand(applyClaySettings(buildListCommand7()));
90350
+ cmd.addCommand(applyClaySettings(buildGetCommand5()));
90351
+ cmd.addCommand(applyClaySettings(buildRestoreCommand()));
89446
90352
  return cmd;
89447
90353
  }
89448
90354
 
@@ -89453,18 +90359,22 @@ function registerWorkflows(program3) {
89453
90359
  "after",
89454
90360
  `
89455
90361
  Subcommands:
89456
- list List workflows in the workspace.
89457
- get Fetch a workflow by id.
89458
- create Create a new empty workflow.
89459
- runs Start and inspect workflow runs.
90362
+ list List workflows in the workspace.
90363
+ get Fetch a workflow by id.
90364
+ create Create a new empty workflow.
90365
+ runs Start and inspect workflow runs.
90366
+ snapshots Inspect and restore a workflow\u2019s version history.
90367
+ actions Browse the Clay action catalog (node building blocks).
89460
90368
 
89461
90369
  See \`clay workflows <subcommand> --help\` for per-subcommand JSON shape, error codes, and examples.
89462
90370
  `
89463
90371
  );
89464
- workflows.addCommand(applyClaySettings(buildListCommand4()));
90372
+ workflows.addCommand(applyClaySettings(buildListCommand6()));
89465
90373
  workflows.addCommand(applyClaySettings(buildGetCommand3()));
89466
- workflows.addCommand(applyClaySettings(buildCreateCommand()));
90374
+ workflows.addCommand(applyClaySettings(buildCreateCommand2()));
89467
90375
  workflows.addCommand(applyClaySettings(buildRunsCommand2()));
90376
+ workflows.addCommand(applyClaySettings(buildSnapshotsCommand()));
90377
+ workflows.addCommand(applyClaySettings(buildActionsCommand()));
89468
90378
  program3.addCommand(workflows);
89469
90379
  }
89470
90380
 
@@ -89523,11 +90433,11 @@ Authentication:
89523
90433
  1. $CLAY_CONFIG_HOME/clay, if set
89524
90434
  2. $XDG_CONFIG_HOME/clay, if set
89525
90435
  3. ~/.config/clay (default)
89526
- There is no env-var fallback for the API key itself: \`clay login\` is the only way to set a key.
90436
+ If no key is stored, the CLI falls back to the CLAY_API_KEY environment variable (a stored key from \`clay login\` always wins). The env var is the right fit for agents and CI that already export it; the env path is not validated up front, so a bad key surfaces as auth_invalid on the first call.
89527
90437
  Values derived from the key (e.g. the resolved workspace id) are cached alongside in \`<config-dir>/cache.json\`; it is disposable and safe to delete.
89528
90438
 
89529
90439
  Environment variables:
89530
- CLAY_BASE_URL Override the Clay backend base URL (default: https://api.clay.com). Intended for Clay engineers pointing at a local dev or staging deploy.
90440
+ CLAY_API_KEY API key used when none is stored by \`clay login\`. A stored key takes precedence. Surfaces as auth_invalid (exit 3) on first use if invalid.
89531
90441
  CLAY_CONFIG_HOME Override the parent of the config directory. The CLI appends \`clay/\` to it, matching XDG semantics. Useful for isolating tests or alternate setups. Both config.json and the sibling cache.json live under this directory.
89532
90442
  CLAY_REQUEST_TIMEOUT_MS Per-request network timeout in milliseconds (default: 60000). Each HTTP request the CLI makes is bounded by this; on expiry the command fails with network_timeout (exit 5).
89533
90443
  CLAY_UPLOAD_TIMEOUT_MS File-upload timeout in milliseconds (default: 600000). Bounds bulk file uploads (e.g. \`clay tools runs start --bulk\`), which move whole payloads and so get a longer budget than CLAY_REQUEST_TIMEOUT_MS; on expiry the command fails with network_timeout (exit 5).
@@ -89547,6 +90457,7 @@ registerLogout(program2);
89547
90457
  registerTools(program2);
89548
90458
  registerTables(program2);
89549
90459
  registerWorkflows(program2);
90460
+ registerWebhooks(program2);
89550
90461
  registerHelp(program2);
89551
90462
  async function main() {
89552
90463
  try {