@zapier/zapier-sdk-cli 0.65.7 → 0.66.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/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # @zapier/zapier-sdk-cli
2
2
 
3
+ ## 0.66.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 615fda9: Interactive parameter pickers keep your place across "Load more…": earlier options stay on the list in order above the cursor, the cursor lands on the first newly loaded option, and type-to-filter covers everything loaded. Paging redraws the picker in place instead of stacking a spent prompt line per page (a settled answer still prints its `✔` record). Multi-select pickers keep already-checked items checked when more options load, and a failed "Load more…" no longer discards the options already on screen — retrying continues from where the list grew.
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [e6b22fb]
12
+ - @zapier/zapier-sdk@0.84.3
13
+ - @zapier/zapier-sdk-mcp@0.18.9
14
+
15
+ ## 0.65.8
16
+
17
+ ### Patch Changes
18
+
19
+ - Updated dependencies [e1c327d]
20
+ - @zapier/zapier-sdk@0.84.2
21
+ - @zapier/zapier-sdk-mcp@0.18.8
22
+
3
23
  ## 0.65.7
4
24
 
5
25
  ### Patch Changes
package/dist/cli.cjs CHANGED
@@ -8,6 +8,7 @@ var inquirer = require('inquirer');
8
8
  var search = require('@inquirer/search');
9
9
  var chalk = require('chalk');
10
10
  var ora = require('ora');
11
+ var core = require('@inquirer/core');
11
12
  var util = require('util');
12
13
  var wrapAnsi3 = require('wrap-ansi');
13
14
  var jwt = require('jsonwebtoken');
@@ -1553,6 +1554,149 @@ Optional fields${pathContext}:`));
1553
1554
  return constants;
1554
1555
  }
1555
1556
  };
1557
+ function isSelectable(item) {
1558
+ return !core.Separator.isSeparator(item) && !item.disabled;
1559
+ }
1560
+ function normalizeChoices(choices) {
1561
+ return choices.map((choice) => {
1562
+ if (core.Separator.isSeparator(choice)) return choice;
1563
+ const name = choice.name ?? String(choice.value);
1564
+ return {
1565
+ value: choice.value,
1566
+ name,
1567
+ short: choice.short ?? name,
1568
+ disabled: choice.disabled ?? false
1569
+ };
1570
+ });
1571
+ }
1572
+ var theme = core.makeTheme({
1573
+ icon: { cursor: "\u276F" },
1574
+ style: {
1575
+ disabled: (text) => chalk__default.default.dim(`- ${text}`),
1576
+ searchTerm: (text) => chalk__default.default.cyan(text),
1577
+ keysHelpTip: (keys) => keys.map(([key, action]) => `${chalk__default.default.bold(key)} ${chalk__default.default.dim(action)}`).join(chalk__default.default.dim(" \u2022 "))
1578
+ }
1579
+ });
1580
+ var searchSelect = core.createPrompt(
1581
+ (config2, done) => {
1582
+ const { pageSize = 7 } = config2;
1583
+ const [status, setStatus] = core.useState(
1584
+ "loading"
1585
+ );
1586
+ const [searchTerm, setSearchTerm] = core.useState("");
1587
+ const [searchResults, setSearchResults] = core.useState([]);
1588
+ const [searchError, setSearchError] = core.useState();
1589
+ const prefix = core.usePrefix({ status, theme });
1590
+ const bounds = core.useMemo(() => {
1591
+ const first = searchResults.findIndex(isSelectable);
1592
+ let last = -1;
1593
+ for (let i = searchResults.length - 1; i >= 0; i--) {
1594
+ if (isSelectable(searchResults[i])) {
1595
+ last = i;
1596
+ break;
1597
+ }
1598
+ }
1599
+ return { first, last };
1600
+ }, [searchResults]);
1601
+ const defaultActive = core.useMemo(() => {
1602
+ const requested = config2.initialActive;
1603
+ if (searchTerm === "" && requested !== void 0 && requested >= 0 && requested < searchResults.length && isSelectable(searchResults[requested])) {
1604
+ return requested;
1605
+ }
1606
+ return bounds.first;
1607
+ }, [searchResults, searchTerm, bounds.first]);
1608
+ const [active = defaultActive, setActive] = core.useState();
1609
+ core.useEffect(() => {
1610
+ const controller = new AbortController();
1611
+ setStatus("loading");
1612
+ setSearchError(void 0);
1613
+ const fetchResults = async () => {
1614
+ try {
1615
+ const results = await config2.source(searchTerm || void 0);
1616
+ if (!controller.signal.aborted) {
1617
+ setActive(void 0);
1618
+ setSearchError(void 0);
1619
+ setSearchResults(normalizeChoices(results));
1620
+ setStatus("idle");
1621
+ }
1622
+ } catch (error2) {
1623
+ if (!controller.signal.aborted && error2 instanceof Error) {
1624
+ setSearchError(error2.message);
1625
+ }
1626
+ }
1627
+ };
1628
+ void fetchResults();
1629
+ return () => {
1630
+ controller.abort();
1631
+ };
1632
+ }, [searchTerm]);
1633
+ const selectedChoice = searchResults[active];
1634
+ core.useKeypress((key, rl) => {
1635
+ if (core.isEnterKey(key)) {
1636
+ if (selectedChoice && isSelectable(selectedChoice)) {
1637
+ setStatus("done");
1638
+ done(selectedChoice.value);
1639
+ } else {
1640
+ rl.write(searchTerm);
1641
+ }
1642
+ } else if (core.isTabKey(key) && selectedChoice && isSelectable(selectedChoice)) {
1643
+ rl.clearLine(0);
1644
+ rl.write(selectedChoice.name);
1645
+ setSearchTerm(selectedChoice.name);
1646
+ } else if (status !== "loading" && (core.isUpKey(key) || core.isDownKey(key))) {
1647
+ rl.clearLine(0);
1648
+ if (core.isUpKey(key) && active !== bounds.first || core.isDownKey(key) && active !== bounds.last) {
1649
+ const offset = core.isUpKey(key) ? -1 : 1;
1650
+ let next = active;
1651
+ do {
1652
+ next = (next + offset + searchResults.length) % searchResults.length;
1653
+ } while (!isSelectable(searchResults[next]));
1654
+ setActive(next);
1655
+ }
1656
+ } else {
1657
+ setSearchTerm(rl.line);
1658
+ }
1659
+ });
1660
+ const page = core.usePagination({
1661
+ items: searchResults,
1662
+ active,
1663
+ renderItem({ item, isActive }) {
1664
+ if (core.Separator.isSeparator(item)) {
1665
+ return ` ${item.separator}`;
1666
+ }
1667
+ if (item.disabled) {
1668
+ const disabledLabel = typeof item.disabled === "string" ? item.disabled : "(disabled)";
1669
+ return theme.style.disabled(`${item.name} ${disabledLabel}`);
1670
+ }
1671
+ const color = isActive ? theme.style.highlight : (x) => x;
1672
+ const cursor = isActive ? theme.icon.cursor : ` `;
1673
+ return color(`${cursor} ${item.name}`);
1674
+ },
1675
+ pageSize,
1676
+ loop: false
1677
+ });
1678
+ const message = theme.style.message(config2.message, status);
1679
+ if (status === "done" && selectedChoice && isSelectable(selectedChoice)) {
1680
+ return [prefix, message, theme.style.answer(selectedChoice.short)].filter(Boolean).join(" ").trimEnd();
1681
+ }
1682
+ const searchStr = theme.style.searchTerm(searchTerm);
1683
+ const helpTip = theme.style.keysHelpTip([
1684
+ ["\u2191\u2193", "navigate"],
1685
+ ["\u23CE", "select"]
1686
+ ]);
1687
+ let error;
1688
+ if (searchError) {
1689
+ error = theme.style.error(searchError);
1690
+ } else if (searchResults.length === 0 && searchTerm !== "" && status === "idle") {
1691
+ error = theme.style.error("No results found");
1692
+ }
1693
+ const header = [prefix, message, searchStr].filter(Boolean).join(" ").trimEnd();
1694
+ const body = [error ?? page, " ", helpTip].filter(Boolean).join("\n").trimEnd();
1695
+ return [header, body];
1696
+ }
1697
+ );
1698
+
1699
+ // src/utils/controller-answer.ts
1556
1700
  function offers(question, action) {
1557
1701
  return question.actions.some((a) => a.action === action);
1558
1702
  }
@@ -1595,21 +1739,63 @@ function buildSelectRows(question, term) {
1595
1739
  }
1596
1740
  if (offers(question, "search"))
1597
1741
  rows.push(row(chalk__default.default.cyan("Search again\u2026"), "search"));
1598
- if (offers(question, "more")) rows.push(row(chalk__default.default.dim("Load more\u2026"), "more"));
1742
+ if (offers(question, "next_page"))
1743
+ rows.push(row(chalk__default.default.dim("Load more\u2026"), "next_page"));
1599
1744
  if (offers(question, "retry")) rows.push(row(chalk__default.default.yellow("Retry"), "retry"));
1600
1745
  if (offers(question, "cancel")) rows.push(row(chalk__default.default.dim("Cancel"), "cancel"));
1601
1746
  for (const note of question.notes ?? [])
1602
1747
  rows.push({ name: chalk__default.default.dim(note), value: note, disabled: true });
1603
1748
  return rows;
1604
1749
  }
1605
- async function answerSelect(question, field) {
1606
- if (question.multiple) {
1750
+ function foldPage(acc, question, field) {
1751
+ const page = question.page;
1752
+ if (!page) {
1753
+ return {
1754
+ key: field,
1755
+ pageIndex: 0,
1756
+ choices: question.choices,
1757
+ newStart: 0,
1758
+ checked: []
1759
+ };
1760
+ }
1761
+ const key = `${field}#${page.generation}`;
1762
+ if (acc?.key === key && page.index === acc.pageIndex + 1) {
1763
+ return {
1764
+ key,
1765
+ pageIndex: page.index,
1766
+ choices: [...acc.choices, ...question.choices],
1767
+ newStart: acc.choices.length,
1768
+ checked: acc.checked
1769
+ };
1770
+ }
1771
+ if (acc?.key === key && page.index === acc.pageIndex) {
1772
+ return { ...acc, newStart: 0 };
1773
+ }
1774
+ return {
1775
+ key,
1776
+ pageIndex: page.index,
1777
+ choices: question.choices,
1778
+ newStart: 0,
1779
+ checked: []
1780
+ };
1781
+ }
1782
+ async function answerSelect(question, field, box, failed = false) {
1783
+ const acc = failed ? void 0 : box.acc = foldPage(box.acc, question, field);
1784
+ const view = acc ? { ...question, choices: acc.choices } : question;
1785
+ if (question.multiple && acc) {
1786
+ if (acc.newStart > 0 && process.stdout.isTTY) {
1787
+ process.stdout.write("\x1B[1A\x1B[2K");
1788
+ }
1607
1789
  const choices = [
1608
- ...question.choices.map((c) => ({ name: display(c), value: c.value })),
1609
- ...offers(question, "more") ? [
1790
+ ...acc.choices.map((c) => ({
1791
+ name: display(c),
1792
+ value: c.value,
1793
+ checked: acc.checked.includes(c.value)
1794
+ })),
1795
+ ...offers(question, "next_page") ? [
1610
1796
  {
1611
1797
  name: chalk__default.default.dim("Load more\u2026"),
1612
- value: { action: "more" }
1798
+ value: { action: "next_page" }
1613
1799
  }
1614
1800
  ] : [],
1615
1801
  ...(question.notes ?? []).map((note) => ({
@@ -1622,11 +1808,15 @@ async function answerSelect(question, field) {
1622
1808
  { type: "checkbox", name: "values", message: question.message, choices }
1623
1809
  ]);
1624
1810
  const selected = values;
1625
- if (selected.some(isActionRow)) return { type: "more" };
1626
- if (selected.length === 0 && offers(question, "skip")) {
1811
+ const picked = selected.filter((v) => !isActionRow(v));
1812
+ if (selected.some(isActionRow)) {
1813
+ box.acc = { ...acc, checked: picked };
1814
+ return { type: "next_page" };
1815
+ }
1816
+ if (picked.length === 0 && offers(question, "skip")) {
1627
1817
  return { type: "skip" };
1628
1818
  }
1629
- return { type: "choose", value: selected };
1819
+ return { type: "choose", value: picked };
1630
1820
  }
1631
1821
  if (offers(question, "search") && question.search === void 0) {
1632
1822
  const optional = offers(question, "skip");
@@ -1644,11 +1834,20 @@ async function answerSelect(question, field) {
1644
1834
  if (optional) return { type: "skip" };
1645
1835
  }
1646
1836
  }
1647
- const value = await search__default.default({
1648
- message: question.message,
1649
- source: (term) => buildSelectRows(question, term ?? "")
1650
- });
1837
+ const newStart = acc?.newStart ?? 0;
1838
+ const firstFreshValue = newStart > 0 ? view.choices[newStart]?.value : void 0;
1839
+ const initialActive = firstFreshValue !== void 0 ? buildSelectRows(view, "").findIndex((r) => r.value === firstFreshValue) : -1;
1840
+ const value = await searchSelect(
1841
+ {
1842
+ message: view.message,
1843
+ source: (term) => buildSelectRows(view, term ?? ""),
1844
+ ...initialActive >= 0 ? { initialActive } : {}
1845
+ },
1846
+ { clearPromptOnDone: true }
1847
+ );
1651
1848
  if (!isActionRow(value)) {
1849
+ const picked = view.choices.find((c) => c.value === value);
1850
+ printAnswered(view.message, picked?.label ?? String(value));
1652
1851
  return { type: "choose", value };
1653
1852
  }
1654
1853
  switch (value.action) {
@@ -1666,16 +1865,20 @@ async function answerSelect(question, field) {
1666
1865
  });
1667
1866
  return { type: "custom", value: custom };
1668
1867
  }
1669
- case "more":
1670
- return { type: "more" };
1868
+ case "next_page":
1869
+ return { type: "next_page" };
1671
1870
  case "retry":
1672
1871
  return { type: "retry" };
1673
1872
  case "skip":
1873
+ printAnswered(view.message, chalk__default.default.dim("(skipped)"));
1674
1874
  return { type: "skip" };
1675
1875
  case "cancel":
1676
1876
  return { type: "cancel" };
1677
1877
  }
1678
1878
  }
1879
+ function printAnswered(message, label) {
1880
+ console.log(`${chalk__default.default.green("\u2714")} ${message} ${chalk__default.default.cyan(label)}`);
1881
+ }
1679
1882
  async function answerInput(question) {
1680
1883
  const message = question.placeholder ? question.message.replace(/:?\s*$/, ` (${question.placeholder}):`) : question.message;
1681
1884
  const value = await promptText({
@@ -1712,22 +1915,25 @@ function withEngineSpinner(answer, spinner) {
1712
1915
  }
1713
1916
  };
1714
1917
  }
1715
- var answerViaCli = ({ state, result }) => {
1716
- if (result.error !== void 0) {
1717
- const message = typeof result.error === "string" ? result.error : result.error.message;
1718
- console.log(chalk__default.default.yellow(`! ${message}`));
1719
- }
1720
- const field = state.current?.join(".") ?? "value";
1721
- const question = result.question;
1722
- switch (question.type) {
1723
- case "select":
1724
- return answerSelect(question, field);
1725
- case "input":
1726
- return answerInput(question);
1727
- case "collection":
1728
- return answerCollection(question);
1729
- }
1730
- };
1918
+ function createCliAnswer() {
1919
+ const box = {};
1920
+ return ({ result }) => {
1921
+ if (result.error !== void 0) {
1922
+ const message = typeof result.error === "string" ? result.error : result.error.message;
1923
+ console.log(chalk__default.default.yellow(`! ${message}`));
1924
+ }
1925
+ const question = result.question;
1926
+ const field = question.path.length ? question.path.join(".") : "value";
1927
+ switch (question.type) {
1928
+ case "select":
1929
+ return answerSelect(question, field, box, result.status === "failed");
1930
+ case "input":
1931
+ return answerInput(question);
1932
+ case "collection":
1933
+ return answerCollection(question);
1934
+ }
1935
+ };
1936
+ }
1731
1937
 
1732
1938
  // src/utils/cli-options.ts
1733
1939
  var RESERVED_CLI_OPTIONS = [
@@ -1759,7 +1965,7 @@ var SHARED_COMMAND_CLI_OPTIONS = [
1759
1965
 
1760
1966
  // package.json
1761
1967
  var package_default = {
1762
- version: "0.65.7"};
1968
+ version: "0.66.0"};
1763
1969
 
1764
1970
  // src/telemetry/builders.ts
1765
1971
  function createCliBaseEvent(context = {}) {
@@ -2673,7 +2879,7 @@ function createCommandConfig(cliCommandName, functionInfo, sdk) {
2673
2879
  resolved = await controller.resolve({
2674
2880
  method: functionInfo.name,
2675
2881
  input: seedInput,
2676
- answer: spinner ? withEngineSpinner(answerViaCli, spinner) : promptingEnabled ? answerViaCli : ({ state }) => {
2882
+ answer: spinner ? withEngineSpinner(createCliAnswer(), spinner) : promptingEnabled ? createCliAnswer() : ({ state }) => {
2677
2883
  const missing = /* @__PURE__ */ new Map();
2678
2884
  missing.set(
2679
2885
  state.current?.join(".") ?? "value",
@@ -8020,7 +8226,7 @@ function buildBoxLines(message) {
8020
8226
  // package.json with { type: 'json' }
8021
8227
  var package_default2 = {
8022
8228
  name: "@zapier/zapier-sdk-cli",
8023
- version: "0.65.7"};
8229
+ version: "0.66.0"};
8024
8230
 
8025
8231
  // src/sdk.ts
8026
8232
  var warnedDeprecatedMethods = /* @__PURE__ */ new Set();
package/dist/cli.mjs CHANGED
@@ -6,6 +6,7 @@ import inquirer from 'inquirer';
6
6
  import search from '@inquirer/search';
7
7
  import chalk from 'chalk';
8
8
  import ora from 'ora';
9
+ import { makeTheme, createPrompt, useState, usePrefix, useMemo, useEffect, useKeypress, isEnterKey, isTabKey, isUpKey, isDownKey, usePagination, Separator } from '@inquirer/core';
9
10
  import util, { stripVTControlCharacters } from 'util';
10
11
  import wrapAnsi3 from 'wrap-ansi';
11
12
  import * as jwt from 'jsonwebtoken';
@@ -1510,6 +1511,149 @@ Optional fields${pathContext}:`));
1510
1511
  return constants;
1511
1512
  }
1512
1513
  };
1514
+ function isSelectable(item) {
1515
+ return !Separator.isSeparator(item) && !item.disabled;
1516
+ }
1517
+ function normalizeChoices(choices) {
1518
+ return choices.map((choice) => {
1519
+ if (Separator.isSeparator(choice)) return choice;
1520
+ const name = choice.name ?? String(choice.value);
1521
+ return {
1522
+ value: choice.value,
1523
+ name,
1524
+ short: choice.short ?? name,
1525
+ disabled: choice.disabled ?? false
1526
+ };
1527
+ });
1528
+ }
1529
+ var theme = makeTheme({
1530
+ icon: { cursor: "\u276F" },
1531
+ style: {
1532
+ disabled: (text) => chalk.dim(`- ${text}`),
1533
+ searchTerm: (text) => chalk.cyan(text),
1534
+ keysHelpTip: (keys) => keys.map(([key, action]) => `${chalk.bold(key)} ${chalk.dim(action)}`).join(chalk.dim(" \u2022 "))
1535
+ }
1536
+ });
1537
+ var searchSelect = createPrompt(
1538
+ (config2, done) => {
1539
+ const { pageSize = 7 } = config2;
1540
+ const [status, setStatus] = useState(
1541
+ "loading"
1542
+ );
1543
+ const [searchTerm, setSearchTerm] = useState("");
1544
+ const [searchResults, setSearchResults] = useState([]);
1545
+ const [searchError, setSearchError] = useState();
1546
+ const prefix = usePrefix({ status, theme });
1547
+ const bounds = useMemo(() => {
1548
+ const first = searchResults.findIndex(isSelectable);
1549
+ let last = -1;
1550
+ for (let i = searchResults.length - 1; i >= 0; i--) {
1551
+ if (isSelectable(searchResults[i])) {
1552
+ last = i;
1553
+ break;
1554
+ }
1555
+ }
1556
+ return { first, last };
1557
+ }, [searchResults]);
1558
+ const defaultActive = useMemo(() => {
1559
+ const requested = config2.initialActive;
1560
+ if (searchTerm === "" && requested !== void 0 && requested >= 0 && requested < searchResults.length && isSelectable(searchResults[requested])) {
1561
+ return requested;
1562
+ }
1563
+ return bounds.first;
1564
+ }, [searchResults, searchTerm, bounds.first]);
1565
+ const [active = defaultActive, setActive] = useState();
1566
+ useEffect(() => {
1567
+ const controller = new AbortController();
1568
+ setStatus("loading");
1569
+ setSearchError(void 0);
1570
+ const fetchResults = async () => {
1571
+ try {
1572
+ const results = await config2.source(searchTerm || void 0);
1573
+ if (!controller.signal.aborted) {
1574
+ setActive(void 0);
1575
+ setSearchError(void 0);
1576
+ setSearchResults(normalizeChoices(results));
1577
+ setStatus("idle");
1578
+ }
1579
+ } catch (error2) {
1580
+ if (!controller.signal.aborted && error2 instanceof Error) {
1581
+ setSearchError(error2.message);
1582
+ }
1583
+ }
1584
+ };
1585
+ void fetchResults();
1586
+ return () => {
1587
+ controller.abort();
1588
+ };
1589
+ }, [searchTerm]);
1590
+ const selectedChoice = searchResults[active];
1591
+ useKeypress((key, rl) => {
1592
+ if (isEnterKey(key)) {
1593
+ if (selectedChoice && isSelectable(selectedChoice)) {
1594
+ setStatus("done");
1595
+ done(selectedChoice.value);
1596
+ } else {
1597
+ rl.write(searchTerm);
1598
+ }
1599
+ } else if (isTabKey(key) && selectedChoice && isSelectable(selectedChoice)) {
1600
+ rl.clearLine(0);
1601
+ rl.write(selectedChoice.name);
1602
+ setSearchTerm(selectedChoice.name);
1603
+ } else if (status !== "loading" && (isUpKey(key) || isDownKey(key))) {
1604
+ rl.clearLine(0);
1605
+ if (isUpKey(key) && active !== bounds.first || isDownKey(key) && active !== bounds.last) {
1606
+ const offset = isUpKey(key) ? -1 : 1;
1607
+ let next = active;
1608
+ do {
1609
+ next = (next + offset + searchResults.length) % searchResults.length;
1610
+ } while (!isSelectable(searchResults[next]));
1611
+ setActive(next);
1612
+ }
1613
+ } else {
1614
+ setSearchTerm(rl.line);
1615
+ }
1616
+ });
1617
+ const page = usePagination({
1618
+ items: searchResults,
1619
+ active,
1620
+ renderItem({ item, isActive }) {
1621
+ if (Separator.isSeparator(item)) {
1622
+ return ` ${item.separator}`;
1623
+ }
1624
+ if (item.disabled) {
1625
+ const disabledLabel = typeof item.disabled === "string" ? item.disabled : "(disabled)";
1626
+ return theme.style.disabled(`${item.name} ${disabledLabel}`);
1627
+ }
1628
+ const color = isActive ? theme.style.highlight : (x) => x;
1629
+ const cursor = isActive ? theme.icon.cursor : ` `;
1630
+ return color(`${cursor} ${item.name}`);
1631
+ },
1632
+ pageSize,
1633
+ loop: false
1634
+ });
1635
+ const message = theme.style.message(config2.message, status);
1636
+ if (status === "done" && selectedChoice && isSelectable(selectedChoice)) {
1637
+ return [prefix, message, theme.style.answer(selectedChoice.short)].filter(Boolean).join(" ").trimEnd();
1638
+ }
1639
+ const searchStr = theme.style.searchTerm(searchTerm);
1640
+ const helpTip = theme.style.keysHelpTip([
1641
+ ["\u2191\u2193", "navigate"],
1642
+ ["\u23CE", "select"]
1643
+ ]);
1644
+ let error;
1645
+ if (searchError) {
1646
+ error = theme.style.error(searchError);
1647
+ } else if (searchResults.length === 0 && searchTerm !== "" && status === "idle") {
1648
+ error = theme.style.error("No results found");
1649
+ }
1650
+ const header = [prefix, message, searchStr].filter(Boolean).join(" ").trimEnd();
1651
+ const body = [error ?? page, " ", helpTip].filter(Boolean).join("\n").trimEnd();
1652
+ return [header, body];
1653
+ }
1654
+ );
1655
+
1656
+ // src/utils/controller-answer.ts
1513
1657
  function offers(question, action) {
1514
1658
  return question.actions.some((a) => a.action === action);
1515
1659
  }
@@ -1552,21 +1696,63 @@ function buildSelectRows(question, term) {
1552
1696
  }
1553
1697
  if (offers(question, "search"))
1554
1698
  rows.push(row(chalk.cyan("Search again\u2026"), "search"));
1555
- if (offers(question, "more")) rows.push(row(chalk.dim("Load more\u2026"), "more"));
1699
+ if (offers(question, "next_page"))
1700
+ rows.push(row(chalk.dim("Load more\u2026"), "next_page"));
1556
1701
  if (offers(question, "retry")) rows.push(row(chalk.yellow("Retry"), "retry"));
1557
1702
  if (offers(question, "cancel")) rows.push(row(chalk.dim("Cancel"), "cancel"));
1558
1703
  for (const note of question.notes ?? [])
1559
1704
  rows.push({ name: chalk.dim(note), value: note, disabled: true });
1560
1705
  return rows;
1561
1706
  }
1562
- async function answerSelect(question, field) {
1563
- if (question.multiple) {
1707
+ function foldPage(acc, question, field) {
1708
+ const page = question.page;
1709
+ if (!page) {
1710
+ return {
1711
+ key: field,
1712
+ pageIndex: 0,
1713
+ choices: question.choices,
1714
+ newStart: 0,
1715
+ checked: []
1716
+ };
1717
+ }
1718
+ const key = `${field}#${page.generation}`;
1719
+ if (acc?.key === key && page.index === acc.pageIndex + 1) {
1720
+ return {
1721
+ key,
1722
+ pageIndex: page.index,
1723
+ choices: [...acc.choices, ...question.choices],
1724
+ newStart: acc.choices.length,
1725
+ checked: acc.checked
1726
+ };
1727
+ }
1728
+ if (acc?.key === key && page.index === acc.pageIndex) {
1729
+ return { ...acc, newStart: 0 };
1730
+ }
1731
+ return {
1732
+ key,
1733
+ pageIndex: page.index,
1734
+ choices: question.choices,
1735
+ newStart: 0,
1736
+ checked: []
1737
+ };
1738
+ }
1739
+ async function answerSelect(question, field, box, failed = false) {
1740
+ const acc = failed ? void 0 : box.acc = foldPage(box.acc, question, field);
1741
+ const view = acc ? { ...question, choices: acc.choices } : question;
1742
+ if (question.multiple && acc) {
1743
+ if (acc.newStart > 0 && process.stdout.isTTY) {
1744
+ process.stdout.write("\x1B[1A\x1B[2K");
1745
+ }
1564
1746
  const choices = [
1565
- ...question.choices.map((c) => ({ name: display(c), value: c.value })),
1566
- ...offers(question, "more") ? [
1747
+ ...acc.choices.map((c) => ({
1748
+ name: display(c),
1749
+ value: c.value,
1750
+ checked: acc.checked.includes(c.value)
1751
+ })),
1752
+ ...offers(question, "next_page") ? [
1567
1753
  {
1568
1754
  name: chalk.dim("Load more\u2026"),
1569
- value: { action: "more" }
1755
+ value: { action: "next_page" }
1570
1756
  }
1571
1757
  ] : [],
1572
1758
  ...(question.notes ?? []).map((note) => ({
@@ -1579,11 +1765,15 @@ async function answerSelect(question, field) {
1579
1765
  { type: "checkbox", name: "values", message: question.message, choices }
1580
1766
  ]);
1581
1767
  const selected = values;
1582
- if (selected.some(isActionRow)) return { type: "more" };
1583
- if (selected.length === 0 && offers(question, "skip")) {
1768
+ const picked = selected.filter((v) => !isActionRow(v));
1769
+ if (selected.some(isActionRow)) {
1770
+ box.acc = { ...acc, checked: picked };
1771
+ return { type: "next_page" };
1772
+ }
1773
+ if (picked.length === 0 && offers(question, "skip")) {
1584
1774
  return { type: "skip" };
1585
1775
  }
1586
- return { type: "choose", value: selected };
1776
+ return { type: "choose", value: picked };
1587
1777
  }
1588
1778
  if (offers(question, "search") && question.search === void 0) {
1589
1779
  const optional = offers(question, "skip");
@@ -1601,11 +1791,20 @@ async function answerSelect(question, field) {
1601
1791
  if (optional) return { type: "skip" };
1602
1792
  }
1603
1793
  }
1604
- const value = await search({
1605
- message: question.message,
1606
- source: (term) => buildSelectRows(question, term ?? "")
1607
- });
1794
+ const newStart = acc?.newStart ?? 0;
1795
+ const firstFreshValue = newStart > 0 ? view.choices[newStart]?.value : void 0;
1796
+ const initialActive = firstFreshValue !== void 0 ? buildSelectRows(view, "").findIndex((r) => r.value === firstFreshValue) : -1;
1797
+ const value = await searchSelect(
1798
+ {
1799
+ message: view.message,
1800
+ source: (term) => buildSelectRows(view, term ?? ""),
1801
+ ...initialActive >= 0 ? { initialActive } : {}
1802
+ },
1803
+ { clearPromptOnDone: true }
1804
+ );
1608
1805
  if (!isActionRow(value)) {
1806
+ const picked = view.choices.find((c) => c.value === value);
1807
+ printAnswered(view.message, picked?.label ?? String(value));
1609
1808
  return { type: "choose", value };
1610
1809
  }
1611
1810
  switch (value.action) {
@@ -1623,16 +1822,20 @@ async function answerSelect(question, field) {
1623
1822
  });
1624
1823
  return { type: "custom", value: custom };
1625
1824
  }
1626
- case "more":
1627
- return { type: "more" };
1825
+ case "next_page":
1826
+ return { type: "next_page" };
1628
1827
  case "retry":
1629
1828
  return { type: "retry" };
1630
1829
  case "skip":
1830
+ printAnswered(view.message, chalk.dim("(skipped)"));
1631
1831
  return { type: "skip" };
1632
1832
  case "cancel":
1633
1833
  return { type: "cancel" };
1634
1834
  }
1635
1835
  }
1836
+ function printAnswered(message, label) {
1837
+ console.log(`${chalk.green("\u2714")} ${message} ${chalk.cyan(label)}`);
1838
+ }
1636
1839
  async function answerInput(question) {
1637
1840
  const message = question.placeholder ? question.message.replace(/:?\s*$/, ` (${question.placeholder}):`) : question.message;
1638
1841
  const value = await promptText({
@@ -1669,22 +1872,25 @@ function withEngineSpinner(answer, spinner) {
1669
1872
  }
1670
1873
  };
1671
1874
  }
1672
- var answerViaCli = ({ state, result }) => {
1673
- if (result.error !== void 0) {
1674
- const message = typeof result.error === "string" ? result.error : result.error.message;
1675
- console.log(chalk.yellow(`! ${message}`));
1676
- }
1677
- const field = state.current?.join(".") ?? "value";
1678
- const question = result.question;
1679
- switch (question.type) {
1680
- case "select":
1681
- return answerSelect(question, field);
1682
- case "input":
1683
- return answerInput(question);
1684
- case "collection":
1685
- return answerCollection(question);
1686
- }
1687
- };
1875
+ function createCliAnswer() {
1876
+ const box = {};
1877
+ return ({ result }) => {
1878
+ if (result.error !== void 0) {
1879
+ const message = typeof result.error === "string" ? result.error : result.error.message;
1880
+ console.log(chalk.yellow(`! ${message}`));
1881
+ }
1882
+ const question = result.question;
1883
+ const field = question.path.length ? question.path.join(".") : "value";
1884
+ switch (question.type) {
1885
+ case "select":
1886
+ return answerSelect(question, field, box, result.status === "failed");
1887
+ case "input":
1888
+ return answerInput(question);
1889
+ case "collection":
1890
+ return answerCollection(question);
1891
+ }
1892
+ };
1893
+ }
1688
1894
 
1689
1895
  // src/utils/cli-options.ts
1690
1896
  var RESERVED_CLI_OPTIONS = [
@@ -1716,7 +1922,7 @@ var SHARED_COMMAND_CLI_OPTIONS = [
1716
1922
 
1717
1923
  // package.json
1718
1924
  var package_default = {
1719
- version: "0.65.7"};
1925
+ version: "0.66.0"};
1720
1926
 
1721
1927
  // src/telemetry/builders.ts
1722
1928
  function createCliBaseEvent(context = {}) {
@@ -2630,7 +2836,7 @@ function createCommandConfig(cliCommandName, functionInfo, sdk) {
2630
2836
  resolved = await controller.resolve({
2631
2837
  method: functionInfo.name,
2632
2838
  input: seedInput,
2633
- answer: spinner ? withEngineSpinner(answerViaCli, spinner) : promptingEnabled ? answerViaCli : ({ state }) => {
2839
+ answer: spinner ? withEngineSpinner(createCliAnswer(), spinner) : promptingEnabled ? createCliAnswer() : ({ state }) => {
2634
2840
  const missing = /* @__PURE__ */ new Map();
2635
2841
  missing.set(
2636
2842
  state.current?.join(".") ?? "value",
@@ -7977,7 +8183,7 @@ function buildBoxLines(message) {
7977
8183
  // package.json with { type: 'json' }
7978
8184
  var package_default2 = {
7979
8185
  name: "@zapier/zapier-sdk-cli",
7980
- version: "0.65.7"};
8186
+ version: "0.66.0"};
7981
8187
 
7982
8188
  // src/sdk.ts
7983
8189
  var warnedDeprecatedMethods = /* @__PURE__ */ new Set();
@@ -5109,7 +5109,7 @@ function collectDeprecationNoticeAndForward(event, onEvent) {
5109
5109
  // package.json with { type: 'json' }
5110
5110
  var package_default = {
5111
5111
  name: "@zapier/zapier-sdk-cli",
5112
- version: "0.65.7"};
5112
+ version: "0.66.0"};
5113
5113
 
5114
5114
  // src/sdk.ts
5115
5115
  var warnedDeprecatedMethods = /* @__PURE__ */ new Set();
@@ -5073,7 +5073,7 @@ function collectDeprecationNoticeAndForward(event, onEvent) {
5073
5073
  // package.json with { type: 'json' }
5074
5074
  var package_default = {
5075
5075
  name: "@zapier/zapier-sdk-cli",
5076
- version: "0.65.7"};
5076
+ version: "0.66.0"};
5077
5077
 
5078
5078
  // src/sdk.ts
5079
5079
  var warnedDeprecatedMethods = /* @__PURE__ */ new Set();
package/dist/index.cjs CHANGED
@@ -5109,7 +5109,7 @@ function collectDeprecationNoticeAndForward(event, onEvent) {
5109
5109
  // package.json with { type: 'json' }
5110
5110
  var package_default = {
5111
5111
  name: "@zapier/zapier-sdk-cli",
5112
- version: "0.65.7"};
5112
+ version: "0.66.0"};
5113
5113
 
5114
5114
  // src/sdk.ts
5115
5115
  var warnedDeprecatedMethods = /* @__PURE__ */ new Set();
@@ -5192,7 +5192,7 @@ function createZapierCliSdk(options = {}) {
5192
5192
 
5193
5193
  // package.json
5194
5194
  var package_default2 = {
5195
- version: "0.65.7"};
5195
+ version: "0.66.0"};
5196
5196
 
5197
5197
  // src/telemetry/builders.ts
5198
5198
  function createCliBaseEvent(context = {}) {
package/dist/index.mjs CHANGED
@@ -5073,7 +5073,7 @@ function collectDeprecationNoticeAndForward(event, onEvent) {
5073
5073
  // package.json with { type: 'json' }
5074
5074
  var package_default = {
5075
5075
  name: "@zapier/zapier-sdk-cli",
5076
- version: "0.65.7"};
5076
+ version: "0.66.0"};
5077
5077
 
5078
5078
  // src/sdk.ts
5079
5079
  var warnedDeprecatedMethods = /* @__PURE__ */ new Set();
@@ -5156,7 +5156,7 @@ function createZapierCliSdk(options = {}) {
5156
5156
 
5157
5157
  // package.json
5158
5158
  var package_default2 = {
5159
- version: "0.65.7"};
5159
+ version: "0.66.0"};
5160
5160
 
5161
5161
  // src/telemetry/builders.ts
5162
5162
  function createCliBaseEvent(context = {}) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zapier/zapier-sdk-cli",
3
- "version": "0.65.7",
3
+ "version": "0.66.0",
4
4
  "description": "Command line interface for Zapier SDK",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.mjs",
@@ -71,6 +71,7 @@
71
71
  "access": "public"
72
72
  },
73
73
  "dependencies": {
74
+ "@inquirer/core": "^10.3.2",
74
75
  "@inquirer/search": "^3.2.2",
75
76
  "@zapier/policy-schema": "0.15.0",
76
77
  "chalk": "^5.3.0",
@@ -93,8 +94,8 @@
93
94
  "typescript": "^5.8.3",
94
95
  "wrap-ansi": "^10.0.0",
95
96
  "zod": "4.3.6",
96
- "@zapier/zapier-sdk": "0.84.1",
97
- "@zapier/zapier-sdk-mcp": "0.18.7"
97
+ "@zapier/zapier-sdk-mcp": "0.18.9",
98
+ "@zapier/zapier-sdk": "0.84.3"
98
99
  },
99
100
  "devDependencies": {
100
101
  "@types/express": "^5.0.3",