@zapier/zapier-sdk-cli 0.68.0 → 0.70.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/cli.cjs CHANGED
@@ -8,14 +8,15 @@ var inquirer = require('inquirer');
8
8
  var chalk8 = require('chalk');
9
9
  var core = require('@inquirer/core');
10
10
  var ora = require('ora');
11
+ var fs = require('fs');
12
+ var path = require('path');
13
+ var isInstalledGlobally = require('is-installed-globally');
11
14
  var util = require('util');
12
- var wrapAnsi3 = require('wrap-ansi');
15
+ var wrapAnsi4 = require('wrap-ansi');
13
16
  var jwt = require('jsonwebtoken');
14
17
  var crossKeychain = require('cross-keychain');
15
18
  var Conf = require('conf');
16
- var fs = require('fs');
17
19
  var crypto = require('crypto');
18
- var path = require('path');
19
20
  var lockfile = require('proper-lockfile');
20
21
  var os = require('os');
21
22
  var express = require('express');
@@ -26,13 +27,14 @@ var zapierSdkMcp = require('@zapier/zapier-sdk-mcp');
26
27
  var esbuild = require('esbuild');
27
28
  var promises = require('fs/promises');
28
29
  var ts = require('typescript');
29
- var isInstalledGlobally = require('is-installed-globally');
30
30
  var child_process = require('child_process');
31
31
  var Handlebars = require('handlebars');
32
32
  var url = require('url');
33
- var experimental = require('@zapier/zapier-sdk/experimental');
34
33
  var packageJsonLib = require('package-json');
35
34
  var semver = require('semver');
35
+ var crossSpawn = require('cross-spawn');
36
+ var Table = require('cli-table3');
37
+ var experimental = require('@zapier/zapier-sdk/experimental');
36
38
  var readline = require('readline');
37
39
 
38
40
  var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
@@ -59,22 +61,24 @@ function _interopNamespace(e) {
59
61
  var inquirer__default = /*#__PURE__*/_interopDefault(inquirer);
60
62
  var chalk8__default = /*#__PURE__*/_interopDefault(chalk8);
61
63
  var ora__default = /*#__PURE__*/_interopDefault(ora);
64
+ var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
65
+ var path__namespace = /*#__PURE__*/_interopNamespace(path);
66
+ var isInstalledGlobally__default = /*#__PURE__*/_interopDefault(isInstalledGlobally);
62
67
  var util__default = /*#__PURE__*/_interopDefault(util);
63
- var wrapAnsi3__default = /*#__PURE__*/_interopDefault(wrapAnsi3);
68
+ var wrapAnsi4__default = /*#__PURE__*/_interopDefault(wrapAnsi4);
64
69
  var jwt__namespace = /*#__PURE__*/_interopNamespace(jwt);
65
70
  var Conf__default = /*#__PURE__*/_interopDefault(Conf);
66
- var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
67
71
  var crypto__default = /*#__PURE__*/_interopDefault(crypto);
68
- var path__namespace = /*#__PURE__*/_interopNamespace(path);
69
72
  var lockfile__namespace = /*#__PURE__*/_interopNamespace(lockfile);
70
73
  var express__default = /*#__PURE__*/_interopDefault(express);
71
74
  var open__default = /*#__PURE__*/_interopDefault(open);
72
75
  var pkceChallenge__default = /*#__PURE__*/_interopDefault(pkceChallenge);
73
76
  var ts__namespace = /*#__PURE__*/_interopNamespace(ts);
74
- var isInstalledGlobally__default = /*#__PURE__*/_interopDefault(isInstalledGlobally);
75
77
  var Handlebars__default = /*#__PURE__*/_interopDefault(Handlebars);
76
78
  var packageJsonLib__default = /*#__PURE__*/_interopDefault(packageJsonLib);
77
79
  var semver__default = /*#__PURE__*/_interopDefault(semver);
80
+ var crossSpawn__default = /*#__PURE__*/_interopDefault(crossSpawn);
81
+ var Table__default = /*#__PURE__*/_interopDefault(Table);
78
82
  var readline__namespace = /*#__PURE__*/_interopNamespace(readline);
79
83
 
80
84
  var __defProp = Object.defineProperty;
@@ -236,11 +240,21 @@ async function promptText({
236
240
  password
237
241
  }) {
238
242
  const { value } = await inquirer__default.default.prompt([
239
- { type: password ? "password" : "input", name: "value", message }
243
+ {
244
+ type: password ? "password" : "input",
245
+ name: "value",
246
+ message,
247
+ theme: HIGH_CONTRAST_PROMPT_THEME
248
+ }
240
249
  ]);
241
250
  return value;
242
251
  }
243
252
  var display = (c) => c.hint ? `${c.label} ${chalk8__default.default.dim(`(${c.hint})`)}` : c.label;
253
+ var HIGH_CONTRAST_PROMPT_THEME = {
254
+ style: {
255
+ answer: (text) => chalk8__default.default.inverse.bold(` ${text} `)
256
+ }
257
+ };
244
258
  function buildSelectRows(question, term) {
245
259
  const row = (name, action) => ({
246
260
  name,
@@ -307,9 +321,39 @@ function foldPage(acc, question, field) {
307
321
  checked: []
308
322
  };
309
323
  }
310
- async function answerSelect(question, field, box, failed = false) {
324
+ async function answerSelect(question, field, box, failed, mode) {
311
325
  const acc = failed ? void 0 : box.acc = foldPage(box.acc, question, field);
312
326
  const view = acc ? { ...question, choices: acc.choices } : question;
327
+ const isClosedListPrompt = mode === "closed-list" && !failed && !view.multiple;
328
+ const booleanValues = view.choices.map(({ value: value2 }) => value2);
329
+ if (isClosedListPrompt && booleanValues.length === 2 && booleanValues.includes("true") && booleanValues.includes("false")) {
330
+ const { value: value2 } = await inquirer__default.default.prompt([
331
+ {
332
+ type: "confirm",
333
+ name: "value",
334
+ message: view.message,
335
+ default: booleanValues[0] === "true",
336
+ theme: HIGH_CONTRAST_PROMPT_THEME
337
+ }
338
+ ]);
339
+ return { type: "choose", value: String(value2) };
340
+ }
341
+ if (isClosedListPrompt && view.choices.length > 0 && !offers(view, "search") && !offers(view, "next_page") && !offers(view, "retry")) {
342
+ const choices = view.choices.map((choice) => ({
343
+ name: display(choice),
344
+ value: choice.value
345
+ }));
346
+ const { value: value2 } = await inquirer__default.default.prompt([
347
+ {
348
+ type: "list",
349
+ name: "value",
350
+ message: view.message,
351
+ choices,
352
+ theme: HIGH_CONTRAST_PROMPT_THEME
353
+ }
354
+ ]);
355
+ return { type: "choose", value: value2 };
356
+ }
313
357
  if (question.multiple && acc) {
314
358
  if (acc.newStart > 0 && process.stdout.isTTY) {
315
359
  process.stdout.write("\x1B[1A\x1B[2K");
@@ -333,7 +377,13 @@ async function answerSelect(question, field, box, failed = false) {
333
377
  }))
334
378
  ];
335
379
  const { values } = await inquirer__default.default.prompt([
336
- { type: "checkbox", name: "values", message: question.message, choices }
380
+ {
381
+ type: "checkbox",
382
+ name: "values",
383
+ message: question.message,
384
+ choices,
385
+ theme: HIGH_CONTRAST_PROMPT_THEME
386
+ }
337
387
  ]);
338
388
  const selected = values;
339
389
  const picked = selected.filter((v) => !isActionRow(v));
@@ -428,7 +478,8 @@ async function answerCollection(question) {
428
478
  type: "confirm",
429
479
  name: "again",
430
480
  message: question.message,
431
- default: false
481
+ default: false,
482
+ theme: HIGH_CONTRAST_PROMPT_THEME
432
483
  }
433
484
  ]);
434
485
  return again ? { type: "add" } : { type: "done" };
@@ -443,22 +494,37 @@ function withEngineSpinner(answer, spinner) {
443
494
  }
444
495
  };
445
496
  }
446
- function createCliAnswer() {
497
+ function createCliAnswer({
498
+ mode = "search"
499
+ } = {}) {
447
500
  const box = {};
448
- return ({ result }) => {
449
- if (result.error !== void 0) {
450
- const message = typeof result.error === "string" ? result.error : result.error.message;
451
- console.log(chalk8__default.default.yellow(`! ${message}`));
452
- }
453
- const question = result.question;
454
- const field = question.path.length ? question.path.join(".") : "value";
455
- switch (question.type) {
456
- case "select":
457
- return answerSelect(question, field, box, result.status === "failed");
458
- case "input":
459
- return answerInput(question);
460
- case "collection":
461
- return answerCollection(question);
501
+ return async ({ result }) => {
502
+ try {
503
+ if (result.error !== void 0) {
504
+ const message = typeof result.error === "string" ? result.error : result.error.message;
505
+ console.log(chalk8__default.default.yellow(`! ${message}`));
506
+ }
507
+ const question = result.question;
508
+ const field = question.path.length ? question.path.join(".") : "value";
509
+ switch (question.type) {
510
+ case "select":
511
+ return await answerSelect(
512
+ question,
513
+ field,
514
+ box,
515
+ result.status === "failed",
516
+ mode
517
+ );
518
+ case "input":
519
+ return await answerInput(question);
520
+ case "collection":
521
+ return await answerCollection(question);
522
+ }
523
+ } catch (error) {
524
+ if (error instanceof Error && error.name === "ExitPromptError") {
525
+ return { type: "cancel" };
526
+ }
527
+ throw error;
462
528
  }
463
529
  };
464
530
  }
@@ -536,7 +602,86 @@ var SHARED_COMMAND_CLI_OPTIONS = [
536
602
 
537
603
  // package.json
538
604
  var package_default = {
539
- version: "0.68.0"};
605
+ version: "0.70.0"};
606
+ var PACKAGE_MANAGERS = ["npm", "pnpm", "yarn", "bun"];
607
+ var LOCKFILES = [
608
+ ["pnpm-lock.yaml", "pnpm"],
609
+ ["yarn.lock", "yarn"],
610
+ ["bun.lock", "bun"],
611
+ ["bun.lockb", "bun"],
612
+ ["package-lock.json", "npm"]
613
+ ];
614
+ function readDeclaredPackageManager(cwd) {
615
+ try {
616
+ const manifest = JSON.parse(
617
+ fs.readFileSync(path.join(cwd, "package.json"), "utf8")
618
+ );
619
+ if (typeof manifest !== "object" || manifest === null || !("packageManager" in manifest) || typeof manifest.packageManager !== "string") {
620
+ return void 0;
621
+ }
622
+ const [name] = manifest.packageManager.split("@", 1);
623
+ return PACKAGE_MANAGERS.find((packageManager) => packageManager === name);
624
+ } catch {
625
+ return void 0;
626
+ }
627
+ }
628
+ function detectPackageManager(cwd = process.cwd()) {
629
+ const lockfileManagers = new Set(
630
+ LOCKFILES.filter(([file]) => fs.existsSync(path.join(cwd, file))).map(
631
+ ([, packageManager]) => packageManager
632
+ )
633
+ );
634
+ if (lockfileManagers.size === 1) {
635
+ return { name: [...lockfileManagers][0], source: "lockfile" };
636
+ }
637
+ const declaredPackageManager = readDeclaredPackageManager(cwd);
638
+ if (declaredPackageManager) {
639
+ return { name: declaredPackageManager, source: "package-json" };
640
+ }
641
+ const userAgent = process.env.npm_config_user_agent;
642
+ if (userAgent) {
643
+ if (userAgent.includes("yarn")) {
644
+ return { name: "yarn", source: "runtime" };
645
+ }
646
+ if (userAgent.includes("pnpm")) {
647
+ return { name: "pnpm", source: "runtime" };
648
+ }
649
+ if (userAgent.includes("bun")) {
650
+ return { name: "bun", source: "runtime" };
651
+ }
652
+ if (userAgent.includes("npm")) {
653
+ return { name: "npm", source: "runtime" };
654
+ }
655
+ }
656
+ return { name: "npm", source: "fallback" };
657
+ }
658
+ function getUpdateCommand(packageName) {
659
+ const pm = detectPackageManager();
660
+ const isGlobal = isInstalledGlobally__default.default;
661
+ if (isGlobal) {
662
+ switch (pm.name) {
663
+ case "yarn":
664
+ return `yarn global upgrade ${packageName}@latest`;
665
+ case "pnpm":
666
+ return `pnpm update -g ${packageName}@latest`;
667
+ case "bun":
668
+ return `bun update -g ${packageName}@latest`;
669
+ default:
670
+ return `npm install -g ${packageName}@latest`;
671
+ }
672
+ } else {
673
+ switch (pm.name) {
674
+ case "yarn":
675
+ return `yarn upgrade ${packageName}@latest`;
676
+ case "pnpm":
677
+ return `pnpm update ${packageName}@latest`;
678
+ case "bun":
679
+ return `bun update ${packageName}@latest`;
680
+ default:
681
+ return `npm install ${packageName}@latest`;
682
+ }
683
+ }
684
+ }
540
685
 
541
686
  // src/telemetry/builders.ts
542
687
  function createCliBaseEvent(context = {}) {
@@ -584,8 +729,7 @@ function buildCliCommandExecutedEvent({
584
729
  ci_platform: zapierSdk.getCiPlatform(),
585
730
  ...zapierSdk.getTtyContext(),
586
731
  agent: zapierSdk.getAgent(),
587
- package_manager: data.package_manager ?? "pnpm",
588
- // Default based on project setup
732
+ package_manager: data.package_manager ?? detectPackageManager(process.cwd()).name,
589
733
  made_network_requests: data.made_network_requests ?? null,
590
734
  files_modified_count: data.files_modified_count ?? null,
591
735
  files_created_count: data.files_created_count ?? null,
@@ -679,7 +823,7 @@ var DETAIL_INDENT = " ";
679
823
  var DETAIL_MAX_LINES = 5;
680
824
  function formatDetailText(text, indent = DETAIL_INDENT) {
681
825
  const columns = Math.max((process.stdout.columns || 80) - indent.length, 40);
682
- const wrapped = wrapAnsi3__default.default(text, columns, { hard: true, trim: false });
826
+ const wrapped = wrapAnsi4__default.default(text, columns, { hard: true, trim: false });
683
827
  const lines = wrapped.split("\n");
684
828
  if (lines.length <= DETAIL_MAX_LINES) {
685
829
  return lines.join("\n" + indent);
@@ -722,6 +866,9 @@ function formatItemsGeneric(items, startingNumber = 0) {
722
866
  function toKebabCase(str) {
723
867
  return str.replace(/([A-Z]+)([A-Z][a-z])/g, "$1-$2").replace(/([a-z\d])([A-Z])/g, "$1-$2").toLowerCase();
724
868
  }
869
+ function kebabToCamelCase(str) {
870
+ return str.replace(/-([a-z])/g, (match) => match[1].toUpperCase());
871
+ }
725
872
  function formatMissingParamsError(error) {
726
873
  return [
727
874
  "Missing required parameters:",
@@ -1117,6 +1264,18 @@ function resolveOutputMode({
1117
1264
  if (hasUserSpecifiedMaxItems) return "collect";
1118
1265
  return "paginate";
1119
1266
  }
1267
+ function negationKebabName(param) {
1268
+ if (param.negatable === true) return `no-${toKebabCase(param.name)}`;
1269
+ if (typeof param.negatable === "string") return toKebabCase(param.negatable);
1270
+ return void 0;
1271
+ }
1272
+ function antonymAttributeName(param) {
1273
+ const negationKebab = negationKebabName(param);
1274
+ if (negationKebab === void 0 || negationKebab.startsWith("no-")) {
1275
+ return void 0;
1276
+ }
1277
+ return kebabToCamelCase(negationKebab);
1278
+ }
1120
1279
  function takesPositionalSlot(param) {
1121
1280
  return param.required || !!param.isPositional && !param.isDeprecated && !param.isAlias;
1122
1281
  }
@@ -1229,7 +1388,8 @@ function analyzeZodField(name, schema) {
1229
1388
  isPositional: zapierSdk.isPositional(schema),
1230
1389
  elementType,
1231
1390
  deprecationMessage,
1232
- isDeprecated
1391
+ isDeprecated,
1392
+ negatable: zapierSdk.getNegatable(schema)
1233
1393
  };
1234
1394
  }
1235
1395
  function positionalProjection(schema, positional) {
@@ -1614,15 +1774,25 @@ function collect(value, previous = []) {
1614
1774
  return previous;
1615
1775
  }
1616
1776
  function addCommand(program2, commandName, config2) {
1617
- const command = program2.command(commandName, { hidden: config2.hidden ?? false }).description(config2.description);
1777
+ const command = program2.command(commandName, { hidden: config2.hidden ?? false }).description(config2.description).allowExcessArguments(false);
1618
1778
  let hasPositionalArray = false;
1779
+ const lastPositionalParamName = [...config2.parameters].reverse().find(takesPositionalSlot)?.name;
1780
+ const booleanFlags2 = [];
1619
1781
  config2.parameters.forEach((param) => {
1620
1782
  const kebabName = toKebabCase(param.name);
1621
1783
  if (param.promptable && param.required) {
1622
- command.argument(
1623
- `[${kebabName}]`,
1624
- param.description || `${kebabName} parameter`
1625
- );
1784
+ if (param.type === "array" && !hasPositionalArray && param.name === lastPositionalParamName) {
1785
+ hasPositionalArray = true;
1786
+ command.argument(
1787
+ `[${kebabName}...]`,
1788
+ param.description || `${kebabName} parameter`
1789
+ );
1790
+ } else {
1791
+ command.argument(
1792
+ `[${kebabName}]`,
1793
+ param.description || `${kebabName} parameter`
1794
+ );
1795
+ }
1626
1796
  } else if (param.required && param.type === "array" && !hasPositionalArray) {
1627
1797
  hasPositionalArray = true;
1628
1798
  command.argument(
@@ -1659,6 +1829,24 @@ function addCommand(program2, commandName, config2) {
1659
1829
  const opt = new commander.Option(flags.join(", "), param.description);
1660
1830
  if (param.isDeprecated) opt.hideHelp();
1661
1831
  command.addOption(opt);
1832
+ const negationKebab = negationKebabName(param);
1833
+ if (negationKebab !== void 0) {
1834
+ const negation = new commander.Option(
1835
+ `--${negationKebab}`,
1836
+ `Disable --${kebabName}`
1837
+ );
1838
+ if (!negationKebab.startsWith("no-")) {
1839
+ negation.conflicts(param.name);
1840
+ }
1841
+ if (param.isDeprecated) negation.hideHelp();
1842
+ command.addOption(negation);
1843
+ }
1844
+ booleanFlags2.push({
1845
+ kebabName,
1846
+ attributeName: param.name,
1847
+ negationKebab,
1848
+ shortAlias: alias && alias.length === 1 ? alias : void 0
1849
+ });
1662
1850
  } else if (param.type === "array") {
1663
1851
  const flagSignature = flags.join(", ") + ` <value>`;
1664
1852
  const opt = new commander.Option(flagSignature, param.description || "");
@@ -1688,24 +1876,128 @@ function addCommand(program2, commandName, config2) {
1688
1876
  if (config2.supportsJsonOutput === false && opt.name === "json") return;
1689
1877
  command.option(opt.flag, opt.description);
1690
1878
  });
1879
+ if (booleanFlags2.length > 0) {
1880
+ addBooleanFlagErrorHints({ command, booleanFlags: booleanFlags2 });
1881
+ rejectBooleanFlagValues({ command, booleanFlags: booleanFlags2 });
1882
+ }
1691
1883
  command.action(config2.handler);
1692
1884
  }
1885
+ function booleanFlagUsageHint(flag) {
1886
+ return flag.negationKebab !== void 0 ? `use --${flag.kebabName} to enable or --${flag.negationKebab} to disable` : `pass --${flag.kebabName} to enable or omit it`;
1887
+ }
1888
+ function addBooleanFlagErrorHints({
1889
+ command,
1890
+ booleanFlags: booleanFlags2
1891
+ }) {
1892
+ const originalError = command.error.bind(command);
1893
+ command.error = (message, errorOptions) => originalError(
1894
+ appendBooleanFlagHint({
1895
+ message,
1896
+ code: errorOptions?.code,
1897
+ command,
1898
+ booleanFlags: booleanFlags2
1899
+ }),
1900
+ errorOptions
1901
+ );
1902
+ }
1903
+ function rejectBooleanFlagValues({
1904
+ command,
1905
+ booleanFlags: booleanFlags2
1906
+ }) {
1907
+ command.hook("preAction", (_thisCommand, actionCommand) => {
1908
+ let root = actionCommand;
1909
+ while (root.parent) root = root.parent;
1910
+ const { rawArgs } = root;
1911
+ const terminatorIndex = rawArgs.indexOf("--");
1912
+ const tokens = terminatorIndex === -1 ? rawArgs : rawArgs.slice(0, terminatorIndex);
1913
+ for (const flag of booleanFlags2) {
1914
+ const spellings = new Set(
1915
+ [
1916
+ `--${flag.kebabName}`,
1917
+ flag.negationKebab === void 0 ? void 0 : `--${flag.negationKebab}`,
1918
+ flag.shortAlias === void 0 ? void 0 : `-${flag.shortAlias}`
1919
+ ].filter((spelling) => spelling !== void 0)
1920
+ );
1921
+ for (let i = 0; i < tokens.length - 1; i++) {
1922
+ if (!spellings.has(tokens[i])) continue;
1923
+ const next = tokens[i + 1].trim().toLowerCase();
1924
+ if (!BOOLEAN_TRUE_TOKENS.has(next) && !BOOLEAN_FALSE_TOKENS.has(next)) {
1925
+ continue;
1926
+ }
1927
+ actionCommand.error(
1928
+ `error: ${tokens[i]} is a boolean flag and takes no value, but was followed by '${tokens[i + 1]}': ${booleanFlagUsageHint(flag)}.`,
1929
+ { code: "zapierSdk.booleanFlagValue" }
1930
+ );
1931
+ }
1932
+ }
1933
+ });
1934
+ }
1935
+ function appendBooleanFlagHint({
1936
+ message,
1937
+ code,
1938
+ command,
1939
+ booleanFlags: booleanFlags2
1940
+ }) {
1941
+ if (code === "commander.unknownOption") {
1942
+ const flagWithValue = message.match(/'--([^=']+)=/);
1943
+ if (!flagWithValue) return message;
1944
+ const typedName = flagWithValue[1];
1945
+ const flag = booleanFlags2.find(
1946
+ (candidate) => candidate.kebabName === typedName || candidate.negationKebab === typedName
1947
+ );
1948
+ if (flag === void 0) return message;
1949
+ return `${message}
1950
+ (--${typedName} is a boolean flag and takes no value: ${booleanFlagUsageHint(flag)}.)`;
1951
+ }
1952
+ if (code === "commander.excessArguments") {
1953
+ const excessOperands = command.args.slice(
1954
+ command.registeredArguments.length
1955
+ );
1956
+ const strayBooleanToken = excessOperands.find((token) => {
1957
+ const normalized = token.trim().toLowerCase();
1958
+ return BOOLEAN_TRUE_TOKENS.has(normalized) || BOOLEAN_FALSE_TOKENS.has(normalized);
1959
+ });
1960
+ if (strayBooleanToken === void 0) return message;
1961
+ const usedBooleanFlag = booleanFlags2.find(
1962
+ (flag) => [flag.attributeName, flag.negationKebab].filter((name) => name !== void 0).some(
1963
+ (name) => command.getOptionValueSource(kebabToCamelCase(name)) === "cli"
1964
+ )
1965
+ );
1966
+ if (usedBooleanFlag === void 0) return message;
1967
+ return `${message}
1968
+ (Boolean flags take no value, so '${strayBooleanToken}' was read as an extra argument: ${booleanFlagUsageHint(usedBooleanFlag)}.)`;
1969
+ }
1970
+ return message;
1971
+ }
1693
1972
  function convertCliArgsToSdkParams(parameters, positionalArgs, options) {
1694
1973
  const sdkParams = {};
1695
1974
  let argIndex = 0;
1696
1975
  parameters.forEach((param) => {
1697
1976
  if (takesPositionalSlot(param) && argIndex < positionalArgs.length) {
1977
+ const positionalValue = positionalArgs[argIndex];
1978
+ argIndex++;
1979
+ if (Array.isArray(positionalValue) && positionalValue.length === 0) {
1980
+ return;
1981
+ }
1698
1982
  sdkParams[param.name] = convertValue(
1699
- positionalArgs[argIndex],
1983
+ positionalValue,
1700
1984
  param.type,
1701
1985
  param.elementType
1702
1986
  );
1703
- argIndex++;
1704
1987
  }
1705
1988
  });
1706
1989
  Object.entries(options).forEach(([key, value]) => {
1707
1990
  const camelKey = key.replace(/-([a-z])/g, (g) => g[1].toUpperCase());
1708
1991
  const param = parameters.find((p) => p.name === camelKey);
1992
+ if (param === void 0 && value === true) {
1993
+ const antonymTarget = parameters.find(
1994
+ (p) => antonymAttributeName(p) === camelKey
1995
+ );
1996
+ if (antonymTarget && sdkParams[antonymTarget.name] === void 0) {
1997
+ sdkParams[antonymTarget.name] = false;
1998
+ }
1999
+ return;
2000
+ }
1709
2001
  if (param && value !== void 0) {
1710
2002
  if (sdkParams[camelKey] !== void 0) {
1711
2003
  return;
@@ -1718,6 +2010,16 @@ function convertCliArgsToSdkParams(parameters, positionalArgs, options) {
1718
2010
  });
1719
2011
  return sdkParams;
1720
2012
  }
2013
+ var BOOLEAN_TRUE_TOKENS = /* @__PURE__ */ new Set(["true", "1", "yes", "y", "on"]);
2014
+ var BOOLEAN_FALSE_TOKENS = /* @__PURE__ */ new Set(["false", "0", "no", "n", "off"]);
2015
+ function parseCliBoolean(value) {
2016
+ const normalized = value.trim().toLowerCase();
2017
+ if (BOOLEAN_TRUE_TOKENS.has(normalized)) return true;
2018
+ if (BOOLEAN_FALSE_TOKENS.has(normalized)) return false;
2019
+ throw new commander.InvalidArgumentError(
2020
+ `Expected a boolean (true or false), received "${value}".`
2021
+ );
2022
+ }
1721
2023
  function convertValue(value, type, elementType) {
1722
2024
  if (value === void 0) {
1723
2025
  return void 0;
@@ -1726,7 +2028,7 @@ function convertValue(value, type, elementType) {
1726
2028
  case "number":
1727
2029
  return Number(value);
1728
2030
  case "boolean":
1729
- return Boolean(value);
2031
+ return typeof value === "string" ? parseCliBoolean(value) : Boolean(value);
1730
2032
  case "array": {
1731
2033
  const arr = Array.isArray(value) ? value : [value];
1732
2034
  if (elementType !== "object") return arr;
@@ -5757,54 +6059,6 @@ var InitSchema = zod.z.object({
5757
6059
  }).describe(
5758
6060
  "Create a new Zapier SDK project in a new directory with starter files"
5759
6061
  );
5760
- function detectPackageManager(cwd = process.cwd()) {
5761
- const ua = process.env.npm_config_user_agent;
5762
- if (ua) {
5763
- if (ua.includes("yarn")) return { name: "yarn", source: "runtime" };
5764
- if (ua.includes("pnpm")) return { name: "pnpm", source: "runtime" };
5765
- if (ua.includes("bun")) return { name: "bun", source: "runtime" };
5766
- if (ua.includes("npm")) return { name: "npm", source: "runtime" };
5767
- }
5768
- const files = [
5769
- ["pnpm-lock.yaml", "pnpm"],
5770
- ["yarn.lock", "yarn"],
5771
- ["bun.lockb", "bun"],
5772
- ["package-lock.json", "npm"]
5773
- ];
5774
- for (const [file, name] of files) {
5775
- if (fs.existsSync(path.join(cwd, file))) {
5776
- return { name, source: "lockfile" };
5777
- }
5778
- }
5779
- return { name: "unknown", source: "fallback" };
5780
- }
5781
- function getUpdateCommand(packageName) {
5782
- const pm = detectPackageManager();
5783
- const isGlobal = isInstalledGlobally__default.default;
5784
- if (isGlobal) {
5785
- switch (pm.name) {
5786
- case "yarn":
5787
- return `yarn global upgrade ${packageName}@latest`;
5788
- case "pnpm":
5789
- return `pnpm update -g ${packageName}@latest`;
5790
- case "bun":
5791
- return `bun update -g ${packageName}@latest`;
5792
- default:
5793
- return `npm install -g ${packageName}@latest`;
5794
- }
5795
- } else {
5796
- switch (pm.name) {
5797
- case "yarn":
5798
- return `yarn upgrade ${packageName}@latest`;
5799
- case "pnpm":
5800
- return `pnpm update ${packageName}@latest`;
5801
- case "bun":
5802
- return `bun update ${packageName}@latest`;
5803
- default:
5804
- return `npm install ${packageName}@latest`;
5805
- }
5806
- }
5807
- }
5808
6062
  function getDirentParentPath(entry) {
5809
6063
  const e = entry;
5810
6064
  const parent = e.parentPath ?? e.path;
@@ -6201,17 +6455,16 @@ var initPlugin = zapierSdk.defineMethod({
6201
6455
  const cwd = process.cwd();
6202
6456
  const { projectName, projectDir } = validateInitOptions({ rawName, cwd });
6203
6457
  const displayHooks = createConsoleDisplayHooks();
6204
- const packageManagerInfo = detectPackageManager(cwd);
6205
- if (packageManagerInfo.name === "unknown") {
6458
+ const packageManager = detectPackageManager(cwd);
6459
+ if (packageManager.source === "fallback") {
6206
6460
  displayHooks.onWarn(
6207
6461
  "Could not detect package manager, defaulting to npm."
6208
6462
  );
6209
6463
  }
6210
- const packageManager = packageManagerInfo.name === "unknown" ? "npm" : packageManagerInfo.name;
6211
6464
  const steps = getInitSteps({
6212
6465
  projectDir,
6213
6466
  projectName,
6214
- packageManager,
6467
+ packageManager: packageManager.name,
6215
6468
  displayHooks
6216
6469
  });
6217
6470
  const completedSetupStepIds = [];
@@ -6239,50 +6492,1378 @@ var initPlugin = zapierSdk.defineMethod({
6239
6492
  projectName,
6240
6493
  steps,
6241
6494
  completedSetupStepIds,
6242
- packageManager
6495
+ packageManager: packageManager.name
6243
6496
  });
6244
6497
  }
6245
6498
  });
6246
- var CliSkipLeaseExpireError = class extends Error {
6247
- constructor() {
6248
- super("user skipped (let lease expire)");
6249
- this.name = "CliSkipLeaseExpireError";
6499
+ var ONE_DAY_MILLISECONDS = 24 * 60 * 60 * 1e3;
6500
+ var CACHE_RESET_INTERVAL_MILLISECONDS = (() => {
6501
+ const {
6502
+ ZAPIER_SDK_UPDATE_CHECK_INTERVAL_SECONDS,
6503
+ ZAPIER_SDK_UPDATE_CHECK_INTERVAL_MS
6504
+ } = process.env;
6505
+ let intervalMs;
6506
+ if (ZAPIER_SDK_UPDATE_CHECK_INTERVAL_SECONDS !== void 0) {
6507
+ const seconds = parseInt(ZAPIER_SDK_UPDATE_CHECK_INTERVAL_SECONDS);
6508
+ intervalMs = isNaN(seconds) ? NaN : seconds * 1e3;
6509
+ } else if (ZAPIER_SDK_UPDATE_CHECK_INTERVAL_MS !== void 0) {
6510
+ intervalMs = parseInt(ZAPIER_SDK_UPDATE_CHECK_INTERVAL_MS);
6511
+ } else {
6512
+ intervalMs = ONE_DAY_MILLISECONDS;
6250
6513
  }
6251
- };
6252
- function createInteractiveCallback() {
6253
- let messageNumber = 0;
6254
- return async (message) => {
6255
- messageNumber++;
6256
- const attrs = message.message_attributes;
6257
- console.log(
6258
- `
6259
- ${chalk8__default.default.bold(`Message #${messageNumber}`)} ${chalk8__default.default.dim(message.id)} ${chalk8__default.default.dim(`(lease #${attrs.lease_count})`)}`
6260
- );
6261
- if (attrs.error_message) {
6262
- console.log(chalk8__default.default.yellow(` upstream error: ${attrs.error_message}`));
6514
+ if (isNaN(intervalMs) || intervalMs < 0) {
6515
+ return -1;
6516
+ }
6517
+ return intervalMs;
6518
+ })();
6519
+ function getVersionCache() {
6520
+ try {
6521
+ const cache = getConfig().get("version_cache");
6522
+ const now = Date.now();
6523
+ if (!cache || !cache.last_reset_timestamp || now - cache.last_reset_timestamp >= CACHE_RESET_INTERVAL_MILLISECONDS) {
6524
+ const newCache = {
6525
+ last_reset_timestamp: now,
6526
+ packages: {}
6527
+ };
6528
+ getConfig().set("version_cache", newCache);
6529
+ return newCache;
6263
6530
  }
6264
- if (attrs.possible_duplicate_data) {
6265
- console.log(chalk8__default.default.yellow(" possible duplicate data"));
6531
+ return cache;
6532
+ } catch (error) {
6533
+ log_default.debug(`Failed to read version cache: ${error}`);
6534
+ return {
6535
+ last_reset_timestamp: Date.now(),
6536
+ packages: {}
6537
+ };
6538
+ }
6539
+ }
6540
+ function setCachedPackageInfo(packageName, version, info) {
6541
+ try {
6542
+ const cache = getVersionCache();
6543
+ if (!cache.packages[packageName]) {
6544
+ cache.packages[packageName] = {};
6266
6545
  }
6267
- while (true) {
6268
- let action;
6269
- try {
6270
- const answer = await inquirer__default.default.prompt([
6271
- {
6272
- type: "list",
6273
- name: "action",
6274
- message: "Action?",
6275
- choices: [
6276
- { name: "Ack (remove from inbox)", value: "ack" },
6277
- {
6278
- name: "Skip (release after draining)",
6279
- value: "skip-release"
6280
- },
6281
- { name: "Skip (let lease expire)", value: "skip-expire" },
6282
- { name: "View payload", value: "view" },
6283
- { name: "Quit", value: "quit" }
6284
- ]
6285
- }
6546
+ cache.packages[packageName][version] = info;
6547
+ getConfig().set("version_cache", cache);
6548
+ } catch (error) {
6549
+ log_default.debug(`Failed to cache package info: ${error}`);
6550
+ }
6551
+ }
6552
+ function getCachedPackageInfo(packageName, version) {
6553
+ try {
6554
+ const cache = getVersionCache();
6555
+ return cache.packages[packageName]?.[version];
6556
+ } catch (error) {
6557
+ log_default.debug(`Failed to get cached package info: ${error}`);
6558
+ return void 0;
6559
+ }
6560
+ }
6561
+ async function fetchCachedPackageInfo(packageName, version) {
6562
+ const cacheKey = version || "latest";
6563
+ let cachedInfo = getCachedPackageInfo(packageName, cacheKey);
6564
+ if (cachedInfo) {
6565
+ return cachedInfo;
6566
+ }
6567
+ const packageInfo = await packageJsonLib__default.default(packageName, {
6568
+ version,
6569
+ fullMetadata: true
6570
+ });
6571
+ const info = {
6572
+ version: packageInfo.version,
6573
+ deprecated: packageInfo.deprecated,
6574
+ fetched_at: (/* @__PURE__ */ new Date()).toISOString()
6575
+ };
6576
+ setCachedPackageInfo(packageName, cacheKey, info);
6577
+ return info;
6578
+ }
6579
+ async function checkForUpdates({
6580
+ packageName,
6581
+ currentVersion
6582
+ }) {
6583
+ try {
6584
+ const latestPackageInfo = await fetchCachedPackageInfo(packageName);
6585
+ const latestVersion = latestPackageInfo.version;
6586
+ const hasUpdate = semver__default.default.gt(latestVersion, currentVersion);
6587
+ let currentPackageInfo;
6588
+ try {
6589
+ currentPackageInfo = await fetchCachedPackageInfo(
6590
+ packageName,
6591
+ currentVersion
6592
+ );
6593
+ } catch (error) {
6594
+ if (!(error instanceof packageJsonLib.VersionNotFoundError)) {
6595
+ log_default.debug(`Failed to check deprecation for current version: ${error}`);
6596
+ }
6597
+ currentPackageInfo = latestPackageInfo;
6598
+ }
6599
+ const isDeprecated = Boolean(currentPackageInfo.deprecated);
6600
+ const deprecationMessage = isDeprecated ? String(currentPackageInfo.deprecated) : void 0;
6601
+ return {
6602
+ hasUpdate,
6603
+ latestVersion,
6604
+ currentVersion,
6605
+ isDeprecated,
6606
+ deprecationMessage
6607
+ };
6608
+ } catch (error) {
6609
+ log_default.debug(`Failed to check for updates: ${error}`);
6610
+ return {
6611
+ hasUpdate: false,
6612
+ currentVersion,
6613
+ isDeprecated: false
6614
+ };
6615
+ }
6616
+ }
6617
+ function displayUpdateNotification(versionInfo, packageName) {
6618
+ if (versionInfo.isDeprecated) {
6619
+ console.error();
6620
+ console.error(
6621
+ chalk8__default.default.red.bold("\u26A0\uFE0F DEPRECATION WARNING") + chalk8__default.default.red(
6622
+ ` - ${packageName} v${versionInfo.currentVersion} is deprecated.`
6623
+ )
6624
+ );
6625
+ if (versionInfo.deprecationMessage) {
6626
+ console.error(chalk8__default.default.red(` ${versionInfo.deprecationMessage}`));
6627
+ }
6628
+ console.error(chalk8__default.default.red(` Please update to the latest version.`));
6629
+ console.error();
6630
+ }
6631
+ if (versionInfo.hasUpdate) {
6632
+ console.error();
6633
+ console.error(
6634
+ chalk8__default.default.yellow.bold("\u{1F4E6} Update available!") + chalk8__default.default.yellow(
6635
+ ` ${packageName} v${versionInfo.currentVersion} \u2192 v${versionInfo.latestVersion}`
6636
+ )
6637
+ );
6638
+ console.error(
6639
+ chalk8__default.default.yellow(
6640
+ ` Run ${chalk8__default.default.bold(getUpdateCommand(packageName))} to update.`
6641
+ )
6642
+ );
6643
+ console.error();
6644
+ }
6645
+ }
6646
+ async function checkAndNotifyUpdates({
6647
+ packageName,
6648
+ currentVersion
6649
+ }) {
6650
+ if (CACHE_RESET_INTERVAL_MILLISECONDS < 0) {
6651
+ return;
6652
+ }
6653
+ const versionInfo = await checkForUpdates({ packageName, currentVersion });
6654
+ displayUpdateNotification(versionInfo, packageName);
6655
+ }
6656
+ var BRAILLE_BLANK = "\u2800";
6657
+ var LIGHTNING_INTERVAL_MILLISECONDS = 140;
6658
+ var boltRows = [
6659
+ "\u2800\u2800\u2880\u28FE\u2800\u2800\u2800\u2800",
6660
+ "\u2800\u2800\u28E0\u28FF\u28FF\u2800\u2800\u2800",
6661
+ "\u2800\u28FC\u28FF\u28FF\u28FF\u28C0\u28C0\u2840",
6662
+ "\u2808\u2809\u2809\u28FF\u28FF\u28FF\u285F\u2800",
6663
+ "\u2800\u2800\u2800\u28FF\u28FF\u280B\u2800\u2800",
6664
+ "\u2800\u2800\u2800\u287F\u2801\u2800\u2800\u2800"
6665
+ ];
6666
+ var boltFillOrder = boltRows.flatMap(
6667
+ (row, rowIndex) => [...row].flatMap(
6668
+ (cell, columnIndex) => cell === BRAILLE_BLANK ? [] : rowIndex * row.length + columnIndex
6669
+ )
6670
+ );
6671
+ var fillStages = [
6672
+ ...Array.from({ length: boltFillOrder.length + 1 }, (_, index) => index),
6673
+ boltFillOrder.length,
6674
+ 0
6675
+ ];
6676
+ var boltFillRanks = new Map(
6677
+ boltFillOrder.map((cellIndex, fillIndex) => [cellIndex, fillIndex])
6678
+ );
6679
+ var STATUS_ROW_INDEX = Math.floor(boltRows.length / 2);
6680
+ function formatPhase({ label, detail }) {
6681
+ return detail ? `${chalk8__default.default.bold(label)} ${chalk8__default.default.dim(detail)}` : chalk8__default.default.bold(label);
6682
+ }
6683
+ function formatLoaderFrame({
6684
+ phase,
6685
+ fillStage
6686
+ }) {
6687
+ return boltRows.map((row, rowIndex) => {
6688
+ const bolt = [...row].map((cell, columnIndex) => {
6689
+ if (cell === BRAILLE_BLANK) return cell;
6690
+ const cellIndex = rowIndex * row.length + columnIndex;
6691
+ const fillRank = boltFillRanks.get(cellIndex);
6692
+ const isFilled = fillRank !== void 0 && fillRank < fillStage;
6693
+ return isFilled ? chalk8__default.default.bold.yellow(cell) : chalk8__default.default.dim.yellow(cell);
6694
+ }).join("");
6695
+ const status = rowIndex === STATUS_ROW_INDEX ? ` ${formatPhase(phase)}` : "";
6696
+ return `${bolt}${status}`;
6697
+ }).join("\n");
6698
+ }
6699
+ async function runWithSetupLoader({
6700
+ promise,
6701
+ ...phase
6702
+ }) {
6703
+ const startedAt = Date.now();
6704
+ let fillFrameIndex = 0;
6705
+ const loader = ora__default.default({
6706
+ isEnabled: process.stderr.isTTY === true,
6707
+ spinner: { interval: 80, frames: [""] },
6708
+ text: formatLoaderFrame({
6709
+ phase,
6710
+ fillStage: fillStages[fillFrameIndex]
6711
+ })
6712
+ }).start();
6713
+ const animationTimer = setInterval(() => {
6714
+ fillFrameIndex = (fillFrameIndex + 1) % fillStages.length;
6715
+ loader.text = formatLoaderFrame({
6716
+ phase,
6717
+ fillStage: fillStages[fillFrameIndex]
6718
+ });
6719
+ }, LIGHTNING_INTERVAL_MILLISECONDS);
6720
+ animationTimer.unref?.();
6721
+ try {
6722
+ const result = await promise;
6723
+ clearInterval(animationTimer);
6724
+ const elapsedSeconds = ((Date.now() - startedAt) / 1e3).toFixed(1);
6725
+ loader.succeed(`${formatPhase(phase)} ${chalk8__default.default.dim(`${elapsedSeconds}s`)}`);
6726
+ return result;
6727
+ } catch (error) {
6728
+ clearInterval(animationTimer);
6729
+ const elapsedSeconds = ((Date.now() - startedAt) / 1e3).toFixed(1);
6730
+ loader.fail(`${formatPhase(phase)} ${chalk8__default.default.dim(`${elapsedSeconds}s`)}`);
6731
+ throw error;
6732
+ }
6733
+ }
6734
+ function isRecord(value) {
6735
+ return typeof value === "object" && value !== null && !Array.isArray(value);
6736
+ }
6737
+ function readPackageJson({
6738
+ directory
6739
+ }) {
6740
+ try {
6741
+ const manifest = JSON.parse(
6742
+ fs.readFileSync(path.join(directory, "package.json"), "utf8")
6743
+ );
6744
+ return isRecord(manifest) ? manifest : void 0;
6745
+ } catch {
6746
+ return void 0;
6747
+ }
6748
+ }
6749
+ var SetupOptionSchema = zod.z.object({
6750
+ label: zod.z.string(),
6751
+ value: zod.z.string()
6752
+ });
6753
+ var SetupOptionsSchema = zod.z.array(SetupOptionSchema).min(1);
6754
+ var SetupDecisionSchema = zod.z.object({
6755
+ message: zod.z.string(),
6756
+ options: SetupOptionsSchema,
6757
+ answer: zod.z.string()
6758
+ });
6759
+ var SetupInputSchema = zod.z.object({
6760
+ message: zod.z.string(),
6761
+ answer: zod.z.string()
6762
+ });
6763
+ var setupDecisionResolver = zapierSdk.defineResolver({
6764
+ requireParameters: ["message", "options"],
6765
+ listItems: ({ input }) => ({ data: input.options }),
6766
+ prompt: ({ items, input }) => ({
6767
+ type: "list",
6768
+ message: input.message,
6769
+ choices: items
6770
+ }),
6771
+ validate: ({ input, value }) => {
6772
+ if (typeof value !== "string") return "Choose an available option.";
6773
+ return input.options.some((option) => option.value === value) || "Choose one of the available options.";
6774
+ }
6775
+ });
6776
+ var setupInputResolver = zapierSdk.defineResolver({
6777
+ type: "static",
6778
+ inputType: "text",
6779
+ requireParameters: ["message"]
6780
+ });
6781
+ var resolveSetupDecisionPlugin = zapierSdk.defineMethod({
6782
+ name: "resolveSetupDecision",
6783
+ description: "Resolve one setup wizard decision.",
6784
+ inputSchema: SetupDecisionSchema,
6785
+ resolvers: { answer: setupDecisionResolver },
6786
+ run: ({ input }) => input
6787
+ });
6788
+ var resolveSetupInputPlugin = zapierSdk.defineMethod({
6789
+ name: "resolveSetupInput",
6790
+ description: "Resolve one setup wizard text input.",
6791
+ inputSchema: SetupInputSchema,
6792
+ resolvers: { answer: setupInputResolver },
6793
+ run: ({ input }) => input
6794
+ });
6795
+ function createSetupController() {
6796
+ const setupResolutionSdk = zapierSdk.createSdk(
6797
+ zapierSdk.definePlugin({
6798
+ name: "setup-resolution",
6799
+ exports: [
6800
+ resolveSetupDecisionPlugin,
6801
+ resolveSetupInputPlugin,
6802
+ zapierSdk.getRegistryPlugin
6803
+ ]
6804
+ })
6805
+ );
6806
+ return zapierSdk.createController(setupResolutionSdk);
6807
+ }
6808
+ async function resolveWithCancellation({
6809
+ run
6810
+ }) {
6811
+ try {
6812
+ return await run();
6813
+ } catch (error) {
6814
+ if (zapierSdk.isCoreCancelledSignal(error)) {
6815
+ throw new ZapierCliUserCancellationError();
6816
+ }
6817
+ throw error;
6818
+ }
6819
+ }
6820
+ async function resolveSetupDecision({
6821
+ answer,
6822
+ controller,
6823
+ message,
6824
+ options
6825
+ }) {
6826
+ const parsedOptions = SetupOptionsSchema.parse(options);
6827
+ const resolved = await resolveWithCancellation({
6828
+ run: () => controller.resolve({
6829
+ method: "resolveSetupDecision",
6830
+ input: { message, options: parsedOptions },
6831
+ answer,
6832
+ interactive: true
6833
+ })
6834
+ });
6835
+ return SetupDecisionSchema.parse(resolved).answer;
6836
+ }
6837
+ async function resolveSetupConfirm({
6838
+ answer,
6839
+ controller,
6840
+ defaultValue,
6841
+ message
6842
+ }) {
6843
+ const values = defaultValue ? [true, false] : [false, true];
6844
+ const resolved = await resolveSetupDecision({
6845
+ answer,
6846
+ controller,
6847
+ message,
6848
+ options: values.map((value) => ({
6849
+ label: value ? "Yes" : "No",
6850
+ value: String(value)
6851
+ }))
6852
+ });
6853
+ return resolved === "true";
6854
+ }
6855
+ async function resolveSetupInput({
6856
+ answer,
6857
+ controller,
6858
+ message
6859
+ }) {
6860
+ const resolved = await resolveWithCancellation({
6861
+ run: () => controller.resolve({
6862
+ method: "resolveSetupInput",
6863
+ input: { message },
6864
+ answer: ({ result, state }) => answer({
6865
+ state,
6866
+ result: {
6867
+ ...result,
6868
+ question: { ...result.question, message }
6869
+ }
6870
+ }),
6871
+ interactive: true
6872
+ })
6873
+ });
6874
+ return SetupInputSchema.parse(resolved).answer.trim();
6875
+ }
6876
+ async function resolveSetupSelect({
6877
+ answer,
6878
+ controller,
6879
+ choices,
6880
+ message
6881
+ }) {
6882
+ const resolved = await resolveSetupDecision({
6883
+ answer,
6884
+ controller,
6885
+ message,
6886
+ options: choices
6887
+ });
6888
+ const selected = choices.find(({ value }) => value === resolved);
6889
+ if (!selected) {
6890
+ throw new Error("Resolved setup selection is not an available choice.");
6891
+ }
6892
+ return selected.value;
6893
+ }
6894
+
6895
+ // src/plugins/setup/dependencies.ts
6896
+ var REQUIRED_PACKAGES = [
6897
+ { name: "@zapier/zapier-sdk", dev: false, checkForUpdates: true },
6898
+ { name: "@zapier/zapier-sdk-cli", dev: true, checkForUpdates: true },
6899
+ {
6900
+ name: "@types/node",
6901
+ dev: true,
6902
+ checkForUpdates: false,
6903
+ typescriptOnly: true
6904
+ },
6905
+ {
6906
+ name: "typescript",
6907
+ dev: true,
6908
+ checkForUpdates: false,
6909
+ typescriptOnly: true
6910
+ },
6911
+ { name: "tsx", dev: true, checkForUpdates: false, typescriptOnly: true }
6912
+ ];
6913
+ function getInstallCommand({
6914
+ packageManager,
6915
+ packages,
6916
+ dev = false
6917
+ }) {
6918
+ const verb = packageManager === "npm" ? "install" : "add";
6919
+ const devFlag = packageManager === "bun" ? "-d" : "-D";
6920
+ return {
6921
+ command: packageManager,
6922
+ args: [verb, ...dev ? [devFlag] : [], ...packages]
6923
+ };
6924
+ }
6925
+ async function executeInstall(context, command) {
6926
+ try {
6927
+ await context.runCommand({ ...command, cwd: context.cwd });
6928
+ } catch (error) {
6929
+ const message = error instanceof Error ? error.message : String(error);
6930
+ if (message.includes("EPERM") && message.includes(".npm/_cacache")) {
6931
+ console.error(
6932
+ "This EPERM usually means the command sandbox blocked npm cache writes; it does not usually mean your file permissions are broken."
6933
+ );
6934
+ }
6935
+ throw error;
6936
+ }
6937
+ }
6938
+ function getDeclaredPackageNames(cwd) {
6939
+ const manifest = readPackageJson({ directory: cwd });
6940
+ if (!manifest) return /* @__PURE__ */ new Set();
6941
+ const names = /* @__PURE__ */ new Set();
6942
+ for (const section of ["dependencies", "devDependencies"]) {
6943
+ const dependencies = manifest[section];
6944
+ if (!isRecord(dependencies)) continue;
6945
+ for (const name of Object.keys(dependencies)) names.add(name);
6946
+ }
6947
+ return names;
6948
+ }
6949
+ function getInstalledPackageVersion({
6950
+ cwd,
6951
+ packageName
6952
+ }) {
6953
+ let directory = cwd;
6954
+ while (true) {
6955
+ const manifest = readPackageJson({
6956
+ directory: path.join(directory, "node_modules", ...packageName.split("/"))
6957
+ });
6958
+ if (manifest?.name === packageName && typeof manifest.version === "string") {
6959
+ return manifest.version;
6960
+ }
6961
+ const parent = path.dirname(directory);
6962
+ if (parent === directory) return void 0;
6963
+ directory = parent;
6964
+ }
6965
+ }
6966
+ async function installPackages({
6967
+ context,
6968
+ packages
6969
+ }) {
6970
+ const runtimePackages = packages.filter(({ dependency }) => !dependency.dev).map(({ dependency }) => dependency.name);
6971
+ if (runtimePackages.length > 0) {
6972
+ await executeInstall(
6973
+ context,
6974
+ getInstallCommand({
6975
+ packageManager: context.packageManager,
6976
+ packages: runtimePackages
6977
+ })
6978
+ );
6979
+ }
6980
+ const developmentPackages = packages.filter(({ dependency }) => dependency.dev).map(({ dependency }) => dependency.name);
6981
+ if (developmentPackages.length > 0) {
6982
+ await executeInstall(
6983
+ context,
6984
+ getInstallCommand({
6985
+ packageManager: context.packageManager,
6986
+ packages: developmentPackages,
6987
+ dev: true
6988
+ })
6989
+ );
6990
+ }
6991
+ }
6992
+ async function offerMissingPackageInstall({
6993
+ context,
6994
+ packages
6995
+ }) {
6996
+ if (packages.length === 0) return;
6997
+ const shouldInstall = await resolveSetupConfirm({
6998
+ answer: context.createAnswer(),
6999
+ controller: context.setupController,
7000
+ message: `These packages are required to continue. Install them now: ${packages.map(({ dependency }) => dependency.name).join(", ")}?`,
7001
+ defaultValue: true
7002
+ });
7003
+ if (!shouldInstall) {
7004
+ console.log(
7005
+ "The Zapier SDK packages are required to continue. Setup cancelled without installing dependencies."
7006
+ );
7007
+ throw new ZapierCliUserCancellationError(
7008
+ "Required Zapier SDK packages were not installed"
7009
+ );
7010
+ }
7011
+ await installPackages({ context, packages });
7012
+ }
7013
+ async function offerPackageUpdate({
7014
+ context,
7015
+ packageState
7016
+ }) {
7017
+ const { currentVersion, dependency } = packageState;
7018
+ if (!currentVersion || !dependency.checkForUpdates) return;
7019
+ const update = await runWithSetupLoader({
7020
+ promise: context.checkForUpdates({
7021
+ packageName: dependency.name,
7022
+ currentVersion
7023
+ }),
7024
+ label: "Checking for updates",
7025
+ detail: dependency.name
7026
+ });
7027
+ if (!update.hasUpdate || !update.latestVersion) return;
7028
+ const shouldUpdate = await resolveSetupConfirm({
7029
+ answer: context.createAnswer(),
7030
+ controller: context.setupController,
7031
+ message: `Update ${dependency.name} from ${currentVersion} to ${update.latestVersion}?`,
7032
+ defaultValue: true
7033
+ });
7034
+ if (!shouldUpdate) return;
7035
+ await executeInstall(
7036
+ context,
7037
+ getInstallCommand({
7038
+ packageManager: context.packageManager,
7039
+ packages: [`${dependency.name}@${update.latestVersion}`],
7040
+ dev: dependency.dev
7041
+ })
7042
+ );
7043
+ }
7044
+ async function prepareDependencies(context) {
7045
+ const declaredPackageNames = getDeclaredPackageNames(context.cwd);
7046
+ const requiredPackages = REQUIRED_PACKAGES.filter(
7047
+ ({ typescriptOnly }) => !typescriptOnly || context.projectLanguage === "typescript"
7048
+ );
7049
+ const packages = requiredPackages.map((dependency) => ({
7050
+ dependency,
7051
+ currentVersion: declaredPackageNames.has(dependency.name) ? getInstalledPackageVersion({
7052
+ cwd: context.cwd,
7053
+ packageName: dependency.name
7054
+ }) : void 0
7055
+ }));
7056
+ await offerMissingPackageInstall({
7057
+ context,
7058
+ packages: packages.filter(
7059
+ ({ dependency }) => !declaredPackageNames.has(dependency.name)
7060
+ )
7061
+ });
7062
+ for (const packageState of packages) {
7063
+ await offerPackageUpdate({ context, packageState });
7064
+ }
7065
+ }
7066
+
7067
+ // src/plugins/setup/package-commands.ts
7068
+ function createLocalPackageCommand({
7069
+ packageManager,
7070
+ binary,
7071
+ args = []
7072
+ }) {
7073
+ const runner = {
7074
+ npm: { command: "npx", args: ["--no-install"] },
7075
+ pnpm: { command: "pnpm", args: ["exec"] },
7076
+ yarn: { command: "yarn", args: ["exec"] },
7077
+ bun: { command: "bunx", args: ["--no-install"] }
7078
+ };
7079
+ return {
7080
+ command: runner[packageManager].command,
7081
+ args: [...runner[packageManager].args, binary, ...args]
7082
+ };
7083
+ }
7084
+ function createPackageRunnerCommand({
7085
+ packageManager,
7086
+ packageName,
7087
+ args = []
7088
+ }) {
7089
+ const runner = {
7090
+ npm: { command: "npx", args: ["--yes"] },
7091
+ pnpm: { command: "pnpm", args: ["dlx"] },
7092
+ yarn: { command: "yarn", args: ["dlx"] },
7093
+ bun: { command: "bunx", args: [] }
7094
+ };
7095
+ return {
7096
+ command: runner[packageManager].command,
7097
+ args: [...runner[packageManager].args, packageName, ...args]
7098
+ };
7099
+ }
7100
+ function formatPackageCommand({
7101
+ command,
7102
+ args
7103
+ }) {
7104
+ return [command, ...args].join(" ");
7105
+ }
7106
+
7107
+ // src/plugins/setup/project.ts
7108
+ var COMMAND_MAX_BUFFER_BYTES = 10 * 1024 * 1024;
7109
+ var PROJECT_INIT_COMMANDS = {
7110
+ npm: { command: "npm", args: ["init", "-y"] },
7111
+ pnpm: { command: "pnpm", args: ["init"] },
7112
+ yarn: { command: "yarn", args: ["init", "-y"] },
7113
+ bun: { command: "bun", args: ["init", "-y"] }
7114
+ };
7115
+ var CapturedCommandError = class extends Error {
7116
+ constructor(error, stdout, stderr) {
7117
+ super(error.message);
7118
+ this.stdout = stdout;
7119
+ this.stderr = stderr;
7120
+ }
7121
+ };
7122
+ function commandError({
7123
+ command,
7124
+ code,
7125
+ signal
7126
+ }) {
7127
+ return new Error(
7128
+ signal ? `${command} was terminated by ${signal}` : `${command} exited with code ${code ?? "unknown"}`
7129
+ );
7130
+ }
7131
+ function executeCapturedCommand({
7132
+ command,
7133
+ args,
7134
+ cwd,
7135
+ input
7136
+ }) {
7137
+ return new Promise((resolve4, reject) => {
7138
+ const child = crossSpawn__default.default(command, args, {
7139
+ cwd,
7140
+ shell: false,
7141
+ stdio: ["pipe", "pipe", "pipe"]
7142
+ });
7143
+ let stdout = "";
7144
+ let stderr = "";
7145
+ const append = ({
7146
+ chunk,
7147
+ stream
7148
+ }) => {
7149
+ if (stream === "stdout") stdout += chunk.toString();
7150
+ else stderr += chunk.toString();
7151
+ if (Buffer.byteLength(stdout) + Buffer.byteLength(stderr) > COMMAND_MAX_BUFFER_BYTES) {
7152
+ child.kill();
7153
+ reject(new Error("Command output exceeded the capture limit."));
7154
+ }
7155
+ };
7156
+ child.stdout?.on(
7157
+ "data",
7158
+ (chunk) => append({ chunk, stream: "stdout" })
7159
+ );
7160
+ child.stderr?.on(
7161
+ "data",
7162
+ (chunk) => append({ chunk, stream: "stderr" })
7163
+ );
7164
+ child.once("error", reject);
7165
+ child.once("close", (code, signal) => {
7166
+ if (code === 0) {
7167
+ resolve4(stdout.trim());
7168
+ return;
7169
+ }
7170
+ reject(
7171
+ new CapturedCommandError(
7172
+ commandError({ command, code, signal }),
7173
+ stdout,
7174
+ stderr
7175
+ )
7176
+ );
7177
+ });
7178
+ child.stdin?.end(input);
7179
+ });
7180
+ }
7181
+ function executeStreamingCommand({
7182
+ command,
7183
+ args,
7184
+ cwd,
7185
+ input
7186
+ }) {
7187
+ return new Promise((resolve4, reject) => {
7188
+ const child = crossSpawn__default.default(command, args, {
7189
+ cwd,
7190
+ shell: false,
7191
+ stdio: [input === void 0 ? "inherit" : "pipe", "inherit", "inherit"]
7192
+ });
7193
+ child.once("error", reject);
7194
+ child.once("close", (code, signal) => {
7195
+ if (code === 0) {
7196
+ resolve4("");
7197
+ return;
7198
+ }
7199
+ reject(commandError({ command, code, signal }));
7200
+ });
7201
+ if (input !== void 0) child.stdin?.end(input);
7202
+ });
7203
+ }
7204
+ async function runCommand({
7205
+ command,
7206
+ args = [],
7207
+ cwd,
7208
+ capture = true,
7209
+ input
7210
+ }) {
7211
+ const commandLabel = `$ ${command} ${args.join(" ")}`.trim();
7212
+ const execute = capture ? executeCapturedCommand({ command, args, cwd, input }) : executeStreamingCommand({ command, args, cwd, input });
7213
+ try {
7214
+ if (capture) {
7215
+ return await runWithSetupLoader({
7216
+ promise: execute,
7217
+ label: "Running command",
7218
+ detail: commandLabel
7219
+ });
7220
+ }
7221
+ console.log(chalk8__default.default.dim(commandLabel));
7222
+ return await execute;
7223
+ } catch (error) {
7224
+ const message = error instanceof Error ? error.message : String(error);
7225
+ if (error instanceof CapturedCommandError) {
7226
+ if (error.stdout) process.stdout.write(error.stdout);
7227
+ if (error.stderr) process.stderr.write(error.stderr);
7228
+ if (!error.stdout && !error.stderr) console.error(message);
7229
+ } else {
7230
+ console.error(message);
7231
+ }
7232
+ throw new ZapierCliExitError(message);
7233
+ }
7234
+ }
7235
+ async function chooseDirectory(context) {
7236
+ const useCurrentDirectory = await resolveSetupConfirm({
7237
+ answer: context.createAnswer(),
7238
+ controller: context.setupController,
7239
+ message: `Set up the Zapier SDK in ${context.cwd}?`,
7240
+ defaultValue: true
7241
+ });
7242
+ if (useCurrentDirectory) return;
7243
+ const setupCommand = formatPackageCommand(
7244
+ createLocalPackageCommand({
7245
+ packageManager: context.packageManager,
7246
+ binary: "zapier-sdk",
7247
+ args: ["setup"]
7248
+ })
7249
+ );
7250
+ console.log(
7251
+ `Setup cancelled. Navigate to the intended directory and run \`${setupCommand}\` again.`
7252
+ );
7253
+ throw new ZapierCliUserCancellationError("Setup cancelled by user");
7254
+ }
7255
+ async function ensureSupportedNode(context) {
7256
+ let version;
7257
+ try {
7258
+ version = await context.runCommand({
7259
+ command: "node",
7260
+ args: ["-v"],
7261
+ cwd: context.cwd,
7262
+ capture: true
7263
+ });
7264
+ } catch {
7265
+ console.error(
7266
+ "Node.js 20 or higher is required. Install it from https://nodejs.org, then run setup again."
7267
+ );
7268
+ throw new ZapierCliExitError(
7269
+ "Setup could not continue without Node.js 20 or higher."
7270
+ );
7271
+ }
7272
+ const major = Number(version.replace(/^v/, "").split(".")[0]);
7273
+ if (!Number.isFinite(major) || major < 20) {
7274
+ console.error(
7275
+ `Node.js 20 or higher is required; found ${version}. Upgrade Node.js, then run setup again.`
7276
+ );
7277
+ throw new ZapierCliExitError(
7278
+ "Setup could not continue without Node.js 20 or higher."
7279
+ );
7280
+ }
7281
+ console.log(`Node.js ${version} is ready.`);
7282
+ }
7283
+ function detectProjectLanguage({
7284
+ cwd,
7285
+ hasExistingProject
7286
+ }) {
7287
+ if (!hasExistingProject || fs.existsSync(path.join(cwd, "tsconfig.json"))) {
7288
+ return "typescript";
7289
+ }
7290
+ const manifest = readPackageJson({ directory: cwd });
7291
+ const hasTypeScript = [
7292
+ manifest?.dependencies,
7293
+ manifest?.devDependencies
7294
+ ].some(
7295
+ (dependencies) => isRecord(dependencies) && "typescript" in dependencies
7296
+ );
7297
+ return hasTypeScript ? "typescript" : "javascript";
7298
+ }
7299
+ async function prepareProject(context) {
7300
+ context.packageManager = detectPackageManager(context.cwd).name;
7301
+ console.log(`Using ${context.packageManager} for dependency installs.`);
7302
+ const hasExistingProject = fs.existsSync(path.join(context.cwd, "package.json"));
7303
+ context.projectLanguage = detectProjectLanguage({
7304
+ cwd: context.cwd,
7305
+ hasExistingProject
7306
+ });
7307
+ if (hasExistingProject) {
7308
+ console.log("Found package.json; using this project as-is.");
7309
+ } else {
7310
+ await context.runCommand({
7311
+ ...PROJECT_INIT_COMMANDS[context.packageManager],
7312
+ cwd: context.cwd
7313
+ });
7314
+ }
7315
+ await prepareDependencies(context);
7316
+ }
7317
+
7318
+ // src/plugins/setup/context.ts
7319
+ function createWizardContext({
7320
+ imports
7321
+ }) {
7322
+ return {
7323
+ cwd: process.cwd(),
7324
+ imports,
7325
+ createAnswer: () => createCliAnswer({ mode: "closed-list" }),
7326
+ setupController: createSetupController(),
7327
+ checkForUpdates,
7328
+ openUrl: async (url) => {
7329
+ await open__default.default(url);
7330
+ },
7331
+ runCommand,
7332
+ packageManager: detectPackageManager(process.cwd()).name,
7333
+ projectLanguage: "typescript"
7334
+ };
7335
+ }
7336
+ var SetupSchema = zod.z.object({}).describe("Set up the Zapier SDK in an existing or new project");
7337
+ function printAuthCommand({
7338
+ context,
7339
+ flow,
7340
+ headless
7341
+ }) {
7342
+ const command = createLocalPackageCommand({
7343
+ packageManager: context.packageManager,
7344
+ binary: "zapier-sdk",
7345
+ args: [flow, ...headless ? ["--headless"] : []]
7346
+ });
7347
+ console.log(`$ ${formatPackageCommand(command)}`);
7348
+ if (headless) {
7349
+ console.log(
7350
+ "Open the printed URL in another browser, then paste the final OAuth callback URL when prompted."
7351
+ );
7352
+ }
7353
+ }
7354
+ function isCredentialWriteError(error) {
7355
+ const code = typeof error === "object" && error !== null && "code" in error && typeof error.code === "string" ? error.code : "";
7356
+ if (/^(eacces|eperm)$/i.test(code)) return true;
7357
+ const message = error instanceof Error ? error.message : String(error);
7358
+ return /permission|sandbox|eacces|eperm/i.test(message);
7359
+ }
7360
+ async function authenticate(context) {
7361
+ const activeProfile = await runWithSetupLoader({
7362
+ promise: context.imports.getProfile({}).then(({ data }) => data).catch((error) => {
7363
+ if (zapierSdk.isZapierAuthenticationError(error)) return void 0;
7364
+ throw error;
7365
+ }),
7366
+ label: "Checking Zapier authentication"
7367
+ });
7368
+ if (activeProfile) {
7369
+ const shouldLogout = await resolveSetupConfirm({
7370
+ answer: context.createAnswer(),
7371
+ controller: context.setupController,
7372
+ message: `You are already logged in as "${activeProfile.email}".
7373
+ Logging out will delete these credentials and may interrupt other Zapier SDK or CLI sessions using them.
7374
+ Log out and use a different account?`,
7375
+ defaultValue: false
7376
+ });
7377
+ if (!shouldLogout) {
7378
+ context.accountEmail = activeProfile.email;
7379
+ console.log(`Continuing as ${activeProfile.email}.`);
7380
+ return;
7381
+ }
7382
+ const logoutCommand = createLocalPackageCommand({
7383
+ packageManager: context.packageManager,
7384
+ binary: "zapier-sdk",
7385
+ args: ["logout"]
7386
+ });
7387
+ console.log(`$ ${formatPackageCommand(logoutCommand)}`);
7388
+ await context.imports.logout({});
7389
+ }
7390
+ const flow = await resolveSetupSelect({
7391
+ answer: context.createAnswer(),
7392
+ controller: context.setupController,
7393
+ message: "Zapier account:",
7394
+ choices: [
7395
+ { label: "Log in to an existing account", value: "login" },
7396
+ { label: "Create a new Zapier account", value: "signup" }
7397
+ ]
7398
+ });
7399
+ const environment = await resolveSetupSelect({
7400
+ answer: context.createAnswer(),
7401
+ controller: context.setupController,
7402
+ message: "Environment:",
7403
+ choices: [
7404
+ { label: "Local machine with a browser", value: "local" },
7405
+ { label: "Remote or headless", value: "headless" }
7406
+ ]
7407
+ });
7408
+ const headless = environment === "headless";
7409
+ const runAuth = flow === "login" ? context.imports.login : context.imports.signup;
7410
+ printAuthCommand({ context, flow, headless });
7411
+ try {
7412
+ await runAuth({ headless });
7413
+ } catch (error) {
7414
+ if (isCredentialWriteError(error)) {
7415
+ console.error(
7416
+ "Authentication could not write credentials. A permissions or sandbox restriction may be blocking disk access."
7417
+ );
7418
+ }
7419
+ throw error;
7420
+ }
7421
+ const { data: profile } = await runWithSetupLoader({
7422
+ promise: context.imports.getProfile({}),
7423
+ label: "Confirming Zapier account"
7424
+ });
7425
+ context.accountEmail = profile.email;
7426
+ console.log(`Authenticated as ${profile.email}.`);
7427
+ }
7428
+ var agentLabels = {
7429
+ claude: "Claude Code",
7430
+ codex: "Codex",
7431
+ cursor: "Cursor",
7432
+ "vscode-copilot": "VS Code Copilot"
7433
+ };
7434
+ function buildAgentPrompt({ context }) {
7435
+ const listConnectionsCommand = formatPackageCommand(
7436
+ createLocalPackageCommand({
7437
+ packageManager: context.packageManager,
7438
+ binary: "zapier-sdk",
7439
+ args: ["list-connections", "--owner", "me", "--json"]
7440
+ })
7441
+ );
7442
+ const listActionsCommand = formatPackageCommand(
7443
+ createLocalPackageCommand({
7444
+ packageManager: context.packageManager,
7445
+ binary: "zapier-sdk",
7446
+ args: ["list-actions", "APP_KEY"]
7447
+ })
7448
+ );
7449
+ return `Start by running this command to discover my active connected apps outside of your sandbox:
7450
+
7451
+ ${listConnectionsCommand}
7452
+
7453
+ Using the connected apps returned by that command:
7454
+
7455
+ - Pick 1-3 apps and show commands I can use to explore their actions, such as: ${listActionsCommand}
7456
+ - Do not run those list-actions commands.
7457
+ - Suggest 3 specific ideas based on my connected apps. Each idea should read from one app, optionally process data, and write to another.
7458
+ - Do not suggest event-driven workflows.
7459
+ - Keep each idea to one sentence. Example: "pull in-progress Jira issues and DM yourself a summary on Slack".
7460
+
7461
+ Do not inspect files or modify the project. If fewer than two distinct apps are listed, explain that cross-app ideas require another active connection instead of inventing apps.`;
7462
+ }
7463
+ function printAgentPrompt({
7464
+ context,
7465
+ message
7466
+ }) {
7467
+ console.log();
7468
+ console.log(chalk8__default.default.bgYellow.black.bold(message));
7469
+ console.log();
7470
+ console.log(buildAgentPrompt({ context }));
7471
+ }
7472
+ async function openAgentHandoff(context) {
7473
+ const agent = await resolveSetupSelect({
7474
+ answer: context.createAnswer(),
7475
+ controller: context.setupController,
7476
+ message: "Want to open your agent and have it give you suggestions to start?",
7477
+ choices: [
7478
+ { label: "No", value: "none" },
7479
+ { label: "Claude Code", value: "claude" },
7480
+ { label: "Cursor", value: "cursor" },
7481
+ { label: "Codex", value: "codex" },
7482
+ { label: "VS Code Copilot", value: "vscode-copilot" },
7483
+ { label: "Other", value: "other" }
7484
+ ]
7485
+ });
7486
+ if (agent === "none") return;
7487
+ if (agent === "other") {
7488
+ printAgentPrompt({
7489
+ context,
7490
+ message: "Paste this prompt into your AI agent:"
7491
+ });
7492
+ return;
7493
+ }
7494
+ const prompt = buildAgentPrompt({ context });
7495
+ const encodedPrompt = encodeURIComponent(prompt);
7496
+ const encodedPath = encodeURIComponent(context.cwd);
7497
+ try {
7498
+ switch (agent) {
7499
+ case "claude":
7500
+ await context.openUrl(
7501
+ `claude://code/new?q=${encodedPrompt}&folder=${encodedPath}`
7502
+ );
7503
+ break;
7504
+ case "codex":
7505
+ await context.openUrl(
7506
+ `codex://threads/new?prompt=${encodedPrompt}&path=${encodedPath}`
7507
+ );
7508
+ break;
7509
+ case "cursor":
7510
+ await context.runCommand({
7511
+ command: "cursor",
7512
+ args: ["."],
7513
+ cwd: context.cwd,
7514
+ capture: true
7515
+ });
7516
+ console.log(`Cursor opened in ${context.cwd}.`);
7517
+ break;
7518
+ case "vscode-copilot":
7519
+ await context.runCommand({
7520
+ command: "code",
7521
+ args: ["chat", "--mode", "agent", "-"],
7522
+ cwd: context.cwd,
7523
+ input: prompt
7524
+ });
7525
+ break;
7526
+ default: {
7527
+ const unsupportedAgent = agent;
7528
+ throw new Error(`Unsupported agent: ${unsupportedAgent}`);
7529
+ }
7530
+ }
7531
+ } catch {
7532
+ console.warn(
7533
+ `Could not open ${agentLabels[agent]}. Open it manually to continue.`
7534
+ );
7535
+ }
7536
+ printAgentPrompt({
7537
+ context,
7538
+ message: "If it didn't load correctly, paste this prompt into your agent:"
7539
+ });
7540
+ }
7541
+ var CONNECTIONS_URL = "https://zapier.com/app/assets/connections";
7542
+ var CONNECTION_DISPLAY_LIMIT = 10;
7543
+ async function ensureConnectionsAvailable(context) {
7544
+ const page = await runWithSetupLoader({
7545
+ promise: context.imports.listConnections({
7546
+ owner: "me",
7547
+ maxItems: CONNECTION_DISPLAY_LIMIT
7548
+ }),
7549
+ label: "Loading app connections"
7550
+ });
7551
+ if (page.data.length === 0) {
7552
+ console.log(
7553
+ `No active connections found. Connect or reconnect an app at ${CONNECTIONS_URL}, then come back and run setup again.`
7554
+ );
7555
+ throw new ZapierCliExitError(
7556
+ "Setup stopped before completion because no active connections are available."
7557
+ );
7558
+ }
7559
+ const table = new Table__default.default({
7560
+ head: ["App", "Connection"],
7561
+ style: { compact: true }
7562
+ });
7563
+ table.push(
7564
+ ...page.data.map((connection) => [
7565
+ connection.slug || connection.app_key,
7566
+ connection.title
7567
+ ])
7568
+ );
7569
+ console.log(
7570
+ `Active Zapier connections (showing up to ${CONNECTION_DISPLAY_LIMIT}):`
7571
+ );
7572
+ console.log(table.toString());
7573
+ }
7574
+ var CONNECTION_PLACEHOLDER = "__ZAPIER_SDK_SLACK_CONNECTION__";
7575
+ var EMAIL_PLACEHOLDER = "__ZAPIER_SDK_ACCOUNT_EMAIL__";
7576
+ var APP_PLACEHOLDER = "__ZAPIER_SDK_SLACK_APP__";
7577
+ var SLACK_SLUG = "slack";
7578
+ function getSlackTestPath(context) {
7579
+ const extension = context.projectLanguage === "typescript" ? "ts" : "mjs";
7580
+ return path.join("src", "sdk-demo", `zapier-slack-test.${extension}`);
7581
+ }
7582
+ function getSlackTestTemplatePath(context) {
7583
+ const extension = context.projectLanguage === "typescript" ? "ts" : "mjs";
7584
+ return path.join(TEMPLATES_DIR, "setup", `zapier-slack-test.${extension}`);
7585
+ }
7586
+ async function findSlackConnection(context) {
7587
+ const page = await runWithSetupLoader({
7588
+ promise: context.imports.listConnections({
7589
+ owner: "me",
7590
+ app: SLACK_SLUG,
7591
+ maxItems: 1
7592
+ }),
7593
+ label: "Looking for a Slack connection"
7594
+ });
7595
+ return page.data.find(({ slug }) => slug === SLACK_SLUG);
7596
+ }
7597
+ function toTemplateString(value) {
7598
+ return JSON.stringify(value).slice(1, -1);
7599
+ }
7600
+ function renderSlackTest({
7601
+ context,
7602
+ app,
7603
+ connection,
7604
+ email
7605
+ }) {
7606
+ return fs.readFileSync(getSlackTestTemplatePath(context), "utf8").replace(APP_PLACEHOLDER, () => toTemplateString(app)).replace(CONNECTION_PLACEHOLDER, () => toTemplateString(connection)).replace(EMAIL_PLACEHOLDER, () => toTemplateString(email));
7607
+ }
7608
+ function writeSlackTest({
7609
+ context,
7610
+ app,
7611
+ connection,
7612
+ email
7613
+ }) {
7614
+ const slackTestPath = getSlackTestPath(context);
7615
+ const path2 = path.join(context.cwd, slackTestPath);
7616
+ if (!fs.existsSync(path.dirname(path2))) fs.mkdirSync(path.dirname(path2), { recursive: true });
7617
+ fs.writeFileSync(path2, renderSlackTest({ context, app, connection, email }));
7618
+ console.log(`Created ${slackTestPath}.`);
7619
+ }
7620
+ async function executeSlackTest(context) {
7621
+ const slackTestPath = getSlackTestPath(context);
7622
+ if (context.projectLanguage === "javascript") {
7623
+ await context.runCommand({
7624
+ command: "node",
7625
+ args: [slackTestPath],
7626
+ cwd: context.cwd,
7627
+ capture: false
7628
+ });
7629
+ return;
7630
+ }
7631
+ const command = context.packageManager === "bun" ? { command: "bun", args: [] } : createLocalPackageCommand({
7632
+ packageManager: context.packageManager,
7633
+ binary: "tsx"
7634
+ });
7635
+ const args = [...command.args, slackTestPath];
7636
+ await context.runCommand({
7637
+ command: command.command,
7638
+ args,
7639
+ cwd: context.cwd,
7640
+ capture: false
7641
+ });
7642
+ }
7643
+ async function trySlackTest(context) {
7644
+ try {
7645
+ await executeSlackTest(context);
7646
+ return true;
7647
+ } catch (error) {
7648
+ const message = error instanceof Error ? error.message : String(error);
7649
+ console.warn(`Slack demo failed: ${message}. Setup will continue.`);
7650
+ return false;
7651
+ }
7652
+ }
7653
+ async function offerSlackTest(context) {
7654
+ if (!context.accountEmail) {
7655
+ console.log("No account email found; skipping the Slack demo.");
7656
+ return;
7657
+ }
7658
+ const slackConnection = await findSlackConnection(context);
7659
+ if (!slackConnection) {
7660
+ console.log("No active Slack connection found; skipping the Slack demo.");
7661
+ return;
7662
+ }
7663
+ const slackTestPath = getSlackTestPath(context);
7664
+ const shouldRun = await resolveSetupConfirm({
7665
+ answer: context.createAnswer(),
7666
+ controller: context.setupController,
7667
+ message: `Run the Slack self-DM test using ${context.accountEmail}?`,
7668
+ defaultValue: true
7669
+ });
7670
+ if (!shouldRun) return;
7671
+ const path2 = path.join(context.cwd, slackTestPath);
7672
+ if (fs.existsSync(path2)) {
7673
+ const shouldOverwrite = await resolveSetupConfirm({
7674
+ answer: context.createAnswer(),
7675
+ controller: context.setupController,
7676
+ message: `${slackTestPath} already exists. Is it okay to overwrite it?`,
7677
+ defaultValue: false
7678
+ });
7679
+ if (!shouldOverwrite) {
7680
+ console.log("Keeping the existing Slack test file.");
7681
+ const shouldRunExisting = await resolveSetupConfirm({
7682
+ answer: context.createAnswer(),
7683
+ controller: context.setupController,
7684
+ message: `Run the existing ${slackTestPath}?`,
7685
+ defaultValue: false
7686
+ });
7687
+ if (shouldRunExisting) await trySlackTest(context);
7688
+ return;
7689
+ }
7690
+ }
7691
+ let email = context.accountEmail;
7692
+ writeSlackTest({
7693
+ context,
7694
+ app: SLACK_SLUG,
7695
+ connection: slackConnection.id,
7696
+ email
7697
+ });
7698
+ if (await trySlackTest(context)) return;
7699
+ email = await resolveSetupInput({
7700
+ answer: context.createAnswer(),
7701
+ controller: context.setupController,
7702
+ message: "Slack email for one retry after the failed test:"
7703
+ });
7704
+ if (!email) {
7705
+ console.log("Skipping the Slack test.");
7706
+ return;
7707
+ }
7708
+ writeSlackTest({
7709
+ context,
7710
+ app: SLACK_SLUG,
7711
+ connection: slackConnection.id,
7712
+ email
7713
+ });
7714
+ await trySlackTest(context);
7715
+ }
7716
+
7717
+ // src/plugins/setup/skill.ts
7718
+ async function installOptionalSkill(context) {
7719
+ const shouldInstall = await resolveSetupConfirm({
7720
+ answer: context.createAnswer(),
7721
+ controller: context.setupController,
7722
+ message: "Install the optional Zapier SDK skill for extra agent context? This is not required for SDK setup.",
7723
+ defaultValue: true
7724
+ });
7725
+ if (!shouldInstall) {
7726
+ console.log("Skipping the optional Zapier SDK skill.");
7727
+ return;
7728
+ }
7729
+ const command = createPackageRunnerCommand({
7730
+ packageManager: context.packageManager,
7731
+ packageName: "skills",
7732
+ args: ["add", "zapier/sdk", "-y"]
7733
+ });
7734
+ try {
7735
+ await context.runCommand({
7736
+ ...command,
7737
+ cwd: context.cwd,
7738
+ capture: true
7739
+ });
7740
+ } catch {
7741
+ console.warn(
7742
+ `Could not install the optional Zapier SDK skill. To install it manually, run: ${formatPackageCommand(command)}`
7743
+ );
7744
+ }
7745
+ }
7746
+
7747
+ // src/plugins/setup/wizard.ts
7748
+ var PHASE_COUNT = 6;
7749
+ var MINIMUM_MESSAGE_WIDTH = 20;
7750
+ var MAXIMUM_MESSAGE_WIDTH = 88;
7751
+ function showPhase({ number, title }) {
7752
+ console.log();
7753
+ console.log(chalk8__default.default.bgCyan.black.bold(` ${number}/${PHASE_COUNT} ${title} `));
7754
+ }
7755
+ function printWrapped(text) {
7756
+ const width = Math.max(
7757
+ MINIMUM_MESSAGE_WIDTH,
7758
+ Math.min(
7759
+ process.stdout.columns ?? MAXIMUM_MESSAGE_WIDTH,
7760
+ MAXIMUM_MESSAGE_WIDTH
7761
+ )
7762
+ );
7763
+ console.log(wrapAnsi4__default.default(text, width));
7764
+ }
7765
+ function showReadyMessage() {
7766
+ console.log();
7767
+ console.log(chalk8__default.default.bgGreen.black.bold(" \u2713 Zapier SDK setup complete "));
7768
+ console.log();
7769
+ printWrapped(
7770
+ "Use active Zapier connections to access 9,000+ app connectors without managing each app's OAuth, token refresh, or retries."
7771
+ );
7772
+ console.log();
7773
+ printWrapped(
7774
+ "To learn more about the Zapier SDK, visit https://docs.zapier.com/sdk"
7775
+ );
7776
+ console.log();
7777
+ }
7778
+ async function runWizard(context) {
7779
+ console.log(chalk8__default.default.bold("Zapier SDK setup"));
7780
+ showPhase({ number: 1, title: "Project directory" });
7781
+ await chooseDirectory(context);
7782
+ showPhase({ number: 2, title: "Node.js" });
7783
+ await ensureSupportedNode(context);
7784
+ showPhase({ number: 3, title: "Dependencies" });
7785
+ await prepareProject(context);
7786
+ await installOptionalSkill(context);
7787
+ showPhase({ number: 4, title: "Zapier account" });
7788
+ await authenticate(context);
7789
+ showPhase({ number: 5, title: "App connections" });
7790
+ await ensureConnectionsAvailable(context);
7791
+ showPhase({ number: 6, title: "Slack demo" });
7792
+ await offerSlackTest(context);
7793
+ showReadyMessage();
7794
+ console.log(chalk8__default.default.bgCyan.black.bold(" Next steps "));
7795
+ await openAgentHandoff(context);
7796
+ }
7797
+
7798
+ // src/plugins/setup/index.ts
7799
+ var getProfileRef = zapierSdk.declareMethod({ id: "getProfile" });
7800
+ var listConnectionsRef2 = zapierSdk.declareMethod({ id: "listConnections" });
7801
+ var loginRef = zapierSdk.declareMethod({ id: "login" });
7802
+ var logoutRef = zapierSdk.declareMethod({ id: "logout" });
7803
+ var signupRef = zapierSdk.declareMethod({ id: "signup" });
7804
+ var setupImports = [
7805
+ getProfileRef,
7806
+ listConnectionsRef2,
7807
+ loginRef,
7808
+ logoutRef,
7809
+ signupRef
7810
+ ];
7811
+ var setupPlugin = zapierSdk.defineMethod({
7812
+ name: "setup",
7813
+ imports: setupImports,
7814
+ categories: ["utility"],
7815
+ supportsJsonOutput: false,
7816
+ inputSchema: SetupSchema,
7817
+ output: "raw",
7818
+ run: async ({ imports }) => {
7819
+ if (process.stdin.isTTY !== true || process.stdout.isTTY !== true) {
7820
+ throw new ZapierCliExitError(
7821
+ "`zapier-sdk setup` requires an interactive terminal."
7822
+ );
7823
+ }
7824
+ await runWizard(createWizardContext({ imports }));
7825
+ }
7826
+ });
7827
+ var CliSkipLeaseExpireError = class extends Error {
7828
+ constructor() {
7829
+ super("user skipped (let lease expire)");
7830
+ this.name = "CliSkipLeaseExpireError";
7831
+ }
7832
+ };
7833
+ function createInteractiveCallback() {
7834
+ let messageNumber = 0;
7835
+ return async (message) => {
7836
+ messageNumber++;
7837
+ const attrs = message.message_attributes;
7838
+ console.log(
7839
+ `
7840
+ ${chalk8__default.default.bold(`Message #${messageNumber}`)} ${chalk8__default.default.dim(message.id)} ${chalk8__default.default.dim(`(lease #${attrs.lease_count})`)}`
7841
+ );
7842
+ if (attrs.error_message) {
7843
+ console.log(chalk8__default.default.yellow(` upstream error: ${attrs.error_message}`));
7844
+ }
7845
+ if (attrs.possible_duplicate_data) {
7846
+ console.log(chalk8__default.default.yellow(" possible duplicate data"));
7847
+ }
7848
+ while (true) {
7849
+ let action;
7850
+ try {
7851
+ const answer = await inquirer__default.default.prompt([
7852
+ {
7853
+ type: "list",
7854
+ name: "action",
7855
+ message: "Action?",
7856
+ choices: [
7857
+ { name: "Ack (remove from inbox)", value: "ack" },
7858
+ {
7859
+ name: "Skip (release after draining)",
7860
+ value: "skip-release"
7861
+ },
7862
+ { name: "Skip (let lease expire)", value: "skip-expire" },
7863
+ { name: "View payload", value: "view" },
7864
+ { name: "Quit", value: "quit" }
7865
+ ]
7866
+ }
6286
7867
  ]);
6287
7868
  action = answer.action;
6288
7869
  } catch (error) {
@@ -6747,7 +8328,7 @@ function renderDeprecationNotices() {
6747
8328
  function buildBoxLines(message) {
6748
8329
  const innerWidth = BOX_WIDTH - 4;
6749
8330
  const pad = (line) => `\u2502 ${line.padEnd(innerWidth)} \u2502`;
6750
- const wrapped = wrapAnsi3__default.default(message, innerWidth, { hard: true }).split("\n");
8331
+ const wrapped = wrapAnsi4__default.default(message, innerWidth, { hard: true }).split("\n");
6751
8332
  return [
6752
8333
  `\u256D${"\u2500".repeat(BOX_WIDTH - 2)}\u256E`,
6753
8334
  pad(BOX_TITLE),
@@ -6760,7 +8341,7 @@ function buildBoxLines(message) {
6760
8341
  // package.json with { type: 'json' }
6761
8342
  var package_default2 = {
6762
8343
  name: "@zapier/zapier-sdk-cli",
6763
- version: "0.68.0"};
8344
+ version: "0.70.0"};
6764
8345
 
6765
8346
  // src/sdk.ts
6766
8347
  var warnedDeprecatedMethods = /* @__PURE__ */ new Set();
@@ -6800,6 +8381,7 @@ var cliSdkPlugin = zapierSdk.definePlugin({
6800
8381
  mcpPlugin,
6801
8382
  getLoginConfigPathPlugin,
6802
8383
  initPlugin,
8384
+ setupPlugin,
6803
8385
  bundleCodePlugin,
6804
8386
  feedbackPlugin,
6805
8387
  curlPlugin,
@@ -6868,6 +8450,7 @@ function createZapierCliSdk2(options = {}) {
6868
8450
  mcpPlugin,
6869
8451
  getLoginConfigPathPlugin,
6870
8452
  initPlugin,
8453
+ setupPlugin,
6871
8454
  bundleCodePlugin,
6872
8455
  feedbackPlugin,
6873
8456
  curlPlugin,
@@ -6952,163 +8535,6 @@ function readEnvSpecs() {
6952
8535
  if (!raw) return [];
6953
8536
  return raw.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
6954
8537
  }
6955
- var ONE_DAY_MILLISECONDS = 24 * 60 * 60 * 1e3;
6956
- var CACHE_RESET_INTERVAL_MILLISECONDS = (() => {
6957
- const {
6958
- ZAPIER_SDK_UPDATE_CHECK_INTERVAL_SECONDS,
6959
- ZAPIER_SDK_UPDATE_CHECK_INTERVAL_MS
6960
- } = process.env;
6961
- let intervalMs;
6962
- if (ZAPIER_SDK_UPDATE_CHECK_INTERVAL_SECONDS !== void 0) {
6963
- const seconds = parseInt(ZAPIER_SDK_UPDATE_CHECK_INTERVAL_SECONDS);
6964
- intervalMs = isNaN(seconds) ? NaN : seconds * 1e3;
6965
- } else if (ZAPIER_SDK_UPDATE_CHECK_INTERVAL_MS !== void 0) {
6966
- intervalMs = parseInt(ZAPIER_SDK_UPDATE_CHECK_INTERVAL_MS);
6967
- } else {
6968
- intervalMs = ONE_DAY_MILLISECONDS;
6969
- }
6970
- if (isNaN(intervalMs) || intervalMs < 0) {
6971
- return -1;
6972
- }
6973
- return intervalMs;
6974
- })();
6975
- function getVersionCache() {
6976
- try {
6977
- const cache = getConfig().get("version_cache");
6978
- const now = Date.now();
6979
- if (!cache || !cache.last_reset_timestamp || now - cache.last_reset_timestamp >= CACHE_RESET_INTERVAL_MILLISECONDS) {
6980
- const newCache = {
6981
- last_reset_timestamp: now,
6982
- packages: {}
6983
- };
6984
- getConfig().set("version_cache", newCache);
6985
- return newCache;
6986
- }
6987
- return cache;
6988
- } catch (error) {
6989
- log_default.debug(`Failed to read version cache: ${error}`);
6990
- return {
6991
- last_reset_timestamp: Date.now(),
6992
- packages: {}
6993
- };
6994
- }
6995
- }
6996
- function setCachedPackageInfo(packageName, version, info) {
6997
- try {
6998
- const cache = getVersionCache();
6999
- if (!cache.packages[packageName]) {
7000
- cache.packages[packageName] = {};
7001
- }
7002
- cache.packages[packageName][version] = info;
7003
- getConfig().set("version_cache", cache);
7004
- } catch (error) {
7005
- log_default.debug(`Failed to cache package info: ${error}`);
7006
- }
7007
- }
7008
- function getCachedPackageInfo(packageName, version) {
7009
- try {
7010
- const cache = getVersionCache();
7011
- return cache.packages[packageName]?.[version];
7012
- } catch (error) {
7013
- log_default.debug(`Failed to get cached package info: ${error}`);
7014
- return void 0;
7015
- }
7016
- }
7017
- async function fetchCachedPackageInfo(packageName, version) {
7018
- const cacheKey = version || "latest";
7019
- let cachedInfo = getCachedPackageInfo(packageName, cacheKey);
7020
- if (cachedInfo) {
7021
- return cachedInfo;
7022
- }
7023
- const packageInfo = await packageJsonLib__default.default(packageName, {
7024
- version,
7025
- fullMetadata: true
7026
- });
7027
- const info = {
7028
- version: packageInfo.version,
7029
- deprecated: packageInfo.deprecated,
7030
- fetched_at: (/* @__PURE__ */ new Date()).toISOString()
7031
- };
7032
- setCachedPackageInfo(packageName, cacheKey, info);
7033
- return info;
7034
- }
7035
- async function checkForUpdates({
7036
- packageName,
7037
- currentVersion
7038
- }) {
7039
- try {
7040
- const latestPackageInfo = await fetchCachedPackageInfo(packageName);
7041
- const latestVersion = latestPackageInfo.version;
7042
- const hasUpdate = semver__default.default.gt(latestVersion, currentVersion);
7043
- let currentPackageInfo;
7044
- try {
7045
- currentPackageInfo = await fetchCachedPackageInfo(
7046
- packageName,
7047
- currentVersion
7048
- );
7049
- } catch (error) {
7050
- if (!(error instanceof packageJsonLib.VersionNotFoundError)) {
7051
- log_default.debug(`Failed to check deprecation for current version: ${error}`);
7052
- }
7053
- currentPackageInfo = latestPackageInfo;
7054
- }
7055
- const isDeprecated = Boolean(currentPackageInfo.deprecated);
7056
- const deprecationMessage = isDeprecated ? String(currentPackageInfo.deprecated) : void 0;
7057
- return {
7058
- hasUpdate,
7059
- latestVersion,
7060
- currentVersion,
7061
- isDeprecated,
7062
- deprecationMessage
7063
- };
7064
- } catch (error) {
7065
- log_default.debug(`Failed to check for updates: ${error}`);
7066
- return {
7067
- hasUpdate: false,
7068
- currentVersion,
7069
- isDeprecated: false
7070
- };
7071
- }
7072
- }
7073
- function displayUpdateNotification(versionInfo, packageName) {
7074
- if (versionInfo.isDeprecated) {
7075
- console.error();
7076
- console.error(
7077
- chalk8__default.default.red.bold("\u26A0\uFE0F DEPRECATION WARNING") + chalk8__default.default.red(
7078
- ` - ${packageName} v${versionInfo.currentVersion} is deprecated.`
7079
- )
7080
- );
7081
- if (versionInfo.deprecationMessage) {
7082
- console.error(chalk8__default.default.red(` ${versionInfo.deprecationMessage}`));
7083
- }
7084
- console.error(chalk8__default.default.red(` Please update to the latest version.`));
7085
- console.error();
7086
- }
7087
- if (versionInfo.hasUpdate) {
7088
- console.error();
7089
- console.error(
7090
- chalk8__default.default.yellow.bold("\u{1F4E6} Update available!") + chalk8__default.default.yellow(
7091
- ` ${packageName} v${versionInfo.currentVersion} \u2192 v${versionInfo.latestVersion}`
7092
- )
7093
- );
7094
- console.error(
7095
- chalk8__default.default.yellow(
7096
- ` Run ${chalk8__default.default.bold(getUpdateCommand(packageName))} to update.`
7097
- )
7098
- );
7099
- console.error();
7100
- }
7101
- }
7102
- async function checkAndNotifyUpdates({
7103
- packageName,
7104
- currentVersion
7105
- }) {
7106
- if (CACHE_RESET_INTERVAL_MILLISECONDS < 0) {
7107
- return;
7108
- }
7109
- const versionInfo = await checkForUpdates({ packageName, currentVersion });
7110
- displayUpdateNotification(versionInfo, packageName);
7111
- }
7112
8538
  var EMOJI_PRESENTATION_PATTERN = /\p{Emoji_Presentation}/u;
7113
8539
  var WIDE_CODE_POINT_RANGES = [
7114
8540
  [4352, 4447],
@@ -7212,7 +8638,7 @@ function buildFrameLines(state, frameIndex) {
7212
8638
  const hasMessages = recentMessages.length > 0;
7213
8639
  recentMessages.forEach((message, index) => {
7214
8640
  const dimmed = Boolean(state.verdict) || index < recentMessages.length - 1;
7215
- const segments = wrapAnsi3__default.default(message, bodyTextWidth, { hard: true }).split(
8641
+ const segments = wrapAnsi4__default.default(message, bodyTextWidth, { hard: true }).split(
7216
8642
  "\n"
7217
8643
  );
7218
8644
  segments.forEach((segment, segmentIndex) => {
@@ -7223,7 +8649,7 @@ function buildFrameLines(state, frameIndex) {
7223
8649
  if (state.streamError) {
7224
8650
  if (hasMessages || !state.verdict) content.push("");
7225
8651
  content.push(chalk8__default.default.bold.red("Approval stream error"));
7226
- for (const segment of wrapAnsi3__default.default(state.streamError, bodyTextWidth, {
8652
+ for (const segment of wrapAnsi4__default.default(state.streamError, bodyTextWidth, {
7227
8653
  hard: true
7228
8654
  }).split("\n")) {
7229
8655
  content.push(` ${segment}`);
@@ -7235,7 +8661,7 @@ function buildFrameLines(state, frameIndex) {
7235
8661
  chalk8__default.default.bold.green(`${state.verdict.icon} ${state.verdict.label}`)
7236
8662
  );
7237
8663
  if (state.verdict.reason) {
7238
- for (const segment of wrapAnsi3__default.default(state.verdict.reason, bodyTextWidth, {
8664
+ for (const segment of wrapAnsi4__default.default(state.verdict.reason, bodyTextWidth, {
7239
8665
  hard: true
7240
8666
  }).split("\n")) {
7241
8667
  content.push(` ${segment}`);