terminal-pilot 0.0.47 → 0.0.49

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/dist/cli.d.ts +5 -0
  2. package/dist/cli.js +706 -164
  3. package/dist/cli.js.map +4 -4
  4. package/dist/commands/close-session.js.map +1 -1
  5. package/dist/commands/create-session.js.map +1 -1
  6. package/dist/commands/daemon-runtime.js.map +1 -1
  7. package/dist/commands/fill.js.map +1 -1
  8. package/dist/commands/get-session.js.map +1 -1
  9. package/dist/commands/index.js +77 -10
  10. package/dist/commands/index.js.map +4 -4
  11. package/dist/commands/install.js +81 -14
  12. package/dist/commands/install.js.map +4 -4
  13. package/dist/commands/installer.js +37 -6
  14. package/dist/commands/installer.js.map +3 -3
  15. package/dist/commands/list-sessions.js.map +1 -1
  16. package/dist/commands/press-key.js.map +1 -1
  17. package/dist/commands/read-history.js.map +1 -1
  18. package/dist/commands/read-screen.js.map +1 -1
  19. package/dist/commands/resize.js.map +1 -1
  20. package/dist/commands/runtime.js.map +1 -1
  21. package/dist/commands/screenshot.js.map +1 -1
  22. package/dist/commands/send-signal.js.map +1 -1
  23. package/dist/commands/type.js.map +1 -1
  24. package/dist/commands/uninstall.js +37 -6
  25. package/dist/commands/uninstall.js.map +3 -3
  26. package/dist/commands/wait-for-exit.js.map +1 -1
  27. package/dist/commands/wait-for.js.map +1 -1
  28. package/dist/composition.json +6 -1
  29. package/dist/testing/cli-repl.js +704 -163
  30. package/dist/testing/cli-repl.js.map +4 -4
  31. package/dist/testing/qa-cli.js +704 -163
  32. package/dist/testing/qa-cli.js.map +4 -4
  33. package/node_modules/@poe-code/agent-defs/README.md +15 -2
  34. package/node_modules/@poe-code/agent-defs/dist/agents/claude-code.js +2 -1
  35. package/node_modules/@poe-code/agent-defs/dist/agents/claude-desktop.js +1 -0
  36. package/node_modules/@poe-code/agent-defs/dist/agents/codex.js +2 -1
  37. package/node_modules/@poe-code/agent-defs/dist/agents/cursor.js +1 -0
  38. package/node_modules/@poe-code/agent-defs/dist/agents/gemini-cli.js +2 -1
  39. package/node_modules/@poe-code/agent-defs/dist/agents/goose.js +1 -0
  40. package/node_modules/@poe-code/agent-defs/dist/agents/index.d.ts +1 -0
  41. package/node_modules/@poe-code/agent-defs/dist/agents/index.js +1 -0
  42. package/node_modules/@poe-code/agent-defs/dist/agents/kimi.js +2 -1
  43. package/node_modules/@poe-code/agent-defs/dist/agents/opencode.js +2 -1
  44. package/node_modules/@poe-code/agent-defs/dist/agents/pi.d.ts +2 -0
  45. package/node_modules/@poe-code/agent-defs/dist/agents/pi.js +15 -0
  46. package/node_modules/@poe-code/agent-defs/dist/agents/poe-agent.js +1 -0
  47. package/node_modules/@poe-code/agent-defs/dist/capabilities.d.ts +14 -0
  48. package/node_modules/@poe-code/agent-defs/dist/capabilities.js +63 -0
  49. package/node_modules/@poe-code/agent-defs/dist/index.d.ts +3 -2
  50. package/node_modules/@poe-code/agent-defs/dist/index.js +2 -1
  51. package/node_modules/@poe-code/agent-defs/dist/registry.js +5 -1
  52. package/node_modules/@poe-code/agent-defs/dist/types.d.ts +8 -1
  53. package/node_modules/@poe-code/agent-skill-config/dist/apply.d.ts +2 -0
  54. package/node_modules/@poe-code/agent-skill-config/dist/apply.js +18 -14
  55. package/node_modules/@poe-code/agent-skill-config/dist/bridge-active-skills.js +3 -1
  56. package/node_modules/@poe-code/agent-skill-config/dist/configs.d.ts +2 -0
  57. package/node_modules/@poe-code/agent-skill-config/dist/configs.js +2 -1
  58. package/node_modules/@poe-code/frontmatter/README.md +3 -0
  59. package/node_modules/@poe-code/frontmatter/dist/index.d.ts +1 -1
  60. package/node_modules/@poe-code/frontmatter/dist/index.js +1 -1
  61. package/node_modules/@poe-code/frontmatter/dist/parse.d.ts +9 -0
  62. package/node_modules/@poe-code/frontmatter/dist/parse.js +16 -0
  63. package/node_modules/toolcraft-design/dist/acp/components.d.ts +8 -1
  64. package/node_modules/toolcraft-design/dist/acp/components.js +11 -6
  65. package/node_modules/toolcraft-design/dist/acp/index.d.ts +1 -0
  66. package/node_modules/toolcraft-design/dist/components/command-errors.d.ts +2 -0
  67. package/node_modules/toolcraft-design/dist/components/command-errors.js +8 -2
  68. package/node_modules/toolcraft-design/dist/components/help-formatter-plain.js +61 -25
  69. package/node_modules/toolcraft-design/dist/components/help-formatter.d.ts +17 -0
  70. package/node_modules/toolcraft-design/dist/components/help-formatter.js +128 -29
  71. package/node_modules/toolcraft-design/dist/components/index.d.ts +3 -3
  72. package/node_modules/toolcraft-design/dist/components/index.js +2 -2
  73. package/node_modules/toolcraft-design/dist/components/table.d.ts +1 -0
  74. package/node_modules/toolcraft-design/dist/components/table.js +52 -5
  75. package/node_modules/toolcraft-design/dist/components/template.d.ts +9 -0
  76. package/node_modules/toolcraft-design/dist/components/template.js +27 -2
  77. package/node_modules/toolcraft-design/dist/explorer/actions.d.ts +1 -0
  78. package/node_modules/toolcraft-design/dist/explorer/actions.js +1 -0
  79. package/node_modules/toolcraft-design/dist/explorer/reducer.js +1 -0
  80. package/node_modules/toolcraft-design/dist/explorer/runtime.js +21 -2
  81. package/node_modules/toolcraft-design/dist/explorer/state.d.ts +6 -0
  82. package/node_modules/toolcraft-design/dist/explorer/state.js +9 -6
  83. package/node_modules/toolcraft-design/dist/help-formatter.d.ts +2 -2
  84. package/node_modules/toolcraft-design/dist/help-formatter.js +1 -1
  85. package/node_modules/toolcraft-design/dist/index.d.ts +4 -4
  86. package/node_modules/toolcraft-design/dist/index.js +3 -3
  87. package/node_modules/toolcraft-design/dist/prompts/interactive/core.d.ts +5 -0
  88. package/node_modules/toolcraft-design/dist/prompts/interactive/core.js +15 -1
  89. package/node_modules/toolcraft-design/dist/prompts/primitives/spinner.js +1 -1
  90. package/package.json +4 -3
@@ -1650,26 +1650,68 @@ function splitWords(value) {
1650
1650
  }
1651
1651
  return words;
1652
1652
  }
1653
- function wrapWords(value, width) {
1654
- const words = splitWords(value);
1653
+ function leadingWhitespaceWidth(value) {
1654
+ let index = 0;
1655
+ while (index < value.length && isWhitespace(value[index])) {
1656
+ index += 1;
1657
+ }
1658
+ return { prefix: value.slice(0, index), rest: value.slice(index) };
1659
+ }
1660
+ function takeVisiblePrefix(value, width) {
1661
+ let visible = 0;
1662
+ let index = 0;
1663
+ while (index < value.length) {
1664
+ const controlEnd = readControlSequence(value, index);
1665
+ if (controlEnd !== void 0) {
1666
+ index = controlEnd;
1667
+ continue;
1668
+ }
1669
+ const segment = graphemeSegmenter.segment(value.slice(index))[Symbol.iterator]().next().value;
1670
+ const cluster = segment?.segment ?? value[index] ?? "";
1671
+ const nextWidth = clusterWidth(cluster);
1672
+ if (visible > 0 && visible + nextWidth > width) {
1673
+ break;
1674
+ }
1675
+ visible += nextWidth;
1676
+ index += cluster.length || 1;
1677
+ }
1678
+ return { prefix: value.slice(0, index), rest: value.slice(index) };
1679
+ }
1680
+ function wrapWords(value, width, continuationWidth = width) {
1681
+ const { prefix, rest } = leadingWhitespaceWidth(value);
1682
+ const prefixWidth = visibleWidth(prefix);
1683
+ const firstContentWidth = Math.max(1, width - prefixWidth);
1684
+ const words = splitWords(rest);
1655
1685
  if (words.length === 0) {
1656
- return [""];
1686
+ return [prefix];
1657
1687
  }
1658
1688
  const lines = [];
1659
1689
  let line = "";
1690
+ let isFirstLine = true;
1660
1691
  for (const word of words) {
1661
- if (!line) {
1662
- line = word;
1663
- continue;
1664
- }
1665
- if (visibleWidth(line) + 1 + visibleWidth(word) <= width) {
1692
+ const limit = isFirstLine ? firstContentWidth : continuationWidth;
1693
+ if (line && visibleWidth(line) + 1 + visibleWidth(word) <= limit) {
1666
1694
  line += ` ${word}`;
1667
1695
  continue;
1668
1696
  }
1669
- lines.push(line);
1670
- line = word;
1697
+ if (line) {
1698
+ lines.push(isFirstLine ? `${prefix}${line}` : line);
1699
+ isFirstLine = false;
1700
+ line = "";
1701
+ }
1702
+ let remaining = word;
1703
+ while (visibleWidth(remaining) > (isFirstLine ? firstContentWidth : continuationWidth)) {
1704
+ const chunk = takeVisiblePrefix(
1705
+ remaining,
1706
+ isFirstLine ? firstContentWidth : continuationWidth
1707
+ );
1708
+ lines.push(isFirstLine ? `${prefix}${chunk.prefix}` : chunk.prefix);
1709
+ isFirstLine = false;
1710
+ remaining = chunk.rest;
1711
+ }
1712
+ line = remaining;
1671
1713
  }
1672
- lines.push(line);
1714
+ lines.push(isFirstLine ? `${prefix}${line}` : line);
1673
1715
  return lines;
1674
1716
  }
1675
1717
  function validateLayoutValue(value, name) {
@@ -1697,37 +1739,90 @@ function formatColumns(opts) {
1697
1739
  validateLayoutValue(indent, "indent");
1698
1740
  const maxLeftContentWidth = Math.max(...rows.map((row) => visibleWidth(row.left)));
1699
1741
  const leftWidth = clamp(maxLeftContentWidth + gap, minLeftWidth, maxLeftWidth);
1700
- const rightWidth = Math.max(20, totalWidth - leftWidth - indent);
1742
+ const rightWidth = Math.max(1, totalWidth - leftWidth - indent);
1743
+ const leftWrapWidth = Math.max(1, totalWidth - indent);
1701
1744
  const firstIndent = " ".repeat(indent);
1702
1745
  const continuationIndent = " ".repeat(indent + leftWidth);
1703
1746
  return rows.flatMap((row) => {
1747
+ const leftLeading = leadingWhitespaceWidth(row.left).prefix;
1748
+ const leftHangIndent = " ".repeat(indent + visibleWidth(leftLeading) + 2);
1749
+ const leftLines = wrapWords(
1750
+ row.left,
1751
+ leftWrapWidth,
1752
+ Math.max(1, totalWidth - visibleWidth(leftHangIndent))
1753
+ );
1704
1754
  if (row.right.length === 0) {
1705
- return [`${firstIndent}${row.left}`];
1755
+ return leftLines.map(
1756
+ (line, index) => index === 0 ? `${firstIndent}${line}` : `${leftHangIndent}${line}`
1757
+ );
1706
1758
  }
1707
1759
  const rightLines = wrapWords(row.right, rightWidth);
1708
- if (visibleWidth(row.left) >= leftWidth) {
1709
- return [
1710
- `${firstIndent}${row.left}`,
1711
- ...rightLines.map((line) => `${continuationIndent}${line}`)
1712
- ];
1713
- }
1714
- const firstLine = `${firstIndent}${padEndVisible(row.left, leftWidth)}${rightLines[0]}`;
1715
- const continuationLines = rightLines.slice(1).map((line) => `${continuationIndent}${line}`);
1716
- return [firstLine, ...continuationLines];
1760
+ const leftFitsInColumn = visibleWidth(row.left) < leftWidth;
1761
+ if (leftFitsInColumn && leftLines.length === 1) {
1762
+ const firstLine = `${firstIndent}${padEndVisible(leftLines[0] ?? "", leftWidth)}${rightLines[0]}`;
1763
+ const continuationLines = rightLines.slice(1).map((line) => `${continuationIndent}${line}`);
1764
+ return [firstLine, ...continuationLines];
1765
+ }
1766
+ const renderedLeft = leftLines.map(
1767
+ (line, index) => index === 0 ? `${firstIndent}${line}` : `${leftHangIndent}${line}`
1768
+ );
1769
+ const renderedRight = rightLines.map((line) => `${continuationIndent}${line}`);
1770
+ return [...renderedLeft, ...renderedRight];
1717
1771
  }).join("\n");
1718
1772
  }
1773
+ function styleHelpToken(token) {
1774
+ switch (token.role) {
1775
+ case "command":
1776
+ return text.command(token.text);
1777
+ case "argument":
1778
+ return styleArgumentToken(token.text);
1779
+ case "option":
1780
+ return text.option(token.text);
1781
+ case "dim":
1782
+ return styleDim(token.text);
1783
+ case "literal":
1784
+ return token.text;
1785
+ }
1786
+ }
1787
+ function styleArgumentToken(content) {
1788
+ const format = resolveOutputFormat();
1789
+ if (format === "markdown" && content.startsWith("<") && content.endsWith(">")) {
1790
+ return text.argument(content.slice(1, -1));
1791
+ }
1792
+ if (format === "json") {
1793
+ return content;
1794
+ }
1795
+ return text.argument(content);
1796
+ }
1797
+ function styleDim(content) {
1798
+ const format = resolveOutputFormat();
1799
+ if (format === "json" || format === "markdown") {
1800
+ return content;
1801
+ }
1802
+ return typography.dim(content);
1803
+ }
1804
+ function joinHelpTokens(tokens) {
1805
+ return tokens.map((token) => token.text).join("");
1806
+ }
1807
+ function renderHelpTokens(tokens) {
1808
+ return tokens.map((token) => styleHelpToken(token)).join("");
1809
+ }
1719
1810
  function formatCommandList(commands) {
1720
1811
  return formatColumns({
1721
- rows: commands.map((cmd) => ({
1722
- left: text.command(cmd.name),
1723
- right: cmd.description
1724
- }))
1812
+ rows: commands.map((cmd) => {
1813
+ const depthPrefix = " ".repeat((cmd.depth ?? 0) * 2);
1814
+ const styledName = cmd.nameTokens !== void 0 && cmd.nameTokens.length > 0 ? renderHelpTokens(cmd.nameTokens) : text.command(cmd.name);
1815
+ return {
1816
+ left: `${depthPrefix}${styledName}`,
1817
+ right: cmd.description
1818
+ };
1819
+ })
1725
1820
  });
1726
1821
  }
1727
1822
  function formatOptionList(options) {
1728
1823
  return formatColumns({
1729
1824
  rows: options.map((opt) => ({
1730
- left: text.option(opt.flags),
1825
+ left: opt.flagTokens !== void 0 && opt.flagTokens.length > 0 ? renderHelpTokens(opt.flagTokens) : text.option(opt.flags),
1731
1826
  right: opt.description
1732
1827
  }))
1733
1828
  });
@@ -1797,26 +1892,47 @@ function splitWords2(value) {
1797
1892
  }
1798
1893
  return words;
1799
1894
  }
1800
- function wrapWords2(value, width) {
1801
- const words = splitWords2(value);
1895
+ function leadingWhitespace(value) {
1896
+ let index = 0;
1897
+ while (index < value.length && isWhitespace2(value[index])) {
1898
+ index += 1;
1899
+ }
1900
+ return { prefix: value.slice(0, index), rest: value.slice(index) };
1901
+ }
1902
+ function takePrefix(value, width) {
1903
+ return { prefix: value.slice(0, width), rest: value.slice(width) };
1904
+ }
1905
+ function wrapWords2(value, width, continuationWidth = width) {
1906
+ const { prefix, rest } = leadingWhitespace(value);
1907
+ const firstContentWidth = Math.max(1, width - prefix.length);
1908
+ const words = splitWords2(rest);
1802
1909
  if (words.length === 0) {
1803
- return [""];
1910
+ return [prefix];
1804
1911
  }
1805
1912
  const lines = [];
1806
1913
  let line = "";
1914
+ let isFirstLine = true;
1807
1915
  for (const word of words) {
1808
- if (!line) {
1809
- line = word;
1810
- continue;
1811
- }
1812
- if (line.length + 1 + word.length <= width) {
1916
+ const limit = isFirstLine ? firstContentWidth : continuationWidth;
1917
+ if (line && line.length + 1 + word.length <= limit) {
1813
1918
  line += ` ${word}`;
1814
1919
  continue;
1815
1920
  }
1816
- lines.push(line);
1817
- line = word;
1921
+ if (line) {
1922
+ lines.push(isFirstLine ? `${prefix}${line}` : line);
1923
+ isFirstLine = false;
1924
+ line = "";
1925
+ }
1926
+ let remaining = word;
1927
+ while (remaining.length > (isFirstLine ? firstContentWidth : continuationWidth)) {
1928
+ const chunk = takePrefix(remaining, isFirstLine ? firstContentWidth : continuationWidth);
1929
+ lines.push(isFirstLine ? `${prefix}${chunk.prefix}` : chunk.prefix);
1930
+ isFirstLine = false;
1931
+ remaining = chunk.rest;
1932
+ }
1933
+ line = remaining;
1818
1934
  }
1819
- lines.push(line);
1935
+ lines.push(isFirstLine ? `${prefix}${line}` : line);
1820
1936
  return lines;
1821
1937
  }
1822
1938
  function formatColumns2(opts) {
@@ -1834,29 +1950,44 @@ function formatColumns2(opts) {
1834
1950
  const indent = opts.indent ?? 2;
1835
1951
  const maxLeftContentWidth = Math.max(...rows.map((row) => row.left.length));
1836
1952
  const leftWidth = clamp2(maxLeftContentWidth + gap, minLeftWidth, maxLeftWidth);
1837
- const rightWidth = Math.max(20, totalWidth - leftWidth - indent);
1953
+ const rightWidth = Math.max(1, totalWidth - leftWidth - indent);
1954
+ const leftWrapWidth = Math.max(1, totalWidth - indent);
1838
1955
  const firstIndent = " ".repeat(indent);
1839
1956
  const continuationIndent = " ".repeat(indent + leftWidth);
1840
1957
  return rows.flatMap((row) => {
1958
+ let leftLeadingWidth = 0;
1959
+ while (leftLeadingWidth < row.left.length && isWhitespace2(row.left[leftLeadingWidth])) {
1960
+ leftLeadingWidth += 1;
1961
+ }
1962
+ const leftHangIndent = " ".repeat(indent + leftLeadingWidth + 2);
1963
+ const leftLines = wrapWords2(
1964
+ row.left,
1965
+ leftWrapWidth,
1966
+ Math.max(1, totalWidth - leftHangIndent.length)
1967
+ );
1841
1968
  if (row.right.length === 0) {
1842
- return [`${firstIndent}${row.left}`];
1969
+ return leftLines.map(
1970
+ (line, index) => index === 0 ? `${firstIndent}${line}` : `${leftHangIndent}${line}`
1971
+ );
1843
1972
  }
1844
1973
  const rightLines = wrapWords2(row.right, rightWidth);
1845
- if (row.left.length >= leftWidth) {
1846
- return [
1847
- `${firstIndent}${row.left}`,
1848
- ...rightLines.map((line) => `${continuationIndent}${line}`)
1849
- ];
1850
- }
1851
- const firstLine = `${firstIndent}${padEndVisible2(row.left, leftWidth)}${rightLines[0]}`;
1852
- const continuationLines = rightLines.slice(1).map((line) => `${continuationIndent}${line}`);
1853
- return [firstLine, ...continuationLines];
1974
+ const leftFitsInColumn = row.left.length < leftWidth;
1975
+ if (leftFitsInColumn && leftLines.length === 1) {
1976
+ const firstLine = `${firstIndent}${padEndVisible2(leftLines[0] ?? "", leftWidth)}${rightLines[0]}`;
1977
+ const continuationLines = rightLines.slice(1).map((line) => `${continuationIndent}${line}`);
1978
+ return [firstLine, ...continuationLines];
1979
+ }
1980
+ const renderedLeft = leftLines.map(
1981
+ (line, index) => index === 0 ? `${firstIndent}${line}` : `${leftHangIndent}${line}`
1982
+ );
1983
+ const renderedRight = rightLines.map((line) => `${continuationIndent}${line}`);
1984
+ return [...renderedLeft, ...renderedRight];
1854
1985
  }).join("\n");
1855
1986
  }
1856
1987
  function formatCommandList2(commands) {
1857
1988
  return formatColumns2({
1858
1989
  rows: commands.map((cmd) => ({
1859
- left: cmd.name,
1990
+ left: `${" ".repeat((cmd.depth ?? 0) * 2)}${cmd.nameTokens !== void 0 && cmd.nameTokens.length > 0 ? joinHelpTokens(cmd.nameTokens) : cmd.name}`,
1860
1991
  right: cmd.description
1861
1992
  }))
1862
1993
  });
@@ -1864,7 +1995,7 @@ function formatCommandList2(commands) {
1864
1995
  function formatOptionList2(options) {
1865
1996
  return formatColumns2({
1866
1997
  rows: options.map((opt) => ({
1867
- left: opt.flags,
1998
+ left: opt.flagTokens !== void 0 && opt.flagTokens.length > 0 ? joinHelpTokens(opt.flagTokens) : opt.flags,
1868
1999
  right: opt.description
1869
2000
  }))
1870
2001
  });
@@ -1873,6 +2004,7 @@ function formatOptionList2(options) {
1873
2004
  // ../toolcraft-design/src/components/table.ts
1874
2005
  var reset2 = "\x1B[0m";
1875
2006
  var ellipsis = "\u2026";
2007
+ var minCellWidth = 4;
1876
2008
  var graphemeSegmenter2 = new Intl.Segmenter(void 0, { granularity: "grapheme" });
1877
2009
  function getCell(row, name) {
1878
2010
  return Object.prototype.hasOwnProperty.call(row, name) ? row[name] ?? "" : "";
@@ -2006,6 +2138,39 @@ function computeColumns(columns) {
2006
2138
  width: getColumnWidth(column)
2007
2139
  }));
2008
2140
  }
2141
+ function frameWidth(columnCount) {
2142
+ return columnCount * 3 + 1;
2143
+ }
2144
+ function budgetColumns(columns, maxWidth) {
2145
+ if (maxWidth === void 0) {
2146
+ return columns;
2147
+ }
2148
+ const available = maxWidth - frameWidth(columns.length);
2149
+ const contentWidth = (cap2) => columns.reduce((total, column) => total + Math.min(column.width, cap2), 0);
2150
+ if (columns.reduce((total, column) => total + column.width, 0) <= available) {
2151
+ return columns;
2152
+ }
2153
+ let cap = minCellWidth;
2154
+ while (contentWidth(cap + 1) <= available) {
2155
+ cap += 1;
2156
+ }
2157
+ const budgeted = columns.map((column) => ({ ...column, width: Math.min(column.width, cap) }));
2158
+ let slack = available - contentWidth(cap);
2159
+ while (slack > 0) {
2160
+ const growable = budgeted.filter((column, index) => column.width < columns[index].width);
2161
+ if (growable.length === 0) {
2162
+ break;
2163
+ }
2164
+ for (const column of growable) {
2165
+ if (slack === 0) {
2166
+ break;
2167
+ }
2168
+ column.width += 1;
2169
+ slack -= 1;
2170
+ }
2171
+ }
2172
+ return budgeted;
2173
+ }
2009
2174
  function renderBorder(columns, theme, parts) {
2010
2175
  const horizontal = theme.muted("\u2500");
2011
2176
  const segments = columns.map((column) => horizontal.repeat(column.width + 2));
@@ -2090,14 +2255,15 @@ function renderTableTerminal(options) {
2090
2255
  }
2091
2256
  const separatorOptions = options;
2092
2257
  const includeRowSeparators = separatorOptions.rowSeparator === true || separatorOptions.rowSeparators === true;
2093
- const top = renderBorder(computedColumns, theme, { left: "\u250C", mid: "\u252C", right: "\u2510" });
2258
+ const budgetedColumns = budgetColumns(computedColumns, options.maxWidth ?? process.stdout.columns);
2259
+ const top = renderBorder(budgetedColumns, theme, { left: "\u250C", mid: "\u252C", right: "\u2510" });
2094
2260
  const header = renderTerminalRow(
2095
- computedColumns.map((column) => theme.header(column.title)),
2096
- computedColumns,
2261
+ budgetedColumns.map((column) => theme.header(column.title)),
2262
+ budgetedColumns,
2097
2263
  theme
2098
2264
  );
2099
- const headerBottom = renderBorder(computedColumns, theme, { left: "\u251C", mid: "\u253C", right: "\u2524" });
2100
- const bottom = renderBorder(computedColumns, theme, { left: "\u2514", mid: "\u2534", right: "\u2518" });
2265
+ const headerBottom = renderBorder(budgetedColumns, theme, { left: "\u251C", mid: "\u253C", right: "\u2524" });
2266
+ const bottom = renderBorder(budgetedColumns, theme, { left: "\u2514", mid: "\u2534", right: "\u2518" });
2101
2267
  const renderedRows = [];
2102
2268
  for (const [index, row] of rows.entries()) {
2103
2269
  if (includeRowSeparators && index > 0) {
@@ -2105,8 +2271,8 @@ function renderTableTerminal(options) {
2105
2271
  }
2106
2272
  renderedRows.push(
2107
2273
  renderTerminalRow(
2108
- computedColumns.map((column) => getCell(row, column.name)),
2109
- computedColumns,
2274
+ budgetedColumns.map((column) => getCell(row, column.name)),
2275
+ budgetedColumns,
2110
2276
  theme
2111
2277
  )
2112
2278
  );
@@ -2199,6 +2365,19 @@ ${options.theme.muted(options.badges.map((badge) => badge[0] + badge.slice(1).to
2199
2365
 
2200
2366
  // ../toolcraft-design/src/components/template.ts
2201
2367
  var MAX_PARTIAL_DEPTH = 100;
2368
+ var MAX_TAG_EXCERPT_LENGTH = 40;
2369
+ var TemplateParseError = class extends Error {
2370
+ description;
2371
+ line;
2372
+ column;
2373
+ constructor(description, position) {
2374
+ super(`${description} at line ${position.line}, column ${position.column}`);
2375
+ this.name = "TemplateParseError";
2376
+ this.description = description;
2377
+ this.line = position.line;
2378
+ this.column = position.column;
2379
+ }
2380
+ };
2202
2381
  var HTML_ESCAPE = {
2203
2382
  "&": "&amp;",
2204
2383
  "<": "&lt;",
@@ -2305,13 +2484,13 @@ function parseTag(template, open) {
2305
2484
  if (template.startsWith("{{{", open)) {
2306
2485
  const close2 = template.indexOf("}}}", open + 3);
2307
2486
  if (close2 === -1) {
2308
- throw new Error("Unclosed unescaped tag");
2487
+ throw unclosedTagError(template, open, "}}}");
2309
2488
  }
2310
2489
  return { kind: "unescaped", name: template.slice(open + 3, close2).trim(), end: close2 + 3 };
2311
2490
  }
2312
2491
  const close = template.indexOf("}}", open + 2);
2313
2492
  if (close === -1) {
2314
- throw new Error("Unclosed tag");
2493
+ throw unclosedTagError(template, open, "}}");
2315
2494
  }
2316
2495
  const raw = template.slice(open + 2, close).trim();
2317
2496
  const sigil = raw[0];
@@ -2326,6 +2505,16 @@ function parseTag(template, open) {
2326
2505
  if (sigil === "=" && raw.endsWith("=")) return { kind: "delimiter", name, end };
2327
2506
  return { kind: "name", name: raw, end };
2328
2507
  }
2508
+ function unclosedTagError(template, open, expected) {
2509
+ const before = template.slice(0, open);
2510
+ const lineEnd = template.indexOf("\n", open);
2511
+ const opened = template.slice(open, lineEnd === -1 ? template.length : lineEnd).trimEnd();
2512
+ const tag = opened.length > MAX_TAG_EXCERPT_LENGTH ? `${opened.slice(0, MAX_TAG_EXCERPT_LENGTH)}...` : opened;
2513
+ return new TemplateParseError(`Unclosed tag "${tag}": expected "${expected}"`, {
2514
+ line: before.split("\n").length,
2515
+ column: open - (before.lastIndexOf("\n") + 1) + 1
2516
+ });
2517
+ }
2329
2518
  function getStandalone(template, tagStart, tagEnd, kind) {
2330
2519
  if (!["section", "inverted", "close", "comment", "partial", "delimiter"].includes(kind)) {
2331
2520
  return void 0;
@@ -2897,6 +3086,15 @@ var cursor = {
2897
3086
  var erase = {
2898
3087
  down: "\x1B[J"
2899
3088
  };
3089
+ function nonTtyPromptMessage(argv = process.argv) {
3090
+ const tokens = [];
3091
+ for (const arg of argv.slice(2)) {
3092
+ if (arg.startsWith("-")) break;
3093
+ tokens.push(arg);
3094
+ }
3095
+ const retry = [...tokens, "--yes"].join(" ");
3096
+ return `Interactive prompt requires a TTY. Re-run with \`${retry}\` to accept defaults non-interactively, or set POE_NO_PROMPT=1 in CI.`;
3097
+ }
2900
3098
  var Prompt = class extends EventEmitter {
2901
3099
  state = "initial";
2902
3100
  value;
@@ -2967,7 +3165,7 @@ var Prompt = class extends EventEmitter {
2967
3165
  });
2968
3166
  }
2969
3167
  promptNonTty() {
2970
- return Promise.reject(new Error("Interactive prompt requires a TTY. Set POE_NO_PROMPT=1 to accept defaults non-interactively."));
3168
+ return Promise.reject(new Error(nonTtyPromptMessage()));
2971
3169
  }
2972
3170
  readNonTtyLine() {
2973
3171
  return new Promise((resolve) => {
@@ -3491,6 +3689,9 @@ var UserError = class extends Error {
3491
3689
  this.name = "UserError";
3492
3690
  }
3493
3691
  };
3692
+ function isUserError(error3) {
3693
+ return error3 instanceof UserError || error3 instanceof Error && error3.name === "UserError";
3694
+ }
3494
3695
  var ToolcraftBugError = class extends Error {
3495
3696
  constructor(message2) {
3496
3697
  super(message2);
@@ -5132,6 +5333,9 @@ function compactUrl(value) {
5132
5333
  return value;
5133
5334
  }
5134
5335
  }
5336
+ function stackedList(value) {
5337
+ return value.map((entry) => displayScalar(entry)).join("\n") || "\u2014";
5338
+ }
5135
5339
  function displayRowValue(value) {
5136
5340
  return isUrl(value) ? compactUrl(value) : displayScalar(value);
5137
5341
  }
@@ -5157,7 +5361,7 @@ function renderObjectCard(result, primitives, title) {
5157
5361
  const scalarRows = directScalarRows(result);
5158
5362
  const nestedSections = directObjectSections(result);
5159
5363
  const arrayObjectSections = directArrayObjectSections(result);
5160
- const listRows = Object.entries(result).filter(([, value]) => Array.isArray(value) && !isNonEmptyArrayOfObjects(value)).map(([key, value]) => ({ label: humanizeKey(key), value: displayScalar(value) }));
5364
+ const listRows = Object.entries(result).filter(([, value]) => Array.isArray(value) && !isNonEmptyArrayOfObjects(value)).map(([key, value]) => ({ label: humanizeKey(key), value: stackedList(value) }));
5161
5365
  return renderDetailCard({
5162
5366
  theme: primitives.getTheme(),
5163
5367
  title,
@@ -5859,6 +6063,13 @@ function formatOptionFlags(field, globalLongOptionFlags) {
5859
6063
  }
5860
6064
  return [`-${field.shortFlag}`, field.optionFlag, ...field.longAliases].join(", ");
5861
6065
  }
6066
+ function formatMissingParameterMessage(field) {
6067
+ const message2 = `Missing required parameter "${field.displayPath}".`;
6068
+ if (field.schema.kind !== "enum") {
6069
+ return message2;
6070
+ }
6071
+ return `${message2} Expected one of: ${field.schema.values.map((value) => String(value)).join(", ")}.`;
6072
+ }
5862
6073
  function formatPositionalToken(field) {
5863
6074
  const optionalPositional = field.optional || field.hasDefault;
5864
6075
  if (field.variadicPosition === true) {
@@ -6145,6 +6356,7 @@ function resolveCLIControls(controls) {
6145
6356
  validateOutputFormats(outputFormats);
6146
6357
  return {
6147
6358
  debug: controls?.debug === true,
6359
+ help: controls?.help === "concise" ? "concise" : "extended",
6148
6360
  logLevel: controls?.logLevel === true,
6149
6361
  output: controls?.output === true || typeof controls?.output === "object",
6150
6362
  outputFormats,
@@ -6339,12 +6551,31 @@ function appendHelpMetadata(description, metadata) {
6339
6551
  return description;
6340
6552
  }
6341
6553
  if (description.length === 0) {
6342
- return `(${metadata.join(", ")})`;
6554
+ return metadata.map((entry) => `(${entry})`).join(" ");
6343
6555
  }
6344
- return `${description} (${metadata.join(", ")})`;
6556
+ return `${description} ${metadata.map((entry) => `(${entry})`).join(" ")}`;
6557
+ }
6558
+ function normalizeHelpEchoKey(value) {
6559
+ let normalized = "";
6560
+ for (const character of value.trim().toLowerCase()) {
6561
+ if (character !== " " && character !== " " && character !== "\n" && character !== "\r" && character !== "_" && character !== "." && character !== "-") {
6562
+ normalized += character;
6563
+ }
6564
+ }
6565
+ return normalized;
6566
+ }
6567
+ function isEchoHelpDescription(description, name) {
6568
+ if (description.length === 0) {
6569
+ return false;
6570
+ }
6571
+ return normalizeHelpEchoKey(description) === normalizeHelpEchoKey(name);
6572
+ }
6573
+ function suppressEchoHelpDescription(description, name) {
6574
+ return isEchoHelpDescription(description, name) ? "" : description;
6345
6575
  }
6346
6576
  function formatHelpFieldDescription(field) {
6347
- const description = field.description ?? field.displayPath;
6577
+ const rawDescription = field.description ?? field.displayPath;
6578
+ const description = suppressEchoHelpDescription(rawDescription, field.displayPath);
6348
6579
  const metadata = [];
6349
6580
  if (field.schema.kind === "enum" && field.schema.values.length <= 8) {
6350
6581
  const values = field.schema.values.map((value) => String(value)).join(", ");
@@ -6493,13 +6724,21 @@ function formatDynamicHelpMetadata(field) {
6493
6724
  }
6494
6725
  return metadata;
6495
6726
  }
6727
+ function createHelpOptionRow(flags, description) {
6728
+ return {
6729
+ flags,
6730
+ flagTokens: tokenizeHelpFlags(flags),
6731
+ description
6732
+ };
6733
+ }
6496
6734
  function collectDynamicObjectHelpRows(schema, casing, optionPrefix, displayPrefix, metadata) {
6497
6735
  const rows = [];
6498
6736
  for (const [key, rawChildSchema] of Object.entries(schema.shape)) {
6499
6737
  const childSchema = unwrapOptional2(rawChildSchema);
6500
6738
  const optionFlag = `${optionPrefix}.${formatSegment(key, casing)}`;
6501
6739
  const displayPath = `${displayPrefix}.${key}`;
6502
- const description = childSchema.description ?? displayPath;
6740
+ const rawDescription = childSchema.description ?? displayPath;
6741
+ const description = suppressEchoHelpDescription(rawDescription, displayPath);
6503
6742
  if (childSchema.kind === "object") {
6504
6743
  rows.push(
6505
6744
  ...collectDynamicObjectHelpRows(childSchema, casing, optionFlag, displayPath, metadata)
@@ -6507,24 +6746,26 @@ function collectDynamicObjectHelpRows(schema, casing, optionPrefix, displayPrefi
6507
6746
  continue;
6508
6747
  }
6509
6748
  if (childSchema.kind === "record") {
6510
- rows.push({
6511
- flags: `${optionFlag}.<key> <${describeDynamicFieldType({
6512
- ...{
6513
- id: displayPath,
6514
- path: [],
6515
- displayPath,
6516
- optionPath: [],
6517
- optionPathDisplay: `${displayPath}.<key>`,
6518
- optionFlag: `${optionFlag}.<key>`,
6519
- optional: false,
6520
- hasDefault: false,
6521
- defaultValue: void 0,
6522
- requiredWhenActive: false,
6523
- schema: childSchema
6524
- }
6525
- })}>`,
6526
- description: appendHelpMetadata(description, metadata)
6527
- });
6749
+ rows.push(
6750
+ createHelpOptionRow(
6751
+ `${optionFlag}.<key> <${describeDynamicFieldType({
6752
+ ...{
6753
+ id: displayPath,
6754
+ path: [],
6755
+ displayPath,
6756
+ optionPath: [],
6757
+ optionPathDisplay: `${displayPath}.<key>`,
6758
+ optionFlag: `${optionFlag}.<key>`,
6759
+ optional: false,
6760
+ hasDefault: false,
6761
+ defaultValue: void 0,
6762
+ requiredWhenActive: false,
6763
+ schema: childSchema
6764
+ }
6765
+ })}>`,
6766
+ appendHelpMetadata(description, metadata)
6767
+ )
6768
+ );
6528
6769
  continue;
6529
6770
  }
6530
6771
  if (childSchema.kind === "array" && unwrapOptional2(childSchema.item).kind === "object") {
@@ -6539,13 +6780,15 @@ function collectDynamicObjectHelpRows(schema, casing, optionPrefix, displayPrefi
6539
6780
  );
6540
6781
  continue;
6541
6782
  }
6542
- rows.push({
6543
- flags: childSchema.kind === "boolean" ? childSchema.default === true ? `--no-${optionFlag.slice(2)}` : optionFlag : `${optionFlag} <${describeHelpValueToken(childSchema, {
6544
- displayPath,
6545
- optionFlag
6546
- })}>`,
6547
- description: appendHelpMetadata(description, metadata)
6548
- });
6783
+ rows.push(
6784
+ createHelpOptionRow(
6785
+ childSchema.kind === "boolean" ? childSchema.default === true ? `--no-${optionFlag.slice(2)}` : optionFlag : `${optionFlag} <${describeHelpValueToken(childSchema, {
6786
+ displayPath,
6787
+ optionFlag
6788
+ })}>`,
6789
+ appendHelpMetadata(description, metadata)
6790
+ )
6791
+ );
6549
6792
  }
6550
6793
  return rows;
6551
6794
  }
@@ -6576,17 +6819,22 @@ function formatDynamicHelpFields(field, casing) {
6576
6819
  }
6577
6820
  }
6578
6821
  return [
6579
- {
6580
- flags: `${field.optionFlag} <${describeDynamicFieldType(field)}>`,
6581
- description: appendHelpMetadata(field.description ?? field.optionPathDisplay, metadata)
6582
- }
6822
+ createHelpOptionRow(
6823
+ `${field.optionFlag} <${describeDynamicFieldType(field)}>`,
6824
+ appendHelpMetadata(
6825
+ suppressEchoHelpDescription(
6826
+ field.description ?? field.optionPathDisplay,
6827
+ field.optionPathDisplay
6828
+ ),
6829
+ metadata
6830
+ )
6831
+ )
6583
6832
  ];
6584
6833
  }
6585
6834
  function formatSecretRows(secrets) {
6586
- return Object.values(secrets).map((secret) => ({
6587
- flags: secret.env,
6588
- description: formatSecretDescription(secret)
6589
- }));
6835
+ return Object.values(secrets).map(
6836
+ (secret) => createHelpOptionRow(secret.env, formatSecretDescription(secret))
6837
+ );
6590
6838
  }
6591
6839
  function formatSecretDescription(secret) {
6592
6840
  if (secret.description !== void 0 && secret.description.length > 0) {
@@ -6614,20 +6862,82 @@ function formatExampleRows(examples, breadcrumb, rootUsageName) {
6614
6862
  ${formatExampleCommand(breadcrumb, rootUsageName, example.params)}`
6615
6863
  );
6616
6864
  }
6617
- function wrapOptionalCommandParameterToken(token, optional) {
6618
- return optional ? `[${token}]` : token;
6865
+ var MAX_INLINE_OPTIONAL_PARAMETER_TOKENS = 8;
6866
+ var DEFAULT_HELP_TOTAL_WIDTH = 100;
6867
+ function tokenizeHelpFlags(flags) {
6868
+ const tokens = [];
6869
+ let index = 0;
6870
+ while (index < flags.length) {
6871
+ if (flags[index] === " ") {
6872
+ let end2 = index + 1;
6873
+ while (end2 < flags.length && flags[end2] === " ") {
6874
+ end2 += 1;
6875
+ }
6876
+ tokens.push({ text: flags.slice(index, end2), role: "literal" });
6877
+ index = end2;
6878
+ continue;
6879
+ }
6880
+ if (flags[index] === "[" || flags[index] === "]") {
6881
+ tokens.push({ text: flags[index], role: "dim" });
6882
+ index += 1;
6883
+ continue;
6884
+ }
6885
+ if (flags[index] === "<") {
6886
+ const close = flags.indexOf(">", index);
6887
+ if (close === -1) {
6888
+ tokens.push({ text: flags.slice(index), role: "literal" });
6889
+ break;
6890
+ }
6891
+ tokens.push({ text: flags.slice(index, close + 1), role: "argument" });
6892
+ index = close + 1;
6893
+ continue;
6894
+ }
6895
+ if (flags.startsWith("--", index) || flags[index] === "-" && flags[index + 1] !== void 0 && flags[index + 1] !== "-") {
6896
+ let end2 = index + 1;
6897
+ while (end2 < flags.length && flags[end2] !== " " && flags[end2] !== "[" && flags[end2] !== "]" && flags[end2] !== "<") {
6898
+ end2 += 1;
6899
+ }
6900
+ tokens.push({ text: flags.slice(index, end2), role: "option" });
6901
+ index = end2;
6902
+ continue;
6903
+ }
6904
+ let end = index + 1;
6905
+ while (end < flags.length && flags[end] !== " " && flags[end] !== "[" && flags[end] !== "]" && flags[end] !== "<") {
6906
+ end += 1;
6907
+ }
6908
+ const piece = flags.slice(index, end);
6909
+ tokens.push({
6910
+ text: piece,
6911
+ role: piece.includes("|") ? "literal" : piece.startsWith("+") ? "dim" : "literal"
6912
+ });
6913
+ index = end;
6914
+ }
6915
+ return tokens;
6916
+ }
6917
+ function wrapOptionalParameterTokens(tokens, optional) {
6918
+ if (!optional) {
6919
+ return tokens;
6920
+ }
6921
+ return [{ text: "[", role: "dim" }, ...tokens, { text: "]", role: "dim" }];
6922
+ }
6923
+ function createCommandParameterToken(text3, optional) {
6924
+ return {
6925
+ text: optional ? `[${text3}]` : text3,
6926
+ optional,
6927
+ tokens: wrapOptionalParameterTokens(tokenizeHelpFlags(text3), optional)
6928
+ };
6619
6929
  }
6620
6930
  function formatCommandDynamicParameterTokens(field, casing) {
6621
6931
  const optional = field.optional || field.hasDefault;
6622
6932
  return formatDynamicHelpFields(field, casing).map(
6623
- (row) => wrapOptionalCommandParameterToken(row.flags, optional)
6933
+ (row) => createCommandParameterToken(row.flags, optional)
6624
6934
  );
6625
6935
  }
6626
6936
  function formatCommandParameterTokens(command, casing, globalLongOptionFlags) {
6627
6937
  const collected = collectFields(command.params, casing, globalLongOptionFlags);
6628
6938
  const fields = assignPositionals(collected.fields, command.positional);
6629
6939
  return fields.filter((field) => field.global !== true).map(
6630
- (field) => wrapOptionalCommandParameterToken(
6940
+ (field) => createCommandParameterToken(
6631
6941
  formatCommandParameterFieldFlags(field, globalLongOptionFlags),
6632
6942
  field.positionalIndex === void 0 && (field.optional || field.hasDefault)
6633
6943
  )
@@ -6635,17 +6945,72 @@ function formatCommandParameterTokens(command, casing, globalLongOptionFlags) {
6635
6945
  collected.dynamicFields.flatMap((field) => formatCommandDynamicParameterTokens(field, casing))
6636
6946
  );
6637
6947
  }
6638
- function formatCommandRowName(node, casing, globalLongOptionFlags) {
6948
+ function collapseOptionalParameterTokens(parameterTokens, inlineWidthBudget = Number.POSITIVE_INFINITY) {
6949
+ const optionalCount = parameterTokens.filter((token) => token.optional).length;
6950
+ if (optionalCount === 0) {
6951
+ return parameterTokens;
6952
+ }
6953
+ const inlineWidth = parameterTokens.reduce((total, token) => total + token.text.length + 1, 0);
6954
+ if (optionalCount <= MAX_INLINE_OPTIONAL_PARAMETER_TOKENS && inlineWidth <= inlineWidthBudget) {
6955
+ return parameterTokens;
6956
+ }
6957
+ const required = parameterTokens.filter((token) => !token.optional);
6958
+ const collapsedText = `+${optionalCount} options`;
6959
+ return [
6960
+ ...required,
6961
+ {
6962
+ text: `[${collapsedText}]`,
6963
+ optional: true,
6964
+ tokens: [
6965
+ { text: "[", role: "dim" },
6966
+ { text: collapsedText, role: "dim" },
6967
+ { text: "]", role: "dim" }
6968
+ ]
6969
+ }
6970
+ ];
6971
+ }
6972
+ function formatCommandRowNameTokens(node, casing, globalLongOptionFlags) {
6639
6973
  const baseName = node.aliases.length === 0 ? node.name : `${node.name} (${node.aliases.join(", ")})`;
6640
- const parameterTokens = node.kind === "command" ? formatCommandParameterTokens(node, casing, globalLongOptionFlags) : [];
6641
- const name = parameterTokens.length === 0 ? baseName : `${baseName} ${parameterTokens.join(" ")}`;
6642
- return name;
6643
- }
6644
- function formatCommandRows(group, scope, casing, globalLongOptionFlags) {
6645
- return getHelpChildren(group, scope).map((child) => ({
6646
- name: formatCommandRowName(child, casing, globalLongOptionFlags),
6647
- description: child.description ?? ""
6648
- }));
6974
+ const nameTokens = [{ text: baseName, role: "command" }];
6975
+ const inlineWidthBudget = Math.max(
6976
+ 0,
6977
+ (process.stdout.columns ?? DEFAULT_HELP_TOTAL_WIDTH) - 2 - baseName.length
6978
+ );
6979
+ const parameterTokens = node.kind === "command" ? collapseOptionalParameterTokens(
6980
+ formatCommandParameterTokens(node, casing, globalLongOptionFlags),
6981
+ inlineWidthBudget
6982
+ ) : [];
6983
+ for (const token of parameterTokens) {
6984
+ nameTokens.push({ text: " ", role: "literal" }, ...token.tokens);
6985
+ }
6986
+ const name = parameterTokens.length === 0 ? baseName : `${baseName} ${parameterTokens.map((token) => token.text).join(" ")}`;
6987
+ return { name, nameTokens };
6988
+ }
6989
+ function formatCommandRows(group, scope, casing, globalLongOptionFlags, help) {
6990
+ const toRow = (child, depth) => {
6991
+ const { name, nameTokens } = formatCommandRowNameTokens(child, casing, globalLongOptionFlags);
6992
+ return {
6993
+ name,
6994
+ nameTokens,
6995
+ description: suppressEchoHelpDescription(child.description ?? "", child.name),
6996
+ kind: child.kind,
6997
+ depth
6998
+ };
6999
+ };
7000
+ if (help === "concise") {
7001
+ return getHelpChildren(group, scope).map((child) => toRow(child, 0));
7002
+ }
7003
+ const rows = [];
7004
+ const visit = (node, depth) => {
7005
+ for (const child of getHelpChildren(node, scope)) {
7006
+ rows.push(toRow(child, depth));
7007
+ if (child.kind === "group") {
7008
+ visit(child, depth + 1);
7009
+ }
7010
+ }
7011
+ };
7012
+ visit(group, 0);
7013
+ return rows;
6649
7014
  }
6650
7015
  function formatGlobalOptionsLine(ctx) {
6651
7016
  const flags = [];
@@ -6664,10 +7029,10 @@ function formatGlobalOptionsLine(ctx) {
6664
7029
  if (ctx.showVersion) {
6665
7030
  flags.push("--version");
6666
7031
  }
6667
- return flags.length > 0 ? `${text.section("Options:")} ${flags.join(" ")}` : "";
7032
+ return flags.length > 0 ? `${text.section("Global Options:")} ${flags.join(" ")}` : "";
6668
7033
  }
6669
7034
  function formatLeafGlobalOptionsLine(ctx) {
6670
- return ctx.controls.verbose ? `${text.section("Options:")} -v, --verbose` : "";
7035
+ return ctx.controls.verbose ? `${text.section("Global Options:")} -v, --verbose` : "";
6671
7036
  }
6672
7037
  function collectSchemaGlobalFieldRows(group, scope, casing, globalLongOptionFlags) {
6673
7038
  const seen = /* @__PURE__ */ new Map();
@@ -6685,10 +7050,13 @@ function collectSchemaGlobalFieldRows(group, scope, casing, globalLongOptionFlag
6685
7050
  if (seen.has(dedupeKey)) {
6686
7051
  continue;
6687
7052
  }
6688
- seen.set(dedupeKey, {
6689
- flags: formatHelpFieldFlags(field, globalLongOptionFlags),
6690
- description: formatHelpFieldDescription(field)
6691
- });
7053
+ seen.set(
7054
+ dedupeKey,
7055
+ createHelpOptionRow(
7056
+ formatHelpFieldFlags(field, globalLongOptionFlags),
7057
+ formatHelpFieldDescription(field)
7058
+ )
7059
+ );
6692
7060
  }
6693
7061
  return;
6694
7062
  }
@@ -6708,6 +7076,18 @@ function formatHelpCommandList(rows) {
6708
7076
  function formatHelpOptionList(rows) {
6709
7077
  return process.stdout.isTTY !== true ? help_formatter_plain_exports.formatOptionList(rows) : formatOptionList(rows);
6710
7078
  }
7079
+ function sortLeafHelpOptionFields(fields) {
7080
+ const required = [];
7081
+ const optional = [];
7082
+ for (const field of fields) {
7083
+ if (!field.optional && !field.hasDefault) {
7084
+ required.push(field);
7085
+ continue;
7086
+ }
7087
+ optional.push(field);
7088
+ }
7089
+ return [...required, ...optional];
7090
+ }
6711
7091
  function buildUsageLine(breadcrumb, rootUsageName, suffix) {
6712
7092
  const visibleBreadcrumb = breadcrumb.filter((segment) => segment.length > 0);
6713
7093
  const usageBreadcrumb = breadcrumb[0] === "" ? [rootUsageName, ...visibleBreadcrumb] : visibleBreadcrumb;
@@ -6717,15 +7097,37 @@ function buildUsageLine(breadcrumb, rootUsageName, suffix) {
6717
7097
  }
6718
7098
  function formatGroupUsageSuffix(group, scope, casing, globalLongOptionFlags) {
6719
7099
  if (group.default !== void 0 && group.default.hidden === true && group.default.scope.includes(scope)) {
6720
- const parameterTokens = formatCommandParameterTokens(
6721
- group.default,
6722
- casing,
6723
- globalLongOptionFlags
7100
+ const parameterTokens = collapseOptionalParameterTokens(
7101
+ formatCommandParameterTokens(group.default, casing, globalLongOptionFlags)
6724
7102
  );
6725
- return ["[command]", "[OPTIONS]", ...parameterTokens].join(" ");
7103
+ return ["[command]", "[OPTIONS]", ...parameterTokens.map((token) => token.text)].join(" ");
6726
7104
  }
6727
7105
  return "[command] [OPTIONS]";
6728
7106
  }
7107
+ function formatHelpDrillDownFooter(rootUsageName) {
7108
+ return text.muted(`Run ${rootUsageName} <command> --help for full options.`);
7109
+ }
7110
+ function formatStyledUsageLine(usageLine) {
7111
+ const parts = usageLine.split(" ").filter((part) => part.length > 0);
7112
+ if (parts.length === 0) {
7113
+ return text.usageCommand(usageLine);
7114
+ }
7115
+ const commandEnd = parts.findIndex(
7116
+ (part) => part.startsWith("-") || part.startsWith("[") || part.startsWith("<")
7117
+ );
7118
+ const commandParts = commandEnd === -1 ? parts : parts.slice(0, commandEnd);
7119
+ const argParts = commandEnd === -1 ? [] : parts.slice(commandEnd);
7120
+ const command = commandParts.join(" ");
7121
+ if (argParts.length === 0) {
7122
+ return text.usageCommand(command);
7123
+ }
7124
+ return `${text.usageCommand(command)} ${renderHelpTokens(
7125
+ argParts.flatMap((part, index) => [
7126
+ ...index === 0 ? [] : [{ text: " ", role: "literal" }],
7127
+ ...tokenizeHelpFlags(part)
7128
+ ])
7129
+ )}`;
7130
+ }
6729
7131
  function renderGroupHelp(group, breadcrumb, scope, casing, globalOptions, rootUsageName, isRoot) {
6730
7132
  const sections = [];
6731
7133
  const globalLongOptionFlags = getGlobalLongOptionFlags(
@@ -6733,9 +7135,15 @@ function renderGroupHelp(group, breadcrumb, scope, casing, globalOptions, rootUs
6733
7135
  globalOptions.showVersion,
6734
7136
  globalOptions.controls
6735
7137
  );
6736
- const commandRows = formatCommandRows(group, scope, casing, globalLongOptionFlags);
7138
+ const commandRows = formatCommandRows(
7139
+ group,
7140
+ scope,
7141
+ casing,
7142
+ globalLongOptionFlags,
7143
+ globalOptions.controls.help
7144
+ );
6737
7145
  if (commandRows.length > 0) {
6738
- sections.push(`${text.sectionHeader("Commands")}
7146
+ sections.push(`${text.section("Commands:")}
6739
7147
  ${formatHelpCommandList(commandRows)}`);
6740
7148
  }
6741
7149
  if (isRoot) {
@@ -6748,7 +7156,7 @@ ${formatHelpCommandList(commandRows)}`);
6748
7156
  const builtInLine = formatGlobalOptionsLine(globalOptions);
6749
7157
  if (schemaGlobalRows.length > 0) {
6750
7158
  sections.push(
6751
- `${text.sectionHeader("Options")}
7159
+ `${text.section("Options:")}
6752
7160
  ${formatHelpOptionList(schemaGlobalRows)}
6753
7161
  ${builtInLine}`
6754
7162
  );
@@ -6756,6 +7164,9 @@ ${builtInLine}`
6756
7164
  sections.push(builtInLine);
6757
7165
  }
6758
7166
  }
7167
+ if (commandRows.length > 0) {
7168
+ sections.push(formatHelpDrillDownFooter(rootUsageName));
7169
+ }
6759
7170
  return renderHelpDocument({
6760
7171
  breadcrumb,
6761
7172
  rootUsageName,
@@ -6778,12 +7189,21 @@ function renderLeafHelp(command, breadcrumb, casing, globalOptions, rootUsageNam
6778
7189
  );
6779
7190
  const collected = collectFields(command.params, casing, globalLongOptionFlags);
6780
7191
  const fields = assignPositionals(collected.fields, command.positional);
6781
- const optionRows = fields.filter((field) => field.global !== true).map((field) => ({
6782
- flags: formatHelpFieldFlags(field, globalLongOptionFlags),
6783
- description: formatHelpFieldDescription(field)
6784
- })).concat(collected.dynamicFields.flatMap((field) => formatDynamicHelpFields(field, casing)));
7192
+ const localFields = fields.filter((field) => field.global !== true);
7193
+ const toHelpRow = (field) => createHelpOptionRow(
7194
+ formatHelpFieldFlags(field, globalLongOptionFlags),
7195
+ formatHelpFieldDescription(field)
7196
+ );
7197
+ const argumentRows = localFields.filter((field) => field.positionalIndex !== void 0).map(toHelpRow);
7198
+ const optionRows = sortLeafHelpOptionFields(
7199
+ localFields.filter((field) => field.positionalIndex === void 0)
7200
+ ).map(toHelpRow).concat(collected.dynamicFields.flatMap((field) => formatDynamicHelpFields(field, casing)));
7201
+ if (argumentRows.length > 0) {
7202
+ sections.push(`${text.section("Arguments:")}
7203
+ ${formatHelpOptionList(argumentRows)}`);
7204
+ }
6785
7205
  if (optionRows.length > 0) {
6786
- sections.push(`${text.sectionHeader("Options")}
7206
+ sections.push(`${text.section("Options:")}
6787
7207
  ${formatHelpOptionList(optionRows)}`);
6788
7208
  }
6789
7209
  const builtInLine = formatLeafGlobalOptionsLine(globalOptions);
@@ -6793,13 +7213,13 @@ ${formatHelpOptionList(optionRows)}`);
6793
7213
  const secretRows = formatSecretRows(command.secrets);
6794
7214
  if (secretRows.length > 0) {
6795
7215
  sections.push(
6796
- `${text.sectionHeader("Secrets (environment)")}
7216
+ `${text.section("Secrets (environment):")}
6797
7217
  ${formatHelpOptionList(secretRows)}`
6798
7218
  );
6799
7219
  }
6800
7220
  if (command.examples.length > 0) {
6801
7221
  sections.push(
6802
- `${text.sectionHeader("Examples")}
7222
+ `${text.section("Examples:")}
6803
7223
  ${formatExampleRows(command.examples, breadcrumb, rootUsageName).join("\n")}`
6804
7224
  );
6805
7225
  }
@@ -6822,7 +7242,13 @@ function renderJsonHelp(target, root, casing, globalOptions, rootUsageName) {
6822
7242
  );
6823
7243
  const node = target.node;
6824
7244
  if (node.kind === "group") {
6825
- const commandRows = formatCommandRows(node, "cli", casing, globalLongOptionFlags);
7245
+ const commandRows = formatCommandRows(
7246
+ node,
7247
+ "cli",
7248
+ casing,
7249
+ globalLongOptionFlags,
7250
+ globalOptions.controls.help
7251
+ );
6826
7252
  const isRoot = node === root;
6827
7253
  return `${JSON.stringify(
6828
7254
  {
@@ -6836,7 +7262,12 @@ function renderJsonHelp(target, root, casing, globalOptions, rootUsageName) {
6836
7262
  formatGroupUsageSuffix(node, "cli", casing, globalLongOptionFlags)
6837
7263
  ),
6838
7264
  ...node.description === void 0 ? {} : { description: node.description },
6839
- commands: commandRows.map((row) => ({ name: row.name, description: row.description })),
7265
+ commands: commandRows.map((row) => ({
7266
+ name: row.name,
7267
+ description: row.description,
7268
+ kind: row.kind,
7269
+ depth: row.depth
7270
+ })),
6840
7271
  options: isRoot ? collectSchemaGlobalFieldRows(node, "cli", casing, globalLongOptionFlags).map((row) => ({
6841
7272
  name: row.flags.split(/[ ,]+/)[0]?.replace(/^--/, "") ?? row.flags,
6842
7273
  flags: row.flags.split(", "),
@@ -6910,7 +7341,7 @@ function renderHelpDocument(input) {
6910
7341
  if (remainingDescription.length > 0) {
6911
7342
  lines.push(remainingDescription, "");
6912
7343
  }
6913
- lines.push(`Usage: ${text.usageCommand(input.usageLine)}`, "");
7344
+ lines.push(`Usage: ${formatStyledUsageLine(input.usageLine)}`, "");
6914
7345
  if (input.requiresAuth) {
6915
7346
  lines.push("Requires: authentication");
6916
7347
  }
@@ -6994,7 +7425,9 @@ function createNodeCommand(node, casing, globalLongOptionFlags, execute, presets
6994
7425
  }
6995
7426
  for (const field of fields) {
6996
7427
  if (field.positionalIndex !== void 0) {
6997
- command.argument(formatPositionalToken(field));
7428
+ command.argument(
7429
+ field.variadicPosition === true ? `[${field.displayPath}...]` : `[${field.displayPath}]`
7430
+ );
6998
7431
  continue;
6999
7432
  }
7000
7433
  for (const option of createOption(field, globalLongOptionFlags)) {
@@ -7829,11 +8262,11 @@ function writeRichHeader(title) {
7829
8262
  function isHumanInLoopPending(result) {
7830
8263
  return typeof result === "object" && result !== null && result.status === "pending-approval" && typeof result.approvalId === "string" && typeof result.message === "string" && typeof result.enqueuedAt === "string";
7831
8264
  }
7832
- function renderHumanInLoopPending(pending) {
8265
+ function renderHumanInLoopPending(pending, rootUsageName) {
7833
8266
  process.stdout.write(
7834
8267
  `\u2713 Queued for human approval (id: ${pending.approvalId})
7835
8268
  Message: ${pending.message}
7836
- Track: toolcraft approvals show ${pending.approvalId}
8269
+ Track: ${rootUsageName} approvals show --approval-id ${pending.approvalId}
7837
8270
  `
7838
8271
  );
7839
8272
  }
@@ -7937,7 +8370,7 @@ function parseOptionFieldValue(field, value, errors) {
7937
8370
  }
7938
8371
  return { ok: true, value: parsedValue };
7939
8372
  } catch (error3) {
7940
- if (error3 instanceof UserError || error3 instanceof InvalidArgumentError) {
8373
+ if (isUserError(error3) || error3 instanceof InvalidArgumentError) {
7941
8374
  errors.push({
7942
8375
  path: field.displayPath,
7943
8376
  message: error3.message
@@ -8519,7 +8952,7 @@ async function resolveParams(fields, dynamicFields, variants, positionalValues,
8519
8952
  }
8520
8953
  errors.push({
8521
8954
  path: field.displayPath,
8522
- message: `Missing required parameter "${field.displayPath}".`
8955
+ message: formatMissingParameterMessage(field)
8523
8956
  });
8524
8957
  continue;
8525
8958
  }
@@ -8570,7 +9003,7 @@ function getResolvedFlags(command) {
8570
9003
  const flags = command.optsWithGlobals();
8571
9004
  return flags;
8572
9005
  }
8573
- async function executeCommand(state, services, requirementOptions, runtimeFetch, humanInLoop, runtimeEnv, runtimeFs, outputEmitter, outputFormats, promptStreams, diagnosticsOptions, onErrorReportContext) {
9006
+ async function executeCommand(state, rootUsageName, services, requirementOptions, runtimeFetch, humanInLoop, runtimeEnv, runtimeFs, outputEmitter, outputFormats, promptStreams, diagnosticsOptions, onErrorReportContext) {
8574
9007
  const logger2 = createLogger(outputEmitter);
8575
9008
  const optionValues = state.actionCommand.optsWithGlobals();
8576
9009
  const resolvedFlags = optionValues;
@@ -8726,7 +9159,7 @@ async function executeCommand(state, services, requirementOptions, runtimeFetch,
8726
9159
  writeRichHeader(`${state.command.name} (fixture)`);
8727
9160
  }
8728
9161
  if (isHumanInLoopPending(result)) {
8729
- renderHumanInLoopPending(result);
9162
+ renderHumanInLoopPending(result, rootUsageName);
8730
9163
  return;
8731
9164
  }
8732
9165
  const renderStatus = renderCLIResult(
@@ -8969,7 +9402,7 @@ function renderHttpError(error3, options) {
8969
9402
  async function handleRunError(error3, options) {
8970
9403
  const logger2 = createLogger(options.outputEmitter);
8971
9404
  await withOutputFormat2(options.output, async () => {
8972
- if (error3 instanceof UserError) {
9405
+ if (isUserError(error3)) {
8973
9406
  renderCliErrorPattern(
8974
9407
  options.userErrorPattern === "definition" ? {
8975
9408
  kind: "definition",
@@ -9285,11 +9718,9 @@ function getDefaultCommanderCommandName(command) {
9285
9718
  function configureCommanderSuggestionOutput(command) {
9286
9719
  command.exitOverride();
9287
9720
  command.configureOutput({
9288
- outputError: (message2, write2) => {
9289
- if (message2.includes("unknown command") || message2.includes("unknown option")) {
9290
- return;
9291
- }
9292
- write2(message2);
9721
+ // Every Commander error throws through exitOverride and is rendered once by handleRunError
9722
+ // in the design-system error pattern; writing it here as well double-reports one mistake.
9723
+ outputError: () => {
9293
9724
  }
9294
9725
  });
9295
9726
  command.commands.forEach((child) => configureCommanderSuggestionOutput(child));
@@ -9362,6 +9793,7 @@ async function runCLI(roots, options = {}) {
9362
9793
  resolvedCommandPath = formatCliCommandPath(state.commandPath);
9363
9794
  await executeCommand(
9364
9795
  state,
9796
+ rootUsageName,
9365
9797
  servicesWithBuiltIns,
9366
9798
  requirementOptions,
9367
9799
  runtimeFetch,
@@ -11032,7 +11464,7 @@ var claudeCodeAgent = {
11032
11464
  id: "claude-code",
11033
11465
  name: "claude-code",
11034
11466
  label: "Claude Code",
11035
- summary: "Configure Claude Code to route through Poe.",
11467
+ summary: "Anthropic's agentic coding tool for the terminal.",
11036
11468
  aliases: ["claude"],
11037
11469
  binaryName: "claude",
11038
11470
  apiShapes: ["anthropic-messages"],
@@ -11042,6 +11474,7 @@ var claudeCodeAgent = {
11042
11474
  }
11043
11475
  },
11044
11476
  configPath: "~/.claude.json",
11477
+ capabilities: ["spawn", "configure", "install", "test", "skill", "mcp"],
11045
11478
  branding: {
11046
11479
  colors: {
11047
11480
  dark: "#C15F3C",
@@ -11062,6 +11495,7 @@ var claudeDesktopAgent = {
11062
11495
  linux: "~/.config/Claude/claude_desktop_config.json",
11063
11496
  win32: "~/AppData/Roaming/Claude/claude_desktop_config.json"
11064
11497
  },
11498
+ capabilities: ["mcp"],
11065
11499
  branding: {
11066
11500
  colors: {
11067
11501
  dark: "#D97757",
@@ -11075,7 +11509,7 @@ var codexAgent = {
11075
11509
  id: "codex",
11076
11510
  name: "codex",
11077
11511
  label: "Codex",
11078
- summary: "Configure Codex to use Poe as the model provider.",
11512
+ summary: "OpenAI's coding agent for the terminal.",
11079
11513
  binaryName: "codex",
11080
11514
  apiShapes: ["openai-responses"],
11081
11515
  otelCapture: {
@@ -11089,6 +11523,7 @@ var codexAgent = {
11089
11523
  ]
11090
11524
  },
11091
11525
  configPath: "~/.codex/config.toml",
11526
+ capabilities: ["spawn", "configure", "install", "test", "skill", "mcp"],
11092
11527
  branding: {
11093
11528
  colors: {
11094
11529
  dark: "#D5D9DF",
@@ -11106,6 +11541,7 @@ var cursorAgent = {
11106
11541
  summary: "Cursor's CLI coding agent.",
11107
11542
  binaryName: "cursor-agent",
11108
11543
  configPath: "~/.cursor/mcp.json",
11544
+ capabilities: ["spawn", "configure", "install", "test", "skill", "mcp"],
11109
11545
  branding: {
11110
11546
  colors: {
11111
11547
  dark: "#FFFFFF",
@@ -11120,10 +11556,11 @@ var geminiCliAgent = {
11120
11556
  name: "gemini-cli",
11121
11557
  aliases: ["gemini"],
11122
11558
  label: "Gemini CLI",
11123
- summary: "Configure Google's Gemini CLI to use a compatible Google generations API.",
11559
+ summary: "Google's open-source AI agent for the terminal.",
11124
11560
  binaryName: "gemini",
11125
11561
  configPath: "~/.gemini/settings.json",
11126
11562
  apiShapes: ["google-generations"],
11563
+ capabilities: ["spawn", "configure", "install", "test", "skill"],
11127
11564
  branding: {
11128
11565
  colors: {
11129
11566
  dark: "#8AB4F8",
@@ -11137,7 +11574,7 @@ var openCodeAgent = {
11137
11574
  id: "opencode",
11138
11575
  name: "opencode",
11139
11576
  label: "OpenCode CLI",
11140
- summary: "Configure OpenCode CLI to use the Poe API.",
11577
+ summary: "Open-source AI coding agent for the terminal.",
11141
11578
  binaryName: "opencode",
11142
11579
  apiShapes: ["openai-chat-completions"],
11143
11580
  otelCapture: {
@@ -11146,6 +11583,7 @@ var openCodeAgent = {
11146
11583
  }
11147
11584
  },
11148
11585
  configPath: "~/.config/opencode/opencode.json",
11586
+ capabilities: ["spawn", "configure", "install", "test", "skill", "mcp"],
11149
11587
  branding: {
11150
11588
  colors: {
11151
11589
  dark: "#4A4F55",
@@ -11159,11 +11597,12 @@ var kimiAgent = {
11159
11597
  id: "kimi",
11160
11598
  name: "kimi",
11161
11599
  label: "Kimi",
11162
- summary: "Configure Kimi CLI to use Poe API",
11600
+ summary: "Moonshot AI's coding agent for the terminal.",
11163
11601
  aliases: ["kimi-cli"],
11164
11602
  binaryName: "kimi",
11165
11603
  apiShapes: ["openai-chat-completions"],
11166
11604
  configPath: "~/.kimi/mcp.json",
11605
+ capabilities: ["spawn", "configure", "install", "test", "mcp"],
11167
11606
  branding: {
11168
11607
  colors: {
11169
11608
  dark: "#7B68EE",
@@ -11182,6 +11621,7 @@ var gooseAgent = {
11182
11621
  apiShapes: ["openai-chat-completions"],
11183
11622
  otelCapture: {},
11184
11623
  configPath: "~/.config/goose/config.yaml",
11624
+ capabilities: ["spawn", "configure", "install", "test", "skill", "mcp"],
11185
11625
  branding: {
11186
11626
  colors: {
11187
11627
  dark: "#FF6B35",
@@ -11190,6 +11630,23 @@ var gooseAgent = {
11190
11630
  }
11191
11631
  };
11192
11632
 
11633
+ // ../agent-defs/src/agents/pi.ts
11634
+ var piAgent = {
11635
+ id: "pi",
11636
+ name: "pi",
11637
+ aliases: ["pi-agent"],
11638
+ label: "Pi",
11639
+ summary: "Minimal AI coding agent for the terminal.",
11640
+ binaryName: "pi",
11641
+ capabilities: ["spawn"],
11642
+ branding: {
11643
+ colors: {
11644
+ dark: "#F2F2F2",
11645
+ light: "#242424"
11646
+ }
11647
+ }
11648
+ };
11649
+
11193
11650
  // ../agent-defs/src/agents/poe-agent.ts
11194
11651
  var poeAgentAgent = {
11195
11652
  id: "poe-agent",
@@ -11198,6 +11655,7 @@ var poeAgentAgent = {
11198
11655
  summary: "Run one-shot prompts with the built-in Poe agent runtime.",
11199
11656
  apiShapes: ["openai-responses", "openai-chat-completions"],
11200
11657
  configPath: "~/.poe-code/config.json",
11658
+ capabilities: ["configure"],
11201
11659
  branding: {
11202
11660
  colors: {
11203
11661
  dark: "#A465F7",
@@ -11214,6 +11672,9 @@ function freezeAgent(agent) {
11214
11672
  if (agent.apiShapes !== void 0) {
11215
11673
  Object.freeze(agent.apiShapes);
11216
11674
  }
11675
+ if (agent.capabilities !== void 0) {
11676
+ Object.freeze(agent.capabilities);
11677
+ }
11217
11678
  if (agent.otelCapture?.env !== void 0) {
11218
11679
  Object.freeze(agent.otelCapture.env);
11219
11680
  }
@@ -11233,6 +11694,7 @@ var allAgents = Object.freeze([
11233
11694
  freezeAgent(openCodeAgent),
11234
11695
  freezeAgent(kimiAgent),
11235
11696
  freezeAgent(gooseAgent),
11697
+ freezeAgent(piAgent),
11236
11698
  freezeAgent(poeAgentAgent)
11237
11699
  ]);
11238
11700
  var lookup2 = /* @__PURE__ */ new Map();
@@ -11276,7 +11738,8 @@ var agentSkillConfigs = {
11276
11738
  },
11277
11739
  goose: {
11278
11740
  globalSkillDir: "~/.agents/skills",
11279
- localSkillDir: ".agents/skills"
11741
+ localSkillDir: ".agents/skills",
11742
+ dirNote: "Goose discovers skills from the shared .agents/skills convention, not a goose-specific directory."
11280
11743
  }
11281
11744
  };
11282
11745
  var supportedAgents = Object.freeze(Object.keys(agentSkillConfigs));
@@ -12650,6 +13113,16 @@ async function executeMutation(mutation, context, options) {
12650
13113
  }
12651
13114
  }
12652
13115
 
13116
+ // ../user-error/src/index.ts
13117
+ var UserError2 = class extends Error {
13118
+ hint;
13119
+ constructor(message2, options) {
13120
+ super(message2, options);
13121
+ this.name = "UserError";
13122
+ this.hint = options?.hint;
13123
+ }
13124
+ };
13125
+
12653
13126
  // ../agent-skill-config/src/error-codes.ts
12654
13127
  function hasOwnErrorCode4(error3, code) {
12655
13128
  return error3 instanceof Error && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === code;
@@ -12701,8 +13174,11 @@ async function installSkill(agentId, skill, options) {
12701
13174
  const skillFilePath = `${skillFolderPath}/SKILL.md`;
12702
13175
  const displayPath = `${scope === "global" ? config2.globalSkillDir : config2.localSkillDir}/${skill.name}/SKILL.md`;
12703
13176
  const absoluteSkillPath = `${scope === "global" ? options.homeDir : options.cwd}/${skillFilePath.slice(2)}`;
12704
- if (await pathExists2(options.fs, absoluteSkillPath)) {
12705
- throw new Error(`Skill already exists: ${displayPath}`);
13177
+ if (!options.force && await pathExists2(options.fs, absoluteSkillPath)) {
13178
+ throw new UserError2(
13179
+ `Skill already exists: ${displayPath}
13180
+ Re-run with --force to overwrite it, or remove it first.`
13181
+ );
12706
13182
  }
12707
13183
  await runMutations(
12708
13184
  [
@@ -14780,13 +15256,78 @@ function sleep2(ms) {
14780
15256
  // src/cli.ts
14781
15257
  configureTheme({ brand: "green", label: "Terminal Pilot" });
14782
15258
  function getBundledPackageVersion() {
14783
- return true ? "0.0.47" : void 0;
14784
- }
15259
+ return true ? "0.0.49" : void 0;
15260
+ }
15261
+ var pilotOptionsWithValues = /* @__PURE__ */ new Set([
15262
+ "--session",
15263
+ "-s",
15264
+ "--cwd",
15265
+ "--cols",
15266
+ "--rows",
15267
+ "--timeout",
15268
+ "-t",
15269
+ "--last",
15270
+ "-n",
15271
+ "--output",
15272
+ "-o",
15273
+ "--scope",
15274
+ "--padding",
15275
+ "-p",
15276
+ "--log-level",
15277
+ "--preset",
15278
+ "--signal"
15279
+ ]);
14785
15280
  function normalizeArgv(argv) {
14786
- if (argv.includes("--json") && !argv.some((argument) => argument === "--output" || argument.startsWith("--output="))) {
14787
- return argv.flatMap((argument) => argument === "--json" ? ["--output", "json"] : [argument]);
15281
+ if (!argv.includes("--json")) {
15282
+ return argv;
15283
+ }
15284
+ if (argv.some((argument) => argument === "--output" || argument.startsWith("--output="))) {
15285
+ return argv;
15286
+ }
15287
+ const normalized = [];
15288
+ let index = 0;
15289
+ let bareTokenCount = 0;
15290
+ let expectOptionValue = false;
15291
+ while (index < argv.length) {
15292
+ const token = argv[index];
15293
+ if (index < 2) {
15294
+ normalized.push(token);
15295
+ index += 1;
15296
+ continue;
15297
+ }
15298
+ if (token === "--") {
15299
+ normalized.push(token, ...argv.slice(index + 1));
15300
+ break;
15301
+ }
15302
+ if (expectOptionValue) {
15303
+ normalized.push(token);
15304
+ expectOptionValue = false;
15305
+ index += 1;
15306
+ continue;
15307
+ }
15308
+ if (token === "--json") {
15309
+ normalized.push("--output", "json");
15310
+ index += 1;
15311
+ continue;
15312
+ }
15313
+ if (token.startsWith("-") && token !== "-") {
15314
+ normalized.push(token);
15315
+ const optionName = token.includes("=") ? token.slice(0, token.indexOf("=")) : token;
15316
+ if (!token.includes("=") && (pilotOptionsWithValues.has(optionName) || optionName === "--debug" && argv[index + 1] !== void 0 && !argv[index + 1].startsWith("-"))) {
15317
+ expectOptionValue = true;
15318
+ }
15319
+ index += 1;
15320
+ continue;
15321
+ }
15322
+ bareTokenCount += 1;
15323
+ if (bareTokenCount >= 2) {
15324
+ normalized.push(...argv.slice(index));
15325
+ break;
15326
+ }
15327
+ normalized.push(token);
15328
+ index += 1;
14788
15329
  }
14789
- return argv;
15330
+ return normalized;
14790
15331
  }
14791
15332
  async function main(argv = process.argv, options = {}) {
14792
15333
  if (isTerminalPilotDaemonArgv(argv)) {