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
package/dist/cli.js CHANGED
@@ -1567,26 +1567,68 @@ function splitWords(value) {
1567
1567
  }
1568
1568
  return words;
1569
1569
  }
1570
- function wrapWords(value, width) {
1571
- const words = splitWords(value);
1570
+ function leadingWhitespaceWidth(value) {
1571
+ let index = 0;
1572
+ while (index < value.length && isWhitespace(value[index])) {
1573
+ index += 1;
1574
+ }
1575
+ return { prefix: value.slice(0, index), rest: value.slice(index) };
1576
+ }
1577
+ function takeVisiblePrefix(value, width) {
1578
+ let visible = 0;
1579
+ let index = 0;
1580
+ while (index < value.length) {
1581
+ const controlEnd = readControlSequence(value, index);
1582
+ if (controlEnd !== void 0) {
1583
+ index = controlEnd;
1584
+ continue;
1585
+ }
1586
+ const segment = graphemeSegmenter.segment(value.slice(index))[Symbol.iterator]().next().value;
1587
+ const cluster = segment?.segment ?? value[index] ?? "";
1588
+ const nextWidth = clusterWidth(cluster);
1589
+ if (visible > 0 && visible + nextWidth > width) {
1590
+ break;
1591
+ }
1592
+ visible += nextWidth;
1593
+ index += cluster.length || 1;
1594
+ }
1595
+ return { prefix: value.slice(0, index), rest: value.slice(index) };
1596
+ }
1597
+ function wrapWords(value, width, continuationWidth = width) {
1598
+ const { prefix, rest } = leadingWhitespaceWidth(value);
1599
+ const prefixWidth = visibleWidth(prefix);
1600
+ const firstContentWidth = Math.max(1, width - prefixWidth);
1601
+ const words = splitWords(rest);
1572
1602
  if (words.length === 0) {
1573
- return [""];
1603
+ return [prefix];
1574
1604
  }
1575
1605
  const lines = [];
1576
1606
  let line = "";
1607
+ let isFirstLine = true;
1577
1608
  for (const word of words) {
1578
- if (!line) {
1579
- line = word;
1580
- continue;
1581
- }
1582
- if (visibleWidth(line) + 1 + visibleWidth(word) <= width) {
1609
+ const limit = isFirstLine ? firstContentWidth : continuationWidth;
1610
+ if (line && visibleWidth(line) + 1 + visibleWidth(word) <= limit) {
1583
1611
  line += ` ${word}`;
1584
1612
  continue;
1585
1613
  }
1586
- lines.push(line);
1587
- line = word;
1614
+ if (line) {
1615
+ lines.push(isFirstLine ? `${prefix}${line}` : line);
1616
+ isFirstLine = false;
1617
+ line = "";
1618
+ }
1619
+ let remaining = word;
1620
+ while (visibleWidth(remaining) > (isFirstLine ? firstContentWidth : continuationWidth)) {
1621
+ const chunk = takeVisiblePrefix(
1622
+ remaining,
1623
+ isFirstLine ? firstContentWidth : continuationWidth
1624
+ );
1625
+ lines.push(isFirstLine ? `${prefix}${chunk.prefix}` : chunk.prefix);
1626
+ isFirstLine = false;
1627
+ remaining = chunk.rest;
1628
+ }
1629
+ line = remaining;
1588
1630
  }
1589
- lines.push(line);
1631
+ lines.push(isFirstLine ? `${prefix}${line}` : line);
1590
1632
  return lines;
1591
1633
  }
1592
1634
  function validateLayoutValue(value, name) {
@@ -1614,37 +1656,90 @@ function formatColumns(opts) {
1614
1656
  validateLayoutValue(indent, "indent");
1615
1657
  const maxLeftContentWidth = Math.max(...rows.map((row) => visibleWidth(row.left)));
1616
1658
  const leftWidth = clamp(maxLeftContentWidth + gap, minLeftWidth, maxLeftWidth);
1617
- const rightWidth = Math.max(20, totalWidth - leftWidth - indent);
1659
+ const rightWidth = Math.max(1, totalWidth - leftWidth - indent);
1660
+ const leftWrapWidth = Math.max(1, totalWidth - indent);
1618
1661
  const firstIndent = " ".repeat(indent);
1619
1662
  const continuationIndent = " ".repeat(indent + leftWidth);
1620
1663
  return rows.flatMap((row) => {
1664
+ const leftLeading = leadingWhitespaceWidth(row.left).prefix;
1665
+ const leftHangIndent = " ".repeat(indent + visibleWidth(leftLeading) + 2);
1666
+ const leftLines = wrapWords(
1667
+ row.left,
1668
+ leftWrapWidth,
1669
+ Math.max(1, totalWidth - visibleWidth(leftHangIndent))
1670
+ );
1621
1671
  if (row.right.length === 0) {
1622
- return [`${firstIndent}${row.left}`];
1672
+ return leftLines.map(
1673
+ (line, index) => index === 0 ? `${firstIndent}${line}` : `${leftHangIndent}${line}`
1674
+ );
1623
1675
  }
1624
1676
  const rightLines = wrapWords(row.right, rightWidth);
1625
- if (visibleWidth(row.left) >= leftWidth) {
1626
- return [
1627
- `${firstIndent}${row.left}`,
1628
- ...rightLines.map((line) => `${continuationIndent}${line}`)
1629
- ];
1630
- }
1631
- const firstLine = `${firstIndent}${padEndVisible(row.left, leftWidth)}${rightLines[0]}`;
1632
- const continuationLines = rightLines.slice(1).map((line) => `${continuationIndent}${line}`);
1633
- return [firstLine, ...continuationLines];
1677
+ const leftFitsInColumn = visibleWidth(row.left) < leftWidth;
1678
+ if (leftFitsInColumn && leftLines.length === 1) {
1679
+ const firstLine = `${firstIndent}${padEndVisible(leftLines[0] ?? "", leftWidth)}${rightLines[0]}`;
1680
+ const continuationLines = rightLines.slice(1).map((line) => `${continuationIndent}${line}`);
1681
+ return [firstLine, ...continuationLines];
1682
+ }
1683
+ const renderedLeft = leftLines.map(
1684
+ (line, index) => index === 0 ? `${firstIndent}${line}` : `${leftHangIndent}${line}`
1685
+ );
1686
+ const renderedRight = rightLines.map((line) => `${continuationIndent}${line}`);
1687
+ return [...renderedLeft, ...renderedRight];
1634
1688
  }).join("\n");
1635
1689
  }
1690
+ function styleHelpToken(token) {
1691
+ switch (token.role) {
1692
+ case "command":
1693
+ return text.command(token.text);
1694
+ case "argument":
1695
+ return styleArgumentToken(token.text);
1696
+ case "option":
1697
+ return text.option(token.text);
1698
+ case "dim":
1699
+ return styleDim(token.text);
1700
+ case "literal":
1701
+ return token.text;
1702
+ }
1703
+ }
1704
+ function styleArgumentToken(content) {
1705
+ const format = resolveOutputFormat();
1706
+ if (format === "markdown" && content.startsWith("<") && content.endsWith(">")) {
1707
+ return text.argument(content.slice(1, -1));
1708
+ }
1709
+ if (format === "json") {
1710
+ return content;
1711
+ }
1712
+ return text.argument(content);
1713
+ }
1714
+ function styleDim(content) {
1715
+ const format = resolveOutputFormat();
1716
+ if (format === "json" || format === "markdown") {
1717
+ return content;
1718
+ }
1719
+ return typography.dim(content);
1720
+ }
1721
+ function joinHelpTokens(tokens) {
1722
+ return tokens.map((token) => token.text).join("");
1723
+ }
1724
+ function renderHelpTokens(tokens) {
1725
+ return tokens.map((token) => styleHelpToken(token)).join("");
1726
+ }
1636
1727
  function formatCommandList(commands) {
1637
1728
  return formatColumns({
1638
- rows: commands.map((cmd) => ({
1639
- left: text.command(cmd.name),
1640
- right: cmd.description
1641
- }))
1729
+ rows: commands.map((cmd) => {
1730
+ const depthPrefix = " ".repeat((cmd.depth ?? 0) * 2);
1731
+ const styledName = cmd.nameTokens !== void 0 && cmd.nameTokens.length > 0 ? renderHelpTokens(cmd.nameTokens) : text.command(cmd.name);
1732
+ return {
1733
+ left: `${depthPrefix}${styledName}`,
1734
+ right: cmd.description
1735
+ };
1736
+ })
1642
1737
  });
1643
1738
  }
1644
1739
  function formatOptionList(options) {
1645
1740
  return formatColumns({
1646
1741
  rows: options.map((opt) => ({
1647
- left: text.option(opt.flags),
1742
+ left: opt.flagTokens !== void 0 && opt.flagTokens.length > 0 ? renderHelpTokens(opt.flagTokens) : text.option(opt.flags),
1648
1743
  right: opt.description
1649
1744
  }))
1650
1745
  });
@@ -1714,26 +1809,47 @@ function splitWords2(value) {
1714
1809
  }
1715
1810
  return words;
1716
1811
  }
1717
- function wrapWords2(value, width) {
1718
- const words = splitWords2(value);
1812
+ function leadingWhitespace(value) {
1813
+ let index = 0;
1814
+ while (index < value.length && isWhitespace2(value[index])) {
1815
+ index += 1;
1816
+ }
1817
+ return { prefix: value.slice(0, index), rest: value.slice(index) };
1818
+ }
1819
+ function takePrefix(value, width) {
1820
+ return { prefix: value.slice(0, width), rest: value.slice(width) };
1821
+ }
1822
+ function wrapWords2(value, width, continuationWidth = width) {
1823
+ const { prefix, rest } = leadingWhitespace(value);
1824
+ const firstContentWidth = Math.max(1, width - prefix.length);
1825
+ const words = splitWords2(rest);
1719
1826
  if (words.length === 0) {
1720
- return [""];
1827
+ return [prefix];
1721
1828
  }
1722
1829
  const lines = [];
1723
1830
  let line = "";
1831
+ let isFirstLine = true;
1724
1832
  for (const word of words) {
1725
- if (!line) {
1726
- line = word;
1727
- continue;
1728
- }
1729
- if (line.length + 1 + word.length <= width) {
1833
+ const limit = isFirstLine ? firstContentWidth : continuationWidth;
1834
+ if (line && line.length + 1 + word.length <= limit) {
1730
1835
  line += ` ${word}`;
1731
1836
  continue;
1732
1837
  }
1733
- lines.push(line);
1734
- line = word;
1838
+ if (line) {
1839
+ lines.push(isFirstLine ? `${prefix}${line}` : line);
1840
+ isFirstLine = false;
1841
+ line = "";
1842
+ }
1843
+ let remaining = word;
1844
+ while (remaining.length > (isFirstLine ? firstContentWidth : continuationWidth)) {
1845
+ const chunk = takePrefix(remaining, isFirstLine ? firstContentWidth : continuationWidth);
1846
+ lines.push(isFirstLine ? `${prefix}${chunk.prefix}` : chunk.prefix);
1847
+ isFirstLine = false;
1848
+ remaining = chunk.rest;
1849
+ }
1850
+ line = remaining;
1735
1851
  }
1736
- lines.push(line);
1852
+ lines.push(isFirstLine ? `${prefix}${line}` : line);
1737
1853
  return lines;
1738
1854
  }
1739
1855
  function formatColumns2(opts) {
@@ -1751,29 +1867,44 @@ function formatColumns2(opts) {
1751
1867
  const indent = opts.indent ?? 2;
1752
1868
  const maxLeftContentWidth = Math.max(...rows.map((row) => row.left.length));
1753
1869
  const leftWidth = clamp2(maxLeftContentWidth + gap, minLeftWidth, maxLeftWidth);
1754
- const rightWidth = Math.max(20, totalWidth - leftWidth - indent);
1870
+ const rightWidth = Math.max(1, totalWidth - leftWidth - indent);
1871
+ const leftWrapWidth = Math.max(1, totalWidth - indent);
1755
1872
  const firstIndent = " ".repeat(indent);
1756
1873
  const continuationIndent = " ".repeat(indent + leftWidth);
1757
1874
  return rows.flatMap((row) => {
1875
+ let leftLeadingWidth = 0;
1876
+ while (leftLeadingWidth < row.left.length && isWhitespace2(row.left[leftLeadingWidth])) {
1877
+ leftLeadingWidth += 1;
1878
+ }
1879
+ const leftHangIndent = " ".repeat(indent + leftLeadingWidth + 2);
1880
+ const leftLines = wrapWords2(
1881
+ row.left,
1882
+ leftWrapWidth,
1883
+ Math.max(1, totalWidth - leftHangIndent.length)
1884
+ );
1758
1885
  if (row.right.length === 0) {
1759
- return [`${firstIndent}${row.left}`];
1886
+ return leftLines.map(
1887
+ (line, index) => index === 0 ? `${firstIndent}${line}` : `${leftHangIndent}${line}`
1888
+ );
1760
1889
  }
1761
1890
  const rightLines = wrapWords2(row.right, rightWidth);
1762
- if (row.left.length >= leftWidth) {
1763
- return [
1764
- `${firstIndent}${row.left}`,
1765
- ...rightLines.map((line) => `${continuationIndent}${line}`)
1766
- ];
1767
- }
1768
- const firstLine = `${firstIndent}${padEndVisible2(row.left, leftWidth)}${rightLines[0]}`;
1769
- const continuationLines = rightLines.slice(1).map((line) => `${continuationIndent}${line}`);
1770
- return [firstLine, ...continuationLines];
1891
+ const leftFitsInColumn = row.left.length < leftWidth;
1892
+ if (leftFitsInColumn && leftLines.length === 1) {
1893
+ const firstLine = `${firstIndent}${padEndVisible2(leftLines[0] ?? "", leftWidth)}${rightLines[0]}`;
1894
+ const continuationLines = rightLines.slice(1).map((line) => `${continuationIndent}${line}`);
1895
+ return [firstLine, ...continuationLines];
1896
+ }
1897
+ const renderedLeft = leftLines.map(
1898
+ (line, index) => index === 0 ? `${firstIndent}${line}` : `${leftHangIndent}${line}`
1899
+ );
1900
+ const renderedRight = rightLines.map((line) => `${continuationIndent}${line}`);
1901
+ return [...renderedLeft, ...renderedRight];
1771
1902
  }).join("\n");
1772
1903
  }
1773
1904
  function formatCommandList2(commands) {
1774
1905
  return formatColumns2({
1775
1906
  rows: commands.map((cmd) => ({
1776
- left: cmd.name,
1907
+ left: `${" ".repeat((cmd.depth ?? 0) * 2)}${cmd.nameTokens !== void 0 && cmd.nameTokens.length > 0 ? joinHelpTokens(cmd.nameTokens) : cmd.name}`,
1777
1908
  right: cmd.description
1778
1909
  }))
1779
1910
  });
@@ -1781,7 +1912,7 @@ function formatCommandList2(commands) {
1781
1912
  function formatOptionList2(options) {
1782
1913
  return formatColumns2({
1783
1914
  rows: options.map((opt) => ({
1784
- left: opt.flags,
1915
+ left: opt.flagTokens !== void 0 && opt.flagTokens.length > 0 ? joinHelpTokens(opt.flagTokens) : opt.flags,
1785
1916
  right: opt.description
1786
1917
  }))
1787
1918
  });
@@ -1790,6 +1921,7 @@ function formatOptionList2(options) {
1790
1921
  // ../toolcraft-design/src/components/table.ts
1791
1922
  var reset2 = "\x1B[0m";
1792
1923
  var ellipsis = "\u2026";
1924
+ var minCellWidth = 4;
1793
1925
  var graphemeSegmenter2 = new Intl.Segmenter(void 0, { granularity: "grapheme" });
1794
1926
  function getCell(row, name) {
1795
1927
  return Object.prototype.hasOwnProperty.call(row, name) ? row[name] ?? "" : "";
@@ -1923,6 +2055,39 @@ function computeColumns(columns) {
1923
2055
  width: getColumnWidth(column)
1924
2056
  }));
1925
2057
  }
2058
+ function frameWidth(columnCount) {
2059
+ return columnCount * 3 + 1;
2060
+ }
2061
+ function budgetColumns(columns, maxWidth) {
2062
+ if (maxWidth === void 0) {
2063
+ return columns;
2064
+ }
2065
+ const available = maxWidth - frameWidth(columns.length);
2066
+ const contentWidth = (cap2) => columns.reduce((total, column) => total + Math.min(column.width, cap2), 0);
2067
+ if (columns.reduce((total, column) => total + column.width, 0) <= available) {
2068
+ return columns;
2069
+ }
2070
+ let cap = minCellWidth;
2071
+ while (contentWidth(cap + 1) <= available) {
2072
+ cap += 1;
2073
+ }
2074
+ const budgeted = columns.map((column) => ({ ...column, width: Math.min(column.width, cap) }));
2075
+ let slack = available - contentWidth(cap);
2076
+ while (slack > 0) {
2077
+ const growable = budgeted.filter((column, index) => column.width < columns[index].width);
2078
+ if (growable.length === 0) {
2079
+ break;
2080
+ }
2081
+ for (const column of growable) {
2082
+ if (slack === 0) {
2083
+ break;
2084
+ }
2085
+ column.width += 1;
2086
+ slack -= 1;
2087
+ }
2088
+ }
2089
+ return budgeted;
2090
+ }
1926
2091
  function renderBorder(columns, theme, parts) {
1927
2092
  const horizontal = theme.muted("\u2500");
1928
2093
  const segments = columns.map((column) => horizontal.repeat(column.width + 2));
@@ -2007,14 +2172,15 @@ function renderTableTerminal(options) {
2007
2172
  }
2008
2173
  const separatorOptions = options;
2009
2174
  const includeRowSeparators = separatorOptions.rowSeparator === true || separatorOptions.rowSeparators === true;
2010
- const top = renderBorder(computedColumns, theme, { left: "\u250C", mid: "\u252C", right: "\u2510" });
2175
+ const budgetedColumns = budgetColumns(computedColumns, options.maxWidth ?? process.stdout.columns);
2176
+ const top = renderBorder(budgetedColumns, theme, { left: "\u250C", mid: "\u252C", right: "\u2510" });
2011
2177
  const header = renderTerminalRow(
2012
- computedColumns.map((column) => theme.header(column.title)),
2013
- computedColumns,
2178
+ budgetedColumns.map((column) => theme.header(column.title)),
2179
+ budgetedColumns,
2014
2180
  theme
2015
2181
  );
2016
- const headerBottom = renderBorder(computedColumns, theme, { left: "\u251C", mid: "\u253C", right: "\u2524" });
2017
- const bottom = renderBorder(computedColumns, theme, { left: "\u2514", mid: "\u2534", right: "\u2518" });
2182
+ const headerBottom = renderBorder(budgetedColumns, theme, { left: "\u251C", mid: "\u253C", right: "\u2524" });
2183
+ const bottom = renderBorder(budgetedColumns, theme, { left: "\u2514", mid: "\u2534", right: "\u2518" });
2018
2184
  const renderedRows = [];
2019
2185
  for (const [index, row] of rows.entries()) {
2020
2186
  if (includeRowSeparators && index > 0) {
@@ -2022,8 +2188,8 @@ function renderTableTerminal(options) {
2022
2188
  }
2023
2189
  renderedRows.push(
2024
2190
  renderTerminalRow(
2025
- computedColumns.map((column) => getCell(row, column.name)),
2026
- computedColumns,
2191
+ budgetedColumns.map((column) => getCell(row, column.name)),
2192
+ budgetedColumns,
2027
2193
  theme
2028
2194
  )
2029
2195
  );
@@ -2116,6 +2282,19 @@ ${options.theme.muted(options.badges.map((badge) => badge[0] + badge.slice(1).to
2116
2282
 
2117
2283
  // ../toolcraft-design/src/components/template.ts
2118
2284
  var MAX_PARTIAL_DEPTH = 100;
2285
+ var MAX_TAG_EXCERPT_LENGTH = 40;
2286
+ var TemplateParseError = class extends Error {
2287
+ description;
2288
+ line;
2289
+ column;
2290
+ constructor(description, position) {
2291
+ super(`${description} at line ${position.line}, column ${position.column}`);
2292
+ this.name = "TemplateParseError";
2293
+ this.description = description;
2294
+ this.line = position.line;
2295
+ this.column = position.column;
2296
+ }
2297
+ };
2119
2298
  var HTML_ESCAPE = {
2120
2299
  "&": "&amp;",
2121
2300
  "<": "&lt;",
@@ -2222,13 +2401,13 @@ function parseTag(template, open) {
2222
2401
  if (template.startsWith("{{{", open)) {
2223
2402
  const close2 = template.indexOf("}}}", open + 3);
2224
2403
  if (close2 === -1) {
2225
- throw new Error("Unclosed unescaped tag");
2404
+ throw unclosedTagError(template, open, "}}}");
2226
2405
  }
2227
2406
  return { kind: "unescaped", name: template.slice(open + 3, close2).trim(), end: close2 + 3 };
2228
2407
  }
2229
2408
  const close = template.indexOf("}}", open + 2);
2230
2409
  if (close === -1) {
2231
- throw new Error("Unclosed tag");
2410
+ throw unclosedTagError(template, open, "}}");
2232
2411
  }
2233
2412
  const raw = template.slice(open + 2, close).trim();
2234
2413
  const sigil = raw[0];
@@ -2243,6 +2422,16 @@ function parseTag(template, open) {
2243
2422
  if (sigil === "=" && raw.endsWith("=")) return { kind: "delimiter", name, end };
2244
2423
  return { kind: "name", name: raw, end };
2245
2424
  }
2425
+ function unclosedTagError(template, open, expected) {
2426
+ const before = template.slice(0, open);
2427
+ const lineEnd = template.indexOf("\n", open);
2428
+ const opened = template.slice(open, lineEnd === -1 ? template.length : lineEnd).trimEnd();
2429
+ const tag = opened.length > MAX_TAG_EXCERPT_LENGTH ? `${opened.slice(0, MAX_TAG_EXCERPT_LENGTH)}...` : opened;
2430
+ return new TemplateParseError(`Unclosed tag "${tag}": expected "${expected}"`, {
2431
+ line: before.split("\n").length,
2432
+ column: open - (before.lastIndexOf("\n") + 1) + 1
2433
+ });
2434
+ }
2246
2435
  function getStandalone(template, tagStart, tagEnd, kind) {
2247
2436
  if (!["section", "inverted", "close", "comment", "partial", "delimiter"].includes(kind)) {
2248
2437
  return void 0;
@@ -2814,6 +3003,15 @@ var cursor = {
2814
3003
  var erase = {
2815
3004
  down: "\x1B[J"
2816
3005
  };
3006
+ function nonTtyPromptMessage(argv = process.argv) {
3007
+ const tokens = [];
3008
+ for (const arg of argv.slice(2)) {
3009
+ if (arg.startsWith("-")) break;
3010
+ tokens.push(arg);
3011
+ }
3012
+ const retry = [...tokens, "--yes"].join(" ");
3013
+ return `Interactive prompt requires a TTY. Re-run with \`${retry}\` to accept defaults non-interactively, or set POE_NO_PROMPT=1 in CI.`;
3014
+ }
2817
3015
  var Prompt = class extends EventEmitter {
2818
3016
  state = "initial";
2819
3017
  value;
@@ -2884,7 +3082,7 @@ var Prompt = class extends EventEmitter {
2884
3082
  });
2885
3083
  }
2886
3084
  promptNonTty() {
2887
- return Promise.reject(new Error("Interactive prompt requires a TTY. Set POE_NO_PROMPT=1 to accept defaults non-interactively."));
3085
+ return Promise.reject(new Error(nonTtyPromptMessage()));
2888
3086
  }
2889
3087
  readNonTtyLine() {
2890
3088
  return new Promise((resolve) => {
@@ -3408,6 +3606,9 @@ var UserError = class extends Error {
3408
3606
  this.name = "UserError";
3409
3607
  }
3410
3608
  };
3609
+ function isUserError(error3) {
3610
+ return error3 instanceof UserError || error3 instanceof Error && error3.name === "UserError";
3611
+ }
3411
3612
  var ToolcraftBugError = class extends Error {
3412
3613
  constructor(message2) {
3413
3614
  super(message2);
@@ -5049,6 +5250,9 @@ function compactUrl(value) {
5049
5250
  return value;
5050
5251
  }
5051
5252
  }
5253
+ function stackedList(value) {
5254
+ return value.map((entry) => displayScalar(entry)).join("\n") || "\u2014";
5255
+ }
5052
5256
  function displayRowValue(value) {
5053
5257
  return isUrl(value) ? compactUrl(value) : displayScalar(value);
5054
5258
  }
@@ -5074,7 +5278,7 @@ function renderObjectCard(result, primitives, title) {
5074
5278
  const scalarRows = directScalarRows(result);
5075
5279
  const nestedSections = directObjectSections(result);
5076
5280
  const arrayObjectSections = directArrayObjectSections(result);
5077
- const listRows = Object.entries(result).filter(([, value]) => Array.isArray(value) && !isNonEmptyArrayOfObjects(value)).map(([key, value]) => ({ label: humanizeKey(key), value: displayScalar(value) }));
5281
+ const listRows = Object.entries(result).filter(([, value]) => Array.isArray(value) && !isNonEmptyArrayOfObjects(value)).map(([key, value]) => ({ label: humanizeKey(key), value: stackedList(value) }));
5078
5282
  return renderDetailCard({
5079
5283
  theme: primitives.getTheme(),
5080
5284
  title,
@@ -5776,6 +5980,13 @@ function formatOptionFlags(field, globalLongOptionFlags) {
5776
5980
  }
5777
5981
  return [`-${field.shortFlag}`, field.optionFlag, ...field.longAliases].join(", ");
5778
5982
  }
5983
+ function formatMissingParameterMessage(field) {
5984
+ const message2 = `Missing required parameter "${field.displayPath}".`;
5985
+ if (field.schema.kind !== "enum") {
5986
+ return message2;
5987
+ }
5988
+ return `${message2} Expected one of: ${field.schema.values.map((value) => String(value)).join(", ")}.`;
5989
+ }
5779
5990
  function formatPositionalToken(field) {
5780
5991
  const optionalPositional = field.optional || field.hasDefault;
5781
5992
  if (field.variadicPosition === true) {
@@ -6062,6 +6273,7 @@ function resolveCLIControls(controls) {
6062
6273
  validateOutputFormats(outputFormats);
6063
6274
  return {
6064
6275
  debug: controls?.debug === true,
6276
+ help: controls?.help === "concise" ? "concise" : "extended",
6065
6277
  logLevel: controls?.logLevel === true,
6066
6278
  output: controls?.output === true || typeof controls?.output === "object",
6067
6279
  outputFormats,
@@ -6256,12 +6468,31 @@ function appendHelpMetadata(description, metadata) {
6256
6468
  return description;
6257
6469
  }
6258
6470
  if (description.length === 0) {
6259
- return `(${metadata.join(", ")})`;
6471
+ return metadata.map((entry) => `(${entry})`).join(" ");
6260
6472
  }
6261
- return `${description} (${metadata.join(", ")})`;
6473
+ return `${description} ${metadata.map((entry) => `(${entry})`).join(" ")}`;
6474
+ }
6475
+ function normalizeHelpEchoKey(value) {
6476
+ let normalized = "";
6477
+ for (const character of value.trim().toLowerCase()) {
6478
+ if (character !== " " && character !== " " && character !== "\n" && character !== "\r" && character !== "_" && character !== "." && character !== "-") {
6479
+ normalized += character;
6480
+ }
6481
+ }
6482
+ return normalized;
6483
+ }
6484
+ function isEchoHelpDescription(description, name) {
6485
+ if (description.length === 0) {
6486
+ return false;
6487
+ }
6488
+ return normalizeHelpEchoKey(description) === normalizeHelpEchoKey(name);
6489
+ }
6490
+ function suppressEchoHelpDescription(description, name) {
6491
+ return isEchoHelpDescription(description, name) ? "" : description;
6262
6492
  }
6263
6493
  function formatHelpFieldDescription(field) {
6264
- const description = field.description ?? field.displayPath;
6494
+ const rawDescription = field.description ?? field.displayPath;
6495
+ const description = suppressEchoHelpDescription(rawDescription, field.displayPath);
6265
6496
  const metadata = [];
6266
6497
  if (field.schema.kind === "enum" && field.schema.values.length <= 8) {
6267
6498
  const values = field.schema.values.map((value) => String(value)).join(", ");
@@ -6410,13 +6641,21 @@ function formatDynamicHelpMetadata(field) {
6410
6641
  }
6411
6642
  return metadata;
6412
6643
  }
6644
+ function createHelpOptionRow(flags, description) {
6645
+ return {
6646
+ flags,
6647
+ flagTokens: tokenizeHelpFlags(flags),
6648
+ description
6649
+ };
6650
+ }
6413
6651
  function collectDynamicObjectHelpRows(schema, casing, optionPrefix, displayPrefix, metadata) {
6414
6652
  const rows = [];
6415
6653
  for (const [key, rawChildSchema] of Object.entries(schema.shape)) {
6416
6654
  const childSchema = unwrapOptional2(rawChildSchema);
6417
6655
  const optionFlag = `${optionPrefix}.${formatSegment(key, casing)}`;
6418
6656
  const displayPath = `${displayPrefix}.${key}`;
6419
- const description = childSchema.description ?? displayPath;
6657
+ const rawDescription = childSchema.description ?? displayPath;
6658
+ const description = suppressEchoHelpDescription(rawDescription, displayPath);
6420
6659
  if (childSchema.kind === "object") {
6421
6660
  rows.push(
6422
6661
  ...collectDynamicObjectHelpRows(childSchema, casing, optionFlag, displayPath, metadata)
@@ -6424,24 +6663,26 @@ function collectDynamicObjectHelpRows(schema, casing, optionPrefix, displayPrefi
6424
6663
  continue;
6425
6664
  }
6426
6665
  if (childSchema.kind === "record") {
6427
- rows.push({
6428
- flags: `${optionFlag}.<key> <${describeDynamicFieldType({
6429
- ...{
6430
- id: displayPath,
6431
- path: [],
6432
- displayPath,
6433
- optionPath: [],
6434
- optionPathDisplay: `${displayPath}.<key>`,
6435
- optionFlag: `${optionFlag}.<key>`,
6436
- optional: false,
6437
- hasDefault: false,
6438
- defaultValue: void 0,
6439
- requiredWhenActive: false,
6440
- schema: childSchema
6441
- }
6442
- })}>`,
6443
- description: appendHelpMetadata(description, metadata)
6444
- });
6666
+ rows.push(
6667
+ createHelpOptionRow(
6668
+ `${optionFlag}.<key> <${describeDynamicFieldType({
6669
+ ...{
6670
+ id: displayPath,
6671
+ path: [],
6672
+ displayPath,
6673
+ optionPath: [],
6674
+ optionPathDisplay: `${displayPath}.<key>`,
6675
+ optionFlag: `${optionFlag}.<key>`,
6676
+ optional: false,
6677
+ hasDefault: false,
6678
+ defaultValue: void 0,
6679
+ requiredWhenActive: false,
6680
+ schema: childSchema
6681
+ }
6682
+ })}>`,
6683
+ appendHelpMetadata(description, metadata)
6684
+ )
6685
+ );
6445
6686
  continue;
6446
6687
  }
6447
6688
  if (childSchema.kind === "array" && unwrapOptional2(childSchema.item).kind === "object") {
@@ -6456,13 +6697,15 @@ function collectDynamicObjectHelpRows(schema, casing, optionPrefix, displayPrefi
6456
6697
  );
6457
6698
  continue;
6458
6699
  }
6459
- rows.push({
6460
- flags: childSchema.kind === "boolean" ? childSchema.default === true ? `--no-${optionFlag.slice(2)}` : optionFlag : `${optionFlag} <${describeHelpValueToken(childSchema, {
6461
- displayPath,
6462
- optionFlag
6463
- })}>`,
6464
- description: appendHelpMetadata(description, metadata)
6465
- });
6700
+ rows.push(
6701
+ createHelpOptionRow(
6702
+ childSchema.kind === "boolean" ? childSchema.default === true ? `--no-${optionFlag.slice(2)}` : optionFlag : `${optionFlag} <${describeHelpValueToken(childSchema, {
6703
+ displayPath,
6704
+ optionFlag
6705
+ })}>`,
6706
+ appendHelpMetadata(description, metadata)
6707
+ )
6708
+ );
6466
6709
  }
6467
6710
  return rows;
6468
6711
  }
@@ -6493,17 +6736,22 @@ function formatDynamicHelpFields(field, casing) {
6493
6736
  }
6494
6737
  }
6495
6738
  return [
6496
- {
6497
- flags: `${field.optionFlag} <${describeDynamicFieldType(field)}>`,
6498
- description: appendHelpMetadata(field.description ?? field.optionPathDisplay, metadata)
6499
- }
6739
+ createHelpOptionRow(
6740
+ `${field.optionFlag} <${describeDynamicFieldType(field)}>`,
6741
+ appendHelpMetadata(
6742
+ suppressEchoHelpDescription(
6743
+ field.description ?? field.optionPathDisplay,
6744
+ field.optionPathDisplay
6745
+ ),
6746
+ metadata
6747
+ )
6748
+ )
6500
6749
  ];
6501
6750
  }
6502
6751
  function formatSecretRows(secrets) {
6503
- return Object.values(secrets).map((secret) => ({
6504
- flags: secret.env,
6505
- description: formatSecretDescription(secret)
6506
- }));
6752
+ return Object.values(secrets).map(
6753
+ (secret) => createHelpOptionRow(secret.env, formatSecretDescription(secret))
6754
+ );
6507
6755
  }
6508
6756
  function formatSecretDescription(secret) {
6509
6757
  if (secret.description !== void 0 && secret.description.length > 0) {
@@ -6531,20 +6779,82 @@ function formatExampleRows(examples, breadcrumb, rootUsageName) {
6531
6779
  ${formatExampleCommand(breadcrumb, rootUsageName, example.params)}`
6532
6780
  );
6533
6781
  }
6534
- function wrapOptionalCommandParameterToken(token, optional) {
6535
- return optional ? `[${token}]` : token;
6782
+ var MAX_INLINE_OPTIONAL_PARAMETER_TOKENS = 8;
6783
+ var DEFAULT_HELP_TOTAL_WIDTH = 100;
6784
+ function tokenizeHelpFlags(flags) {
6785
+ const tokens = [];
6786
+ let index = 0;
6787
+ while (index < flags.length) {
6788
+ if (flags[index] === " ") {
6789
+ let end2 = index + 1;
6790
+ while (end2 < flags.length && flags[end2] === " ") {
6791
+ end2 += 1;
6792
+ }
6793
+ tokens.push({ text: flags.slice(index, end2), role: "literal" });
6794
+ index = end2;
6795
+ continue;
6796
+ }
6797
+ if (flags[index] === "[" || flags[index] === "]") {
6798
+ tokens.push({ text: flags[index], role: "dim" });
6799
+ index += 1;
6800
+ continue;
6801
+ }
6802
+ if (flags[index] === "<") {
6803
+ const close = flags.indexOf(">", index);
6804
+ if (close === -1) {
6805
+ tokens.push({ text: flags.slice(index), role: "literal" });
6806
+ break;
6807
+ }
6808
+ tokens.push({ text: flags.slice(index, close + 1), role: "argument" });
6809
+ index = close + 1;
6810
+ continue;
6811
+ }
6812
+ if (flags.startsWith("--", index) || flags[index] === "-" && flags[index + 1] !== void 0 && flags[index + 1] !== "-") {
6813
+ let end2 = index + 1;
6814
+ while (end2 < flags.length && flags[end2] !== " " && flags[end2] !== "[" && flags[end2] !== "]" && flags[end2] !== "<") {
6815
+ end2 += 1;
6816
+ }
6817
+ tokens.push({ text: flags.slice(index, end2), role: "option" });
6818
+ index = end2;
6819
+ continue;
6820
+ }
6821
+ let end = index + 1;
6822
+ while (end < flags.length && flags[end] !== " " && flags[end] !== "[" && flags[end] !== "]" && flags[end] !== "<") {
6823
+ end += 1;
6824
+ }
6825
+ const piece = flags.slice(index, end);
6826
+ tokens.push({
6827
+ text: piece,
6828
+ role: piece.includes("|") ? "literal" : piece.startsWith("+") ? "dim" : "literal"
6829
+ });
6830
+ index = end;
6831
+ }
6832
+ return tokens;
6833
+ }
6834
+ function wrapOptionalParameterTokens(tokens, optional) {
6835
+ if (!optional) {
6836
+ return tokens;
6837
+ }
6838
+ return [{ text: "[", role: "dim" }, ...tokens, { text: "]", role: "dim" }];
6839
+ }
6840
+ function createCommandParameterToken(text3, optional) {
6841
+ return {
6842
+ text: optional ? `[${text3}]` : text3,
6843
+ optional,
6844
+ tokens: wrapOptionalParameterTokens(tokenizeHelpFlags(text3), optional)
6845
+ };
6536
6846
  }
6537
6847
  function formatCommandDynamicParameterTokens(field, casing) {
6538
6848
  const optional = field.optional || field.hasDefault;
6539
6849
  return formatDynamicHelpFields(field, casing).map(
6540
- (row) => wrapOptionalCommandParameterToken(row.flags, optional)
6850
+ (row) => createCommandParameterToken(row.flags, optional)
6541
6851
  );
6542
6852
  }
6543
6853
  function formatCommandParameterTokens(command, casing, globalLongOptionFlags) {
6544
6854
  const collected = collectFields(command.params, casing, globalLongOptionFlags);
6545
6855
  const fields = assignPositionals(collected.fields, command.positional);
6546
6856
  return fields.filter((field) => field.global !== true).map(
6547
- (field) => wrapOptionalCommandParameterToken(
6857
+ (field) => createCommandParameterToken(
6548
6858
  formatCommandParameterFieldFlags(field, globalLongOptionFlags),
6549
6859
  field.positionalIndex === void 0 && (field.optional || field.hasDefault)
6550
6860
  )
@@ -6552,17 +6862,72 @@ function formatCommandParameterTokens(command, casing, globalLongOptionFlags) {
6552
6862
  collected.dynamicFields.flatMap((field) => formatCommandDynamicParameterTokens(field, casing))
6553
6863
  );
6554
6864
  }
6555
- function formatCommandRowName(node, casing, globalLongOptionFlags) {
6865
+ function collapseOptionalParameterTokens(parameterTokens, inlineWidthBudget = Number.POSITIVE_INFINITY) {
6866
+ const optionalCount = parameterTokens.filter((token) => token.optional).length;
6867
+ if (optionalCount === 0) {
6868
+ return parameterTokens;
6869
+ }
6870
+ const inlineWidth = parameterTokens.reduce((total, token) => total + token.text.length + 1, 0);
6871
+ if (optionalCount <= MAX_INLINE_OPTIONAL_PARAMETER_TOKENS && inlineWidth <= inlineWidthBudget) {
6872
+ return parameterTokens;
6873
+ }
6874
+ const required = parameterTokens.filter((token) => !token.optional);
6875
+ const collapsedText = `+${optionalCount} options`;
6876
+ return [
6877
+ ...required,
6878
+ {
6879
+ text: `[${collapsedText}]`,
6880
+ optional: true,
6881
+ tokens: [
6882
+ { text: "[", role: "dim" },
6883
+ { text: collapsedText, role: "dim" },
6884
+ { text: "]", role: "dim" }
6885
+ ]
6886
+ }
6887
+ ];
6888
+ }
6889
+ function formatCommandRowNameTokens(node, casing, globalLongOptionFlags) {
6556
6890
  const baseName = node.aliases.length === 0 ? node.name : `${node.name} (${node.aliases.join(", ")})`;
6557
- const parameterTokens = node.kind === "command" ? formatCommandParameterTokens(node, casing, globalLongOptionFlags) : [];
6558
- const name = parameterTokens.length === 0 ? baseName : `${baseName} ${parameterTokens.join(" ")}`;
6559
- return name;
6560
- }
6561
- function formatCommandRows(group, scope, casing, globalLongOptionFlags) {
6562
- return getHelpChildren(group, scope).map((child) => ({
6563
- name: formatCommandRowName(child, casing, globalLongOptionFlags),
6564
- description: child.description ?? ""
6565
- }));
6891
+ const nameTokens = [{ text: baseName, role: "command" }];
6892
+ const inlineWidthBudget = Math.max(
6893
+ 0,
6894
+ (process.stdout.columns ?? DEFAULT_HELP_TOTAL_WIDTH) - 2 - baseName.length
6895
+ );
6896
+ const parameterTokens = node.kind === "command" ? collapseOptionalParameterTokens(
6897
+ formatCommandParameterTokens(node, casing, globalLongOptionFlags),
6898
+ inlineWidthBudget
6899
+ ) : [];
6900
+ for (const token of parameterTokens) {
6901
+ nameTokens.push({ text: " ", role: "literal" }, ...token.tokens);
6902
+ }
6903
+ const name = parameterTokens.length === 0 ? baseName : `${baseName} ${parameterTokens.map((token) => token.text).join(" ")}`;
6904
+ return { name, nameTokens };
6905
+ }
6906
+ function formatCommandRows(group, scope, casing, globalLongOptionFlags, help) {
6907
+ const toRow = (child, depth) => {
6908
+ const { name, nameTokens } = formatCommandRowNameTokens(child, casing, globalLongOptionFlags);
6909
+ return {
6910
+ name,
6911
+ nameTokens,
6912
+ description: suppressEchoHelpDescription(child.description ?? "", child.name),
6913
+ kind: child.kind,
6914
+ depth
6915
+ };
6916
+ };
6917
+ if (help === "concise") {
6918
+ return getHelpChildren(group, scope).map((child) => toRow(child, 0));
6919
+ }
6920
+ const rows = [];
6921
+ const visit = (node, depth) => {
6922
+ for (const child of getHelpChildren(node, scope)) {
6923
+ rows.push(toRow(child, depth));
6924
+ if (child.kind === "group") {
6925
+ visit(child, depth + 1);
6926
+ }
6927
+ }
6928
+ };
6929
+ visit(group, 0);
6930
+ return rows;
6566
6931
  }
6567
6932
  function formatGlobalOptionsLine(ctx) {
6568
6933
  const flags = [];
@@ -6581,10 +6946,10 @@ function formatGlobalOptionsLine(ctx) {
6581
6946
  if (ctx.showVersion) {
6582
6947
  flags.push("--version");
6583
6948
  }
6584
- return flags.length > 0 ? `${text.section("Options:")} ${flags.join(" ")}` : "";
6949
+ return flags.length > 0 ? `${text.section("Global Options:")} ${flags.join(" ")}` : "";
6585
6950
  }
6586
6951
  function formatLeafGlobalOptionsLine(ctx) {
6587
- return ctx.controls.verbose ? `${text.section("Options:")} -v, --verbose` : "";
6952
+ return ctx.controls.verbose ? `${text.section("Global Options:")} -v, --verbose` : "";
6588
6953
  }
6589
6954
  function collectSchemaGlobalFieldRows(group, scope, casing, globalLongOptionFlags) {
6590
6955
  const seen = /* @__PURE__ */ new Map();
@@ -6602,10 +6967,13 @@ function collectSchemaGlobalFieldRows(group, scope, casing, globalLongOptionFlag
6602
6967
  if (seen.has(dedupeKey)) {
6603
6968
  continue;
6604
6969
  }
6605
- seen.set(dedupeKey, {
6606
- flags: formatHelpFieldFlags(field, globalLongOptionFlags),
6607
- description: formatHelpFieldDescription(field)
6608
- });
6970
+ seen.set(
6971
+ dedupeKey,
6972
+ createHelpOptionRow(
6973
+ formatHelpFieldFlags(field, globalLongOptionFlags),
6974
+ formatHelpFieldDescription(field)
6975
+ )
6976
+ );
6609
6977
  }
6610
6978
  return;
6611
6979
  }
@@ -6625,6 +6993,18 @@ function formatHelpCommandList(rows) {
6625
6993
  function formatHelpOptionList(rows) {
6626
6994
  return process.stdout.isTTY !== true ? help_formatter_plain_exports.formatOptionList(rows) : formatOptionList(rows);
6627
6995
  }
6996
+ function sortLeafHelpOptionFields(fields) {
6997
+ const required = [];
6998
+ const optional = [];
6999
+ for (const field of fields) {
7000
+ if (!field.optional && !field.hasDefault) {
7001
+ required.push(field);
7002
+ continue;
7003
+ }
7004
+ optional.push(field);
7005
+ }
7006
+ return [...required, ...optional];
7007
+ }
6628
7008
  function buildUsageLine(breadcrumb, rootUsageName, suffix) {
6629
7009
  const visibleBreadcrumb = breadcrumb.filter((segment) => segment.length > 0);
6630
7010
  const usageBreadcrumb = breadcrumb[0] === "" ? [rootUsageName, ...visibleBreadcrumb] : visibleBreadcrumb;
@@ -6634,15 +7014,37 @@ function buildUsageLine(breadcrumb, rootUsageName, suffix) {
6634
7014
  }
6635
7015
  function formatGroupUsageSuffix(group, scope, casing, globalLongOptionFlags) {
6636
7016
  if (group.default !== void 0 && group.default.hidden === true && group.default.scope.includes(scope)) {
6637
- const parameterTokens = formatCommandParameterTokens(
6638
- group.default,
6639
- casing,
6640
- globalLongOptionFlags
7017
+ const parameterTokens = collapseOptionalParameterTokens(
7018
+ formatCommandParameterTokens(group.default, casing, globalLongOptionFlags)
6641
7019
  );
6642
- return ["[command]", "[OPTIONS]", ...parameterTokens].join(" ");
7020
+ return ["[command]", "[OPTIONS]", ...parameterTokens.map((token) => token.text)].join(" ");
6643
7021
  }
6644
7022
  return "[command] [OPTIONS]";
6645
7023
  }
7024
+ function formatHelpDrillDownFooter(rootUsageName) {
7025
+ return text.muted(`Run ${rootUsageName} <command> --help for full options.`);
7026
+ }
7027
+ function formatStyledUsageLine(usageLine) {
7028
+ const parts = usageLine.split(" ").filter((part) => part.length > 0);
7029
+ if (parts.length === 0) {
7030
+ return text.usageCommand(usageLine);
7031
+ }
7032
+ const commandEnd = parts.findIndex(
7033
+ (part) => part.startsWith("-") || part.startsWith("[") || part.startsWith("<")
7034
+ );
7035
+ const commandParts = commandEnd === -1 ? parts : parts.slice(0, commandEnd);
7036
+ const argParts = commandEnd === -1 ? [] : parts.slice(commandEnd);
7037
+ const command = commandParts.join(" ");
7038
+ if (argParts.length === 0) {
7039
+ return text.usageCommand(command);
7040
+ }
7041
+ return `${text.usageCommand(command)} ${renderHelpTokens(
7042
+ argParts.flatMap((part, index) => [
7043
+ ...index === 0 ? [] : [{ text: " ", role: "literal" }],
7044
+ ...tokenizeHelpFlags(part)
7045
+ ])
7046
+ )}`;
7047
+ }
6646
7048
  function renderGroupHelp(group, breadcrumb, scope, casing, globalOptions, rootUsageName, isRoot) {
6647
7049
  const sections = [];
6648
7050
  const globalLongOptionFlags = getGlobalLongOptionFlags(
@@ -6650,9 +7052,15 @@ function renderGroupHelp(group, breadcrumb, scope, casing, globalOptions, rootUs
6650
7052
  globalOptions.showVersion,
6651
7053
  globalOptions.controls
6652
7054
  );
6653
- const commandRows = formatCommandRows(group, scope, casing, globalLongOptionFlags);
7055
+ const commandRows = formatCommandRows(
7056
+ group,
7057
+ scope,
7058
+ casing,
7059
+ globalLongOptionFlags,
7060
+ globalOptions.controls.help
7061
+ );
6654
7062
  if (commandRows.length > 0) {
6655
- sections.push(`${text.sectionHeader("Commands")}
7063
+ sections.push(`${text.section("Commands:")}
6656
7064
  ${formatHelpCommandList(commandRows)}`);
6657
7065
  }
6658
7066
  if (isRoot) {
@@ -6665,7 +7073,7 @@ ${formatHelpCommandList(commandRows)}`);
6665
7073
  const builtInLine = formatGlobalOptionsLine(globalOptions);
6666
7074
  if (schemaGlobalRows.length > 0) {
6667
7075
  sections.push(
6668
- `${text.sectionHeader("Options")}
7076
+ `${text.section("Options:")}
6669
7077
  ${formatHelpOptionList(schemaGlobalRows)}
6670
7078
  ${builtInLine}`
6671
7079
  );
@@ -6673,6 +7081,9 @@ ${builtInLine}`
6673
7081
  sections.push(builtInLine);
6674
7082
  }
6675
7083
  }
7084
+ if (commandRows.length > 0) {
7085
+ sections.push(formatHelpDrillDownFooter(rootUsageName));
7086
+ }
6676
7087
  return renderHelpDocument({
6677
7088
  breadcrumb,
6678
7089
  rootUsageName,
@@ -6695,12 +7106,21 @@ function renderLeafHelp(command, breadcrumb, casing, globalOptions, rootUsageNam
6695
7106
  );
6696
7107
  const collected = collectFields(command.params, casing, globalLongOptionFlags);
6697
7108
  const fields = assignPositionals(collected.fields, command.positional);
6698
- const optionRows = fields.filter((field) => field.global !== true).map((field) => ({
6699
- flags: formatHelpFieldFlags(field, globalLongOptionFlags),
6700
- description: formatHelpFieldDescription(field)
6701
- })).concat(collected.dynamicFields.flatMap((field) => formatDynamicHelpFields(field, casing)));
7109
+ const localFields = fields.filter((field) => field.global !== true);
7110
+ const toHelpRow = (field) => createHelpOptionRow(
7111
+ formatHelpFieldFlags(field, globalLongOptionFlags),
7112
+ formatHelpFieldDescription(field)
7113
+ );
7114
+ const argumentRows = localFields.filter((field) => field.positionalIndex !== void 0).map(toHelpRow);
7115
+ const optionRows = sortLeafHelpOptionFields(
7116
+ localFields.filter((field) => field.positionalIndex === void 0)
7117
+ ).map(toHelpRow).concat(collected.dynamicFields.flatMap((field) => formatDynamicHelpFields(field, casing)));
7118
+ if (argumentRows.length > 0) {
7119
+ sections.push(`${text.section("Arguments:")}
7120
+ ${formatHelpOptionList(argumentRows)}`);
7121
+ }
6702
7122
  if (optionRows.length > 0) {
6703
- sections.push(`${text.sectionHeader("Options")}
7123
+ sections.push(`${text.section("Options:")}
6704
7124
  ${formatHelpOptionList(optionRows)}`);
6705
7125
  }
6706
7126
  const builtInLine = formatLeafGlobalOptionsLine(globalOptions);
@@ -6710,13 +7130,13 @@ ${formatHelpOptionList(optionRows)}`);
6710
7130
  const secretRows = formatSecretRows(command.secrets);
6711
7131
  if (secretRows.length > 0) {
6712
7132
  sections.push(
6713
- `${text.sectionHeader("Secrets (environment)")}
7133
+ `${text.section("Secrets (environment):")}
6714
7134
  ${formatHelpOptionList(secretRows)}`
6715
7135
  );
6716
7136
  }
6717
7137
  if (command.examples.length > 0) {
6718
7138
  sections.push(
6719
- `${text.sectionHeader("Examples")}
7139
+ `${text.section("Examples:")}
6720
7140
  ${formatExampleRows(command.examples, breadcrumb, rootUsageName).join("\n")}`
6721
7141
  );
6722
7142
  }
@@ -6739,7 +7159,13 @@ function renderJsonHelp(target, root, casing, globalOptions, rootUsageName) {
6739
7159
  );
6740
7160
  const node = target.node;
6741
7161
  if (node.kind === "group") {
6742
- const commandRows = formatCommandRows(node, "cli", casing, globalLongOptionFlags);
7162
+ const commandRows = formatCommandRows(
7163
+ node,
7164
+ "cli",
7165
+ casing,
7166
+ globalLongOptionFlags,
7167
+ globalOptions.controls.help
7168
+ );
6743
7169
  const isRoot = node === root;
6744
7170
  return `${JSON.stringify(
6745
7171
  {
@@ -6753,7 +7179,12 @@ function renderJsonHelp(target, root, casing, globalOptions, rootUsageName) {
6753
7179
  formatGroupUsageSuffix(node, "cli", casing, globalLongOptionFlags)
6754
7180
  ),
6755
7181
  ...node.description === void 0 ? {} : { description: node.description },
6756
- commands: commandRows.map((row) => ({ name: row.name, description: row.description })),
7182
+ commands: commandRows.map((row) => ({
7183
+ name: row.name,
7184
+ description: row.description,
7185
+ kind: row.kind,
7186
+ depth: row.depth
7187
+ })),
6757
7188
  options: isRoot ? collectSchemaGlobalFieldRows(node, "cli", casing, globalLongOptionFlags).map((row) => ({
6758
7189
  name: row.flags.split(/[ ,]+/)[0]?.replace(/^--/, "") ?? row.flags,
6759
7190
  flags: row.flags.split(", "),
@@ -6827,7 +7258,7 @@ function renderHelpDocument(input) {
6827
7258
  if (remainingDescription.length > 0) {
6828
7259
  lines.push(remainingDescription, "");
6829
7260
  }
6830
- lines.push(`Usage: ${text.usageCommand(input.usageLine)}`, "");
7261
+ lines.push(`Usage: ${formatStyledUsageLine(input.usageLine)}`, "");
6831
7262
  if (input.requiresAuth) {
6832
7263
  lines.push("Requires: authentication");
6833
7264
  }
@@ -6911,7 +7342,9 @@ function createNodeCommand(node, casing, globalLongOptionFlags, execute, presets
6911
7342
  }
6912
7343
  for (const field of fields) {
6913
7344
  if (field.positionalIndex !== void 0) {
6914
- command.argument(formatPositionalToken(field));
7345
+ command.argument(
7346
+ field.variadicPosition === true ? `[${field.displayPath}...]` : `[${field.displayPath}]`
7347
+ );
6915
7348
  continue;
6916
7349
  }
6917
7350
  for (const option of createOption(field, globalLongOptionFlags)) {
@@ -7746,11 +8179,11 @@ function writeRichHeader(title) {
7746
8179
  function isHumanInLoopPending(result) {
7747
8180
  return typeof result === "object" && result !== null && result.status === "pending-approval" && typeof result.approvalId === "string" && typeof result.message === "string" && typeof result.enqueuedAt === "string";
7748
8181
  }
7749
- function renderHumanInLoopPending(pending) {
8182
+ function renderHumanInLoopPending(pending, rootUsageName) {
7750
8183
  process.stdout.write(
7751
8184
  `\u2713 Queued for human approval (id: ${pending.approvalId})
7752
8185
  Message: ${pending.message}
7753
- Track: toolcraft approvals show ${pending.approvalId}
8186
+ Track: ${rootUsageName} approvals show --approval-id ${pending.approvalId}
7754
8187
  `
7755
8188
  );
7756
8189
  }
@@ -7854,7 +8287,7 @@ function parseOptionFieldValue(field, value, errors) {
7854
8287
  }
7855
8288
  return { ok: true, value: parsedValue };
7856
8289
  } catch (error3) {
7857
- if (error3 instanceof UserError || error3 instanceof InvalidArgumentError) {
8290
+ if (isUserError(error3) || error3 instanceof InvalidArgumentError) {
7858
8291
  errors.push({
7859
8292
  path: field.displayPath,
7860
8293
  message: error3.message
@@ -8436,7 +8869,7 @@ async function resolveParams(fields, dynamicFields, variants, positionalValues,
8436
8869
  }
8437
8870
  errors.push({
8438
8871
  path: field.displayPath,
8439
- message: `Missing required parameter "${field.displayPath}".`
8872
+ message: formatMissingParameterMessage(field)
8440
8873
  });
8441
8874
  continue;
8442
8875
  }
@@ -8487,7 +8920,7 @@ function getResolvedFlags(command) {
8487
8920
  const flags = command.optsWithGlobals();
8488
8921
  return flags;
8489
8922
  }
8490
- async function executeCommand(state, services, requirementOptions, runtimeFetch, humanInLoop, runtimeEnv, runtimeFs, outputEmitter, outputFormats, promptStreams, diagnosticsOptions, onErrorReportContext) {
8923
+ async function executeCommand(state, rootUsageName, services, requirementOptions, runtimeFetch, humanInLoop, runtimeEnv, runtimeFs, outputEmitter, outputFormats, promptStreams, diagnosticsOptions, onErrorReportContext) {
8491
8924
  const logger2 = createLogger(outputEmitter);
8492
8925
  const optionValues = state.actionCommand.optsWithGlobals();
8493
8926
  const resolvedFlags = optionValues;
@@ -8643,7 +9076,7 @@ async function executeCommand(state, services, requirementOptions, runtimeFetch,
8643
9076
  writeRichHeader(`${state.command.name} (fixture)`);
8644
9077
  }
8645
9078
  if (isHumanInLoopPending(result)) {
8646
- renderHumanInLoopPending(result);
9079
+ renderHumanInLoopPending(result, rootUsageName);
8647
9080
  return;
8648
9081
  }
8649
9082
  const renderStatus = renderCLIResult(
@@ -8886,7 +9319,7 @@ function renderHttpError(error3, options) {
8886
9319
  async function handleRunError(error3, options) {
8887
9320
  const logger2 = createLogger(options.outputEmitter);
8888
9321
  await withOutputFormat2(options.output, async () => {
8889
- if (error3 instanceof UserError) {
9322
+ if (isUserError(error3)) {
8890
9323
  renderCliErrorPattern(
8891
9324
  options.userErrorPattern === "definition" ? {
8892
9325
  kind: "definition",
@@ -9202,11 +9635,9 @@ function getDefaultCommanderCommandName(command) {
9202
9635
  function configureCommanderSuggestionOutput(command) {
9203
9636
  command.exitOverride();
9204
9637
  command.configureOutput({
9205
- outputError: (message2, write2) => {
9206
- if (message2.includes("unknown command") || message2.includes("unknown option")) {
9207
- return;
9208
- }
9209
- write2(message2);
9638
+ // Every Commander error throws through exitOverride and is rendered once by handleRunError
9639
+ // in the design-system error pattern; writing it here as well double-reports one mistake.
9640
+ outputError: () => {
9210
9641
  }
9211
9642
  });
9212
9643
  command.commands.forEach((child) => configureCommanderSuggestionOutput(child));
@@ -9279,6 +9710,7 @@ async function runCLI(roots, options = {}) {
9279
9710
  resolvedCommandPath = formatCliCommandPath(state.commandPath);
9280
9711
  await executeCommand(
9281
9712
  state,
9713
+ rootUsageName,
9282
9714
  servicesWithBuiltIns,
9283
9715
  requirementOptions,
9284
9716
  runtimeFetch,
@@ -11022,7 +11454,7 @@ var claudeCodeAgent = {
11022
11454
  id: "claude-code",
11023
11455
  name: "claude-code",
11024
11456
  label: "Claude Code",
11025
- summary: "Configure Claude Code to route through Poe.",
11457
+ summary: "Anthropic's agentic coding tool for the terminal.",
11026
11458
  aliases: ["claude"],
11027
11459
  binaryName: "claude",
11028
11460
  apiShapes: ["anthropic-messages"],
@@ -11032,6 +11464,7 @@ var claudeCodeAgent = {
11032
11464
  }
11033
11465
  },
11034
11466
  configPath: "~/.claude.json",
11467
+ capabilities: ["spawn", "configure", "install", "test", "skill", "mcp"],
11035
11468
  branding: {
11036
11469
  colors: {
11037
11470
  dark: "#C15F3C",
@@ -11052,6 +11485,7 @@ var claudeDesktopAgent = {
11052
11485
  linux: "~/.config/Claude/claude_desktop_config.json",
11053
11486
  win32: "~/AppData/Roaming/Claude/claude_desktop_config.json"
11054
11487
  },
11488
+ capabilities: ["mcp"],
11055
11489
  branding: {
11056
11490
  colors: {
11057
11491
  dark: "#D97757",
@@ -11065,7 +11499,7 @@ var codexAgent = {
11065
11499
  id: "codex",
11066
11500
  name: "codex",
11067
11501
  label: "Codex",
11068
- summary: "Configure Codex to use Poe as the model provider.",
11502
+ summary: "OpenAI's coding agent for the terminal.",
11069
11503
  binaryName: "codex",
11070
11504
  apiShapes: ["openai-responses"],
11071
11505
  otelCapture: {
@@ -11079,6 +11513,7 @@ var codexAgent = {
11079
11513
  ]
11080
11514
  },
11081
11515
  configPath: "~/.codex/config.toml",
11516
+ capabilities: ["spawn", "configure", "install", "test", "skill", "mcp"],
11082
11517
  branding: {
11083
11518
  colors: {
11084
11519
  dark: "#D5D9DF",
@@ -11096,6 +11531,7 @@ var cursorAgent = {
11096
11531
  summary: "Cursor's CLI coding agent.",
11097
11532
  binaryName: "cursor-agent",
11098
11533
  configPath: "~/.cursor/mcp.json",
11534
+ capabilities: ["spawn", "configure", "install", "test", "skill", "mcp"],
11099
11535
  branding: {
11100
11536
  colors: {
11101
11537
  dark: "#FFFFFF",
@@ -11110,10 +11546,11 @@ var geminiCliAgent = {
11110
11546
  name: "gemini-cli",
11111
11547
  aliases: ["gemini"],
11112
11548
  label: "Gemini CLI",
11113
- summary: "Configure Google's Gemini CLI to use a compatible Google generations API.",
11549
+ summary: "Google's open-source AI agent for the terminal.",
11114
11550
  binaryName: "gemini",
11115
11551
  configPath: "~/.gemini/settings.json",
11116
11552
  apiShapes: ["google-generations"],
11553
+ capabilities: ["spawn", "configure", "install", "test", "skill"],
11117
11554
  branding: {
11118
11555
  colors: {
11119
11556
  dark: "#8AB4F8",
@@ -11127,7 +11564,7 @@ var openCodeAgent = {
11127
11564
  id: "opencode",
11128
11565
  name: "opencode",
11129
11566
  label: "OpenCode CLI",
11130
- summary: "Configure OpenCode CLI to use the Poe API.",
11567
+ summary: "Open-source AI coding agent for the terminal.",
11131
11568
  binaryName: "opencode",
11132
11569
  apiShapes: ["openai-chat-completions"],
11133
11570
  otelCapture: {
@@ -11136,6 +11573,7 @@ var openCodeAgent = {
11136
11573
  }
11137
11574
  },
11138
11575
  configPath: "~/.config/opencode/opencode.json",
11576
+ capabilities: ["spawn", "configure", "install", "test", "skill", "mcp"],
11139
11577
  branding: {
11140
11578
  colors: {
11141
11579
  dark: "#4A4F55",
@@ -11149,11 +11587,12 @@ var kimiAgent = {
11149
11587
  id: "kimi",
11150
11588
  name: "kimi",
11151
11589
  label: "Kimi",
11152
- summary: "Configure Kimi CLI to use Poe API",
11590
+ summary: "Moonshot AI's coding agent for the terminal.",
11153
11591
  aliases: ["kimi-cli"],
11154
11592
  binaryName: "kimi",
11155
11593
  apiShapes: ["openai-chat-completions"],
11156
11594
  configPath: "~/.kimi/mcp.json",
11595
+ capabilities: ["spawn", "configure", "install", "test", "mcp"],
11157
11596
  branding: {
11158
11597
  colors: {
11159
11598
  dark: "#7B68EE",
@@ -11172,6 +11611,7 @@ var gooseAgent = {
11172
11611
  apiShapes: ["openai-chat-completions"],
11173
11612
  otelCapture: {},
11174
11613
  configPath: "~/.config/goose/config.yaml",
11614
+ capabilities: ["spawn", "configure", "install", "test", "skill", "mcp"],
11175
11615
  branding: {
11176
11616
  colors: {
11177
11617
  dark: "#FF6B35",
@@ -11180,6 +11620,23 @@ var gooseAgent = {
11180
11620
  }
11181
11621
  };
11182
11622
 
11623
+ // ../agent-defs/src/agents/pi.ts
11624
+ var piAgent = {
11625
+ id: "pi",
11626
+ name: "pi",
11627
+ aliases: ["pi-agent"],
11628
+ label: "Pi",
11629
+ summary: "Minimal AI coding agent for the terminal.",
11630
+ binaryName: "pi",
11631
+ capabilities: ["spawn"],
11632
+ branding: {
11633
+ colors: {
11634
+ dark: "#F2F2F2",
11635
+ light: "#242424"
11636
+ }
11637
+ }
11638
+ };
11639
+
11183
11640
  // ../agent-defs/src/agents/poe-agent.ts
11184
11641
  var poeAgentAgent = {
11185
11642
  id: "poe-agent",
@@ -11188,6 +11645,7 @@ var poeAgentAgent = {
11188
11645
  summary: "Run one-shot prompts with the built-in Poe agent runtime.",
11189
11646
  apiShapes: ["openai-responses", "openai-chat-completions"],
11190
11647
  configPath: "~/.poe-code/config.json",
11648
+ capabilities: ["configure"],
11191
11649
  branding: {
11192
11650
  colors: {
11193
11651
  dark: "#A465F7",
@@ -11204,6 +11662,9 @@ function freezeAgent(agent) {
11204
11662
  if (agent.apiShapes !== void 0) {
11205
11663
  Object.freeze(agent.apiShapes);
11206
11664
  }
11665
+ if (agent.capabilities !== void 0) {
11666
+ Object.freeze(agent.capabilities);
11667
+ }
11207
11668
  if (agent.otelCapture?.env !== void 0) {
11208
11669
  Object.freeze(agent.otelCapture.env);
11209
11670
  }
@@ -11223,6 +11684,7 @@ var allAgents = Object.freeze([
11223
11684
  freezeAgent(openCodeAgent),
11224
11685
  freezeAgent(kimiAgent),
11225
11686
  freezeAgent(gooseAgent),
11687
+ freezeAgent(piAgent),
11226
11688
  freezeAgent(poeAgentAgent)
11227
11689
  ]);
11228
11690
  var lookup2 = /* @__PURE__ */ new Map();
@@ -11266,7 +11728,8 @@ var agentSkillConfigs = {
11266
11728
  },
11267
11729
  goose: {
11268
11730
  globalSkillDir: "~/.agents/skills",
11269
- localSkillDir: ".agents/skills"
11731
+ localSkillDir: ".agents/skills",
11732
+ dirNote: "Goose discovers skills from the shared .agents/skills convention, not a goose-specific directory."
11270
11733
  }
11271
11734
  };
11272
11735
  var supportedAgents = Object.freeze(Object.keys(agentSkillConfigs));
@@ -12640,6 +13103,16 @@ async function executeMutation(mutation, context, options) {
12640
13103
  }
12641
13104
  }
12642
13105
 
13106
+ // ../user-error/src/index.ts
13107
+ var UserError2 = class extends Error {
13108
+ hint;
13109
+ constructor(message2, options) {
13110
+ super(message2, options);
13111
+ this.name = "UserError";
13112
+ this.hint = options?.hint;
13113
+ }
13114
+ };
13115
+
12643
13116
  // ../agent-skill-config/src/error-codes.ts
12644
13117
  function hasOwnErrorCode4(error3, code) {
12645
13118
  return error3 instanceof Error && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === code;
@@ -12691,8 +13164,11 @@ async function installSkill(agentId, skill, options) {
12691
13164
  const skillFilePath = `${skillFolderPath}/SKILL.md`;
12692
13165
  const displayPath = `${scope === "global" ? config2.globalSkillDir : config2.localSkillDir}/${skill.name}/SKILL.md`;
12693
13166
  const absoluteSkillPath = `${scope === "global" ? options.homeDir : options.cwd}/${skillFilePath.slice(2)}`;
12694
- if (await pathExists2(options.fs, absoluteSkillPath)) {
12695
- throw new Error(`Skill already exists: ${displayPath}`);
13167
+ if (!options.force && await pathExists2(options.fs, absoluteSkillPath)) {
13168
+ throw new UserError2(
13169
+ `Skill already exists: ${displayPath}
13170
+ Re-run with --force to overwrite it, or remove it first.`
13171
+ );
12696
13172
  }
12697
13173
  await runMutations(
12698
13174
  [
@@ -14770,13 +15246,78 @@ function sleep2(ms) {
14770
15246
  // src/cli.ts
14771
15247
  configureTheme({ brand: "green", label: "Terminal Pilot" });
14772
15248
  function getBundledPackageVersion() {
14773
- return true ? "0.0.47" : void 0;
14774
- }
15249
+ return true ? "0.0.49" : void 0;
15250
+ }
15251
+ var pilotOptionsWithValues = /* @__PURE__ */ new Set([
15252
+ "--session",
15253
+ "-s",
15254
+ "--cwd",
15255
+ "--cols",
15256
+ "--rows",
15257
+ "--timeout",
15258
+ "-t",
15259
+ "--last",
15260
+ "-n",
15261
+ "--output",
15262
+ "-o",
15263
+ "--scope",
15264
+ "--padding",
15265
+ "-p",
15266
+ "--log-level",
15267
+ "--preset",
15268
+ "--signal"
15269
+ ]);
14775
15270
  function normalizeArgv(argv) {
14776
- if (argv.includes("--json") && !argv.some((argument) => argument === "--output" || argument.startsWith("--output="))) {
14777
- return argv.flatMap((argument) => argument === "--json" ? ["--output", "json"] : [argument]);
15271
+ if (!argv.includes("--json")) {
15272
+ return argv;
15273
+ }
15274
+ if (argv.some((argument) => argument === "--output" || argument.startsWith("--output="))) {
15275
+ return argv;
15276
+ }
15277
+ const normalized = [];
15278
+ let index = 0;
15279
+ let bareTokenCount = 0;
15280
+ let expectOptionValue = false;
15281
+ while (index < argv.length) {
15282
+ const token = argv[index];
15283
+ if (index < 2) {
15284
+ normalized.push(token);
15285
+ index += 1;
15286
+ continue;
15287
+ }
15288
+ if (token === "--") {
15289
+ normalized.push(token, ...argv.slice(index + 1));
15290
+ break;
15291
+ }
15292
+ if (expectOptionValue) {
15293
+ normalized.push(token);
15294
+ expectOptionValue = false;
15295
+ index += 1;
15296
+ continue;
15297
+ }
15298
+ if (token === "--json") {
15299
+ normalized.push("--output", "json");
15300
+ index += 1;
15301
+ continue;
15302
+ }
15303
+ if (token.startsWith("-") && token !== "-") {
15304
+ normalized.push(token);
15305
+ const optionName = token.includes("=") ? token.slice(0, token.indexOf("=")) : token;
15306
+ if (!token.includes("=") && (pilotOptionsWithValues.has(optionName) || optionName === "--debug" && argv[index + 1] !== void 0 && !argv[index + 1].startsWith("-"))) {
15307
+ expectOptionValue = true;
15308
+ }
15309
+ index += 1;
15310
+ continue;
15311
+ }
15312
+ bareTokenCount += 1;
15313
+ if (bareTokenCount >= 2) {
15314
+ normalized.push(...argv.slice(index));
15315
+ break;
15316
+ }
15317
+ normalized.push(token);
15318
+ index += 1;
14778
15319
  }
14779
- return argv;
15320
+ return normalized;
14780
15321
  }
14781
15322
  async function main(argv = process.argv, options = {}) {
14782
15323
  if (isTerminalPilotDaemonArgv(argv)) {
@@ -14823,6 +15364,7 @@ if (await isDirectExecution(process.argv)) {
14823
15364
  await main();
14824
15365
  }
14825
15366
  export {
14826
- main
15367
+ main,
15368
+ normalizeArgv
14827
15369
  };
14828
15370
  //# sourceMappingURL=cli.js.map