@outfitter/cli 0.1.0-rc.2 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (250) hide show
  1. package/README.md +21 -32
  2. package/dist/actions.d.ts +12 -1
  3. package/dist/actions.js +170 -3
  4. package/dist/borders/index.d.ts +3 -0
  5. package/dist/borders/index.js +13 -0
  6. package/dist/box/index.d.ts +4 -0
  7. package/dist/box/index.js +13 -0
  8. package/dist/cli.js +1 -1
  9. package/dist/colors/index.d.ts +3 -0
  10. package/dist/colors/index.js +18 -0
  11. package/dist/command.d.ts +40 -3
  12. package/dist/command.js +45 -3
  13. package/dist/demo/index.d.ts +78 -0
  14. package/dist/demo/index.js +148 -0
  15. package/dist/demo/registry.d.ts +7 -0
  16. package/dist/demo/registry.js +28 -0
  17. package/dist/demo/renderers/borders.d.ts +7 -0
  18. package/dist/demo/renderers/borders.js +17 -0
  19. package/dist/demo/renderers/box.d.ts +7 -0
  20. package/dist/demo/renderers/box.js +18 -0
  21. package/dist/demo/renderers/colors.d.ts +7 -0
  22. package/dist/demo/renderers/colors.js +18 -0
  23. package/dist/demo/renderers/indicators.d.ts +7 -0
  24. package/dist/demo/renderers/indicators.js +17 -0
  25. package/dist/demo/renderers/list.d.ts +7 -0
  26. package/dist/demo/renderers/list.js +19 -0
  27. package/dist/demo/renderers/markdown.d.ts +7 -0
  28. package/dist/demo/renderers/markdown.js +18 -0
  29. package/dist/demo/renderers/progress.d.ts +7 -0
  30. package/dist/demo/renderers/progress.js +17 -0
  31. package/dist/demo/renderers/spinner.d.ts +7 -0
  32. package/dist/demo/renderers/spinner.js +19 -0
  33. package/dist/demo/renderers/table.d.ts +7 -0
  34. package/dist/demo/renderers/table.js +19 -0
  35. package/dist/demo/renderers/text.d.ts +7 -0
  36. package/dist/demo/renderers/text.js +16 -0
  37. package/dist/demo/renderers/tree.d.ts +7 -0
  38. package/dist/demo/renderers/tree.js +18 -0
  39. package/dist/demo/section.d.ts +5 -0
  40. package/dist/demo/section.js +23 -0
  41. package/dist/demo/templates.d.ts +4 -0
  42. package/dist/demo/templates.js +10 -0
  43. package/dist/demo/types.d.ts +3 -0
  44. package/dist/demo/types.js +8 -0
  45. package/dist/index.d.ts +5 -8
  46. package/dist/index.js +9 -43
  47. package/dist/input.d.ts +163 -2
  48. package/dist/input.js +425 -11
  49. package/dist/list/index.d.ts +3 -0
  50. package/dist/list/index.js +9 -0
  51. package/dist/output.js +1 -1
  52. package/dist/pagination.d.ts +62 -2
  53. package/dist/pagination.js +84 -6
  54. package/dist/preset/full.d.ts +14 -0
  55. package/dist/preset/full.js +41 -0
  56. package/dist/preset/standard.d.ts +11 -0
  57. package/dist/preset/standard.js +30 -0
  58. package/dist/prompt/confirm.d.ts +4 -0
  59. package/dist/prompt/confirm.js +9 -0
  60. package/dist/prompt/group.d.ts +4 -0
  61. package/dist/prompt/group.js +9 -0
  62. package/dist/prompt/index.d.ts +7 -0
  63. package/dist/prompt/index.js +32 -0
  64. package/dist/prompt/select.d.ts +4 -0
  65. package/dist/prompt/select.js +11 -0
  66. package/dist/prompt/text.d.ts +4 -0
  67. package/dist/prompt/text.js +11 -0
  68. package/dist/prompt/types.d.ts +3 -0
  69. package/dist/prompt/types.js +8 -0
  70. package/dist/prompt/validators.d.ts +2 -0
  71. package/dist/prompt/validators.js +8 -0
  72. package/dist/render/borders.d.ts +2 -0
  73. package/dist/render/borders.js +15 -0
  74. package/dist/render/box.d.ts +3 -0
  75. package/dist/render/box.js +23 -0
  76. package/dist/render/colors.d.ts +1 -1
  77. package/dist/render/colors.js +6 -3
  78. package/dist/render/date.js +1 -1
  79. package/dist/render/format-relative.js +1 -1
  80. package/dist/render/format.js +1 -1
  81. package/dist/render/heading.d.ts +3 -0
  82. package/dist/render/heading.js +14 -0
  83. package/dist/render/index.d.ts +26 -7
  84. package/dist/render/index.js +160 -26
  85. package/dist/render/indicators.d.ts +2 -0
  86. package/dist/render/indicators.js +14 -0
  87. package/dist/render/json.js +1 -1
  88. package/dist/render/layout.d.ts +5 -0
  89. package/dist/render/layout.js +25 -0
  90. package/dist/render/list.d.ts +2 -2
  91. package/dist/render/list.js +2 -2
  92. package/dist/render/markdown.js +4 -4
  93. package/dist/render/progress.js +1 -1
  94. package/dist/render/separator.d.ts +3 -0
  95. package/dist/render/separator.js +14 -0
  96. package/dist/render/shapes.js +10 -9
  97. package/dist/render/spinner.d.ts +2 -0
  98. package/dist/render/spinner.js +12 -0
  99. package/dist/render/stack.d.ts +3 -0
  100. package/dist/render/stack.js +38 -0
  101. package/dist/render/table.d.ts +2 -1
  102. package/dist/render/table.js +6 -5
  103. package/dist/render/text.d.ts +1 -1
  104. package/dist/render/text.js +7 -4
  105. package/dist/render/tree.d.ts +2 -2
  106. package/dist/render/tree.js +5 -3
  107. package/dist/render/types.d.ts +2 -0
  108. package/dist/render/types.js +1 -0
  109. package/dist/shared/@outfitter/cli-0ggcy7fa.js +20 -0
  110. package/dist/shared/@outfitter/cli-0psys2vm.js +7 -0
  111. package/dist/shared/@outfitter/cli-1bghjef6.js +352 -0
  112. package/dist/shared/@outfitter/cli-1kwbnt86.d.ts +45 -0
  113. package/dist/shared/@outfitter/cli-2g8bx1aq.d.ts +50 -0
  114. package/dist/shared/@outfitter/cli-34fqr7bp.js +37 -0
  115. package/dist/shared/@outfitter/cli-3b7ed3rm.d.ts +97 -0
  116. package/dist/shared/@outfitter/cli-3dxmmy4c.d.ts +20 -0
  117. package/dist/shared/@outfitter/cli-3f12z5kf.d.ts +83 -0
  118. package/dist/shared/@outfitter/cli-3t2zaenc.d.ts +59 -0
  119. package/dist/shared/@outfitter/{cli-dds0qqvm.d.ts → cli-4cb5g831.d.ts} +2 -0
  120. package/dist/shared/@outfitter/cli-4w2a1rfy.d.ts +23 -0
  121. package/dist/shared/@outfitter/cli-4x6pqnez.js +20 -0
  122. package/dist/shared/@outfitter/cli-671sxkhj.js +146 -0
  123. package/dist/shared/@outfitter/cli-6bztk73z.d.ts +51 -0
  124. package/dist/shared/@outfitter/cli-6fxffp8k.js +1 -0
  125. package/dist/shared/@outfitter/cli-6j9qynm8.js +118 -0
  126. package/dist/shared/@outfitter/cli-6m988kh0.d.ts +61 -0
  127. package/dist/shared/@outfitter/cli-74ba31gz.js +134 -0
  128. package/dist/shared/@outfitter/cli-7gnrb8cr.js +214 -0
  129. package/dist/shared/@outfitter/cli-7nm6edvh.d.ts +17 -0
  130. package/dist/shared/@outfitter/cli-85fg2vr5.js +123 -0
  131. package/dist/shared/@outfitter/cli-8a8xrzhy.js +20 -0
  132. package/dist/shared/@outfitter/cli-8bwaw3pz.js +7 -0
  133. package/dist/shared/@outfitter/cli-8rx4g3s5.d.ts +41 -0
  134. package/dist/shared/@outfitter/cli-8xsmsbbd.d.ts +223 -0
  135. package/dist/shared/@outfitter/cli-96b2p4td.d.ts +56 -0
  136. package/dist/shared/@outfitter/cli-9khk3cbq.d.ts +190 -0
  137. package/dist/shared/@outfitter/cli-9mtjjykw.js +67 -0
  138. package/dist/shared/@outfitter/{cli-ag0w4pk0.js → cli-9nbyj2bt.js} +60 -21
  139. package/dist/shared/@outfitter/{cli-azzk8a1d.js → cli-afhjqmg3.js} +7 -3
  140. package/dist/shared/@outfitter/cli-an9j0h80.js +117 -0
  141. package/dist/shared/@outfitter/cli-ay411nbr.js +122 -0
  142. package/dist/shared/@outfitter/cli-b0tzqgnf.d.ts +132 -0
  143. package/dist/shared/@outfitter/cli-b5c2k0d7.js +39 -0
  144. package/dist/shared/@outfitter/cli-b5epywry.js +1 -0
  145. package/dist/shared/@outfitter/cli-bcmcaz1b.js +23 -0
  146. package/dist/shared/@outfitter/cli-bf3vma4q.js +61 -0
  147. package/dist/shared/@outfitter/cli-cf1xexgn.d.ts +53 -0
  148. package/dist/shared/@outfitter/cli-cs45xd6q.js +59 -0
  149. package/dist/shared/@outfitter/cli-d7jpshq5.d.ts +128 -0
  150. package/dist/shared/@outfitter/{cli-jbj78ac5.js → cli-d9ad0rqj.js} +6 -1
  151. package/dist/shared/@outfitter/cli-daw296mv.js +61 -0
  152. package/dist/shared/@outfitter/cli-e5ms1y0x.d.ts +91 -0
  153. package/dist/shared/@outfitter/cli-e73v3qqy.d.ts +93 -0
  154. package/dist/shared/@outfitter/cli-en6zn6sj.js +1 -0
  155. package/dist/shared/@outfitter/cli-ep2cvtk8.js +48 -0
  156. package/dist/shared/@outfitter/cli-f75h8e94.js +7 -0
  157. package/dist/shared/@outfitter/cli-fakncnjp.d.ts +106 -0
  158. package/dist/shared/@outfitter/cli-feb5j90n.js +94 -0
  159. package/dist/shared/@outfitter/cli-h20jc0bs.d.ts +66 -0
  160. package/dist/shared/@outfitter/cli-hnpbqmc8.d.ts +328 -0
  161. package/dist/shared/@outfitter/cli-j4n8gaf3.js +95 -0
  162. package/dist/shared/@outfitter/cli-jejfypgf.js +85 -0
  163. package/dist/shared/@outfitter/{cli-wqc652mx.js → cli-jhcdwvpn.js} +8 -8
  164. package/dist/shared/@outfitter/{cli-v9mjsvjh.js → cli-jjemfdta.js} +13 -46
  165. package/dist/shared/@outfitter/cli-kc84wmch.js +267 -0
  166. package/dist/shared/@outfitter/cli-ktqme80d.js +7 -0
  167. package/dist/shared/@outfitter/cli-mq0jp15z.js +1 -0
  168. package/dist/shared/@outfitter/cli-mymyavvj.d.ts +26 -0
  169. package/dist/shared/@outfitter/cli-n17gt1dz.js +19 -0
  170. package/dist/shared/@outfitter/cli-n9dbh0hp.js +51 -0
  171. package/dist/shared/@outfitter/cli-nvvc92c8.js +128 -0
  172. package/dist/shared/@outfitter/cli-p1m5dhrs.js +169 -0
  173. package/dist/shared/@outfitter/cli-p38sfxyk.js +25 -0
  174. package/dist/shared/@outfitter/cli-p3dqm1vd.js +22 -0
  175. package/dist/shared/@outfitter/cli-p9j1phge.js +20 -0
  176. package/dist/shared/@outfitter/cli-pkxmzavm.js +62 -0
  177. package/dist/shared/@outfitter/cli-q8r6jarq.d.ts +24 -0
  178. package/dist/shared/@outfitter/{cli-2y3kxew8.d.ts → cli-qj83y5wj.d.ts} +22 -9
  179. package/dist/shared/@outfitter/cli-qjfc3j11.d.ts +112 -0
  180. package/dist/shared/@outfitter/cli-qp4cbhqr.js +70 -0
  181. package/dist/shared/@outfitter/cli-s0kkx9m1.d.ts +164 -0
  182. package/dist/shared/@outfitter/cli-snxj55n6.js +43 -0
  183. package/dist/shared/@outfitter/cli-swwxvjvm.d.ts +24 -0
  184. package/dist/shared/@outfitter/cli-sx67mmfx.d.ts +98 -0
  185. package/dist/shared/@outfitter/cli-tarpsa8a.js +30 -0
  186. package/dist/shared/@outfitter/cli-thvzhjd1.js +126 -0
  187. package/dist/shared/@outfitter/cli-tqewy503.d.ts +36 -0
  188. package/dist/shared/@outfitter/cli-tvw1xrdj.js +20 -0
  189. package/dist/shared/@outfitter/cli-v1tzwxkt.js +32 -0
  190. package/dist/shared/@outfitter/cli-vd60dj65.js +1 -0
  191. package/dist/shared/@outfitter/cli-vp88gxev.js +279 -0
  192. package/dist/shared/@outfitter/cli-vstbkzky.d.ts +74 -0
  193. package/dist/shared/@outfitter/cli-vtg0sqk2.d.ts +54 -0
  194. package/dist/shared/@outfitter/cli-w5y3xepp.js +20 -0
  195. package/dist/shared/@outfitter/cli-x4cavvc0.js +1 -0
  196. package/dist/shared/@outfitter/cli-xep6v2c0.js +52 -0
  197. package/dist/shared/@outfitter/cli-xg5y5fhk.js +86 -0
  198. package/dist/shared/@outfitter/{cli-n51t773m.d.ts → cli-xsaheemc.d.ts} +44 -4
  199. package/dist/shared/@outfitter/cli-xvqtqjxk.js +82 -0
  200. package/dist/shared/@outfitter/cli-y25tt8nc.d.ts +48 -0
  201. package/dist/streaming/ansi.d.ts +2 -0
  202. package/dist/streaming/ansi.js +8 -0
  203. package/dist/streaming/index.d.ts +4 -0
  204. package/dist/streaming/index.js +17 -0
  205. package/dist/streaming/spinner.d.ts +3 -0
  206. package/dist/streaming/spinner.js +10 -0
  207. package/dist/streaming/writer.d.ts +2 -0
  208. package/dist/streaming/writer.js +9 -0
  209. package/dist/table/index.d.ts +4 -0
  210. package/dist/table/index.js +13 -0
  211. package/dist/terminal/detection.js +5 -2
  212. package/dist/terminal/index.js +6 -2
  213. package/dist/theme/context.d.ts +9 -0
  214. package/dist/theme/context.js +14 -0
  215. package/dist/theme/create.d.ts +8 -0
  216. package/dist/theme/create.js +12 -0
  217. package/dist/theme/index.d.ts +17 -0
  218. package/dist/theme/index.js +42 -0
  219. package/dist/theme/presets/bold.d.ts +8 -0
  220. package/dist/theme/presets/bold.js +12 -0
  221. package/dist/theme/presets/default.d.ts +8 -0
  222. package/dist/theme/presets/default.js +11 -0
  223. package/dist/theme/presets/index.d.ts +12 -0
  224. package/dist/theme/presets/index.js +24 -0
  225. package/dist/theme/presets/minimal.d.ts +8 -0
  226. package/dist/theme/presets/minimal.js +12 -0
  227. package/dist/theme/presets/rounded.d.ts +8 -0
  228. package/dist/theme/presets/rounded.js +12 -0
  229. package/dist/theme/resolve.d.ts +8 -0
  230. package/dist/theme/resolve.js +11 -0
  231. package/dist/theme/types.d.ts +7 -0
  232. package/dist/theme/types.js +1 -0
  233. package/dist/tree/index.d.ts +3 -0
  234. package/dist/tree/index.js +11 -0
  235. package/dist/types.js +1 -1
  236. package/package.json +168 -54
  237. package/dist/shared/@outfitter/cli-2vs2gxa8.js +0 -429
  238. package/dist/shared/@outfitter/cli-2yq94zst.d.ts +0 -39
  239. package/dist/shared/@outfitter/cli-6xc869x1.js +0 -26
  240. package/dist/shared/@outfitter/cli-7km1e58p.js +0 -85
  241. package/dist/shared/@outfitter/cli-8r0bnyyx.js +0 -43
  242. package/dist/shared/@outfitter/cli-afecwfrn.d.ts +0 -13
  243. package/dist/shared/@outfitter/cli-bt423m6y.js +0 -4
  244. package/dist/shared/@outfitter/cli-d4fegbad.d.ts +0 -66
  245. package/dist/shared/@outfitter/cli-e0ecw3x1.js +0 -64
  246. package/dist/shared/@outfitter/cli-fheaaa6b.js +0 -25
  247. package/dist/shared/@outfitter/cli-j361wp3g.d.ts +0 -41
  248. package/dist/shared/@outfitter/cli-p0m2fc51.js +0 -172
  249. package/dist/shared/@outfitter/cli-tyajr8qa.d.ts +0 -63
  250. package/dist/shared/@outfitter/cli-zs6jy1am.d.ts +0 -164
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Indicator primitives for CLI output.
3
+ *
4
+ * Provides status symbols, selection indicators, list bullets, and progress
5
+ * markers with unicode and ASCII fallback support.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ /**
10
+ * Categories of indicators available.
11
+ */
12
+ type IndicatorCategory = "status" | "marker" | "progress" | "triangle" | "special" | "directional" | "math";
13
+ /**
14
+ * An indicator with unicode and fallback representations.
15
+ */
16
+ interface IndicatorSet {
17
+ /** Unicode character for modern terminals */
18
+ unicode: string;
19
+ /** ASCII fallback for limited terminals */
20
+ fallback: string;
21
+ /** Optional semantic color name */
22
+ color?: string;
23
+ }
24
+ /**
25
+ * All available indicators organized by category.
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * import { INDICATORS, getIndicator } from "@outfitter/cli/render";
30
+ *
31
+ * // Access directly
32
+ * console.log(INDICATORS.status.success.unicode); // "✔"
33
+ *
34
+ * // Or use helper
35
+ * console.log(getIndicator("status", "success")); // "✔" or "[ok]"
36
+ * ```
37
+ */
38
+ declare const INDICATORS: Record<IndicatorCategory, Record<string, IndicatorSet>>;
39
+ /**
40
+ * Detects if the terminal supports Unicode characters.
41
+ *
42
+ * Checks for:
43
+ * - CI environments (usually support unicode)
44
+ * - Windows Terminal / ConEmu
45
+ * - TERM containing xterm/vt100
46
+ * - Locale settings
47
+ *
48
+ * @returns true if unicode is likely supported
49
+ */
50
+ declare function isUnicodeSupported(): boolean;
51
+ /**
52
+ * Gets an indicator character with automatic unicode/fallback selection.
53
+ *
54
+ * @param category - The indicator category
55
+ * @param name - The indicator name within the category
56
+ * @param forceUnicode - Override unicode detection (useful for testing)
57
+ * @returns The appropriate character for the current terminal
58
+ *
59
+ * @example
60
+ * ```typescript
61
+ * // Automatic detection
62
+ * console.log(getIndicator("status", "success"));
63
+ *
64
+ * // Force unicode
65
+ * console.log(getIndicator("status", "success", true)); // "✔"
66
+ *
67
+ * // Force fallback
68
+ * console.log(getIndicator("status", "success", false)); // "[ok]"
69
+ * ```
70
+ */
71
+ declare function getIndicator(category: IndicatorCategory, name: string, forceUnicode?: boolean): string;
72
+ /**
73
+ * Progress indicator styles.
74
+ */
75
+ type ProgressStyle = "circle" | "vertical" | "horizontal" | "shade";
76
+ /**
77
+ * Gets a progress indicator based on current/max values.
78
+ *
79
+ * @param style - The progress style (circle, vertical, horizontal, shade)
80
+ * @param current - Current progress value
81
+ * @param max - Maximum progress value
82
+ * @param forceUnicode - Override unicode detection
83
+ * @returns The appropriate progress indicator character
84
+ *
85
+ * @example
86
+ * ```typescript
87
+ * // Circle progress at 50%
88
+ * getProgressIndicator("circle", 50, 100); // "◑"
89
+ *
90
+ * // Vertical block at 75%
91
+ * getProgressIndicator("vertical", 6, 8); // "▆"
92
+ *
93
+ * // Horizontal bar at 100%
94
+ * getProgressIndicator("horizontal", 1, 1); // "█"
95
+ * ```
96
+ */
97
+ declare function getProgressIndicator(style: ProgressStyle, current: number, max: number, forceUnicode?: boolean): string;
98
+ export { IndicatorCategory, IndicatorSet, INDICATORS, isUnicodeSupported, getIndicator, ProgressStyle, getProgressIndicator };
@@ -0,0 +1,30 @@
1
+ // @bun
2
+ import {
3
+ defaultTheme
4
+ } from "./cli-cs45xd6q.js";
5
+ import {
6
+ BORDERS,
7
+ init_borders
8
+ } from "./cli-85fg2vr5.js";
9
+
10
+ // packages/cli/src/theme/presets/minimal.ts
11
+ init_borders();
12
+ var minimalTheme = {
13
+ ...defaultTheme,
14
+ name: "minimal",
15
+ border: "ascii",
16
+ borderChars: BORDERS.ascii,
17
+ treeGuide: "single",
18
+ delimiter: "bullet",
19
+ markers: {
20
+ ...defaultTheme.markers
21
+ },
22
+ listBullet: { unicode: "-", fallback: "-" },
23
+ checkbox: {
24
+ checked: { unicode: "[x]", fallback: "[x]" },
25
+ unchecked: { unicode: "[ ]", fallback: "[ ]" }
26
+ },
27
+ spinner: "line"
28
+ };
29
+
30
+ export { minimalTheme };
@@ -0,0 +1,126 @@
1
+ // @bun
2
+ import {
3
+ renderList
4
+ } from "./cli-xg5y5fhk.js";
5
+ import {
6
+ LIST_STYLE_META,
7
+ getListStyles
8
+ } from "./cli-kc84wmch.js";
9
+ import {
10
+ getExample
11
+ } from "./cli-xep6v2c0.js";
12
+ import {
13
+ demoSection
14
+ } from "./cli-34fqr7bp.js";
15
+
16
+ // packages/cli/src/demo/renderers/list.ts
17
+ function renderListDemo(config, theme) {
18
+ const showCode = config.showCode ?? true;
19
+ const showDescriptions = config.showDescriptions ?? true;
20
+ const lines = [];
21
+ lines.push(demoSection("List Styles"));
22
+ lines.push("");
23
+ if (showCode) {
24
+ lines.push('import { renderList } from "@outfitter/cli/render";');
25
+ lines.push("");
26
+ }
27
+ const items = getExample("listItems", config.examples);
28
+ const styles = getListStyles();
29
+ for (const style of styles) {
30
+ const meta = LIST_STYLE_META[style];
31
+ lines.push(`${meta.label.toUpperCase()} STYLE`);
32
+ if (showDescriptions) {
33
+ lines.push(theme.muted(meta.description));
34
+ }
35
+ lines.push("");
36
+ if (showCode) {
37
+ lines.push(`renderList(items, { style: "${style}" })`);
38
+ lines.push("");
39
+ }
40
+ if (style === "checkbox") {
41
+ const output = renderList(items, {
42
+ style,
43
+ checked: new Set([1])
44
+ });
45
+ lines.push(output);
46
+ } else {
47
+ const output = renderList(items, { style });
48
+ lines.push(output);
49
+ }
50
+ lines.push("");
51
+ }
52
+ lines.push(demoSection("Nested Lists"));
53
+ lines.push("");
54
+ const nestedItems = [
55
+ "Top level item",
56
+ {
57
+ text: "Parent with children",
58
+ children: ["Child one", "Child two"]
59
+ },
60
+ "Another top level"
61
+ ];
62
+ if (showCode) {
63
+ lines.push("renderList([");
64
+ lines.push(' "Top level item",');
65
+ lines.push(' { text: "Parent with children", children: ["Child one", "Child two"] },');
66
+ lines.push(' "Another top level",');
67
+ lines.push("])");
68
+ lines.push("");
69
+ }
70
+ lines.push(renderList(nestedItems));
71
+ lines.push("");
72
+ lines.push(demoSection("Numbered with Nesting"));
73
+ lines.push("");
74
+ const numberedNested = [
75
+ {
76
+ text: "First section",
77
+ children: [
78
+ {
79
+ text: "Subsection A",
80
+ children: ["Detail i", "Detail ii"]
81
+ },
82
+ "Subsection B"
83
+ ]
84
+ },
85
+ "Second section"
86
+ ];
87
+ if (showCode) {
88
+ lines.push('renderList(items, { style: "number" })');
89
+ lines.push("");
90
+ }
91
+ lines.push(renderList(numberedNested, { style: "number" }));
92
+ lines.push("");
93
+ lines.push(demoSection("Mixed Styles"));
94
+ lines.push("");
95
+ if (showDescriptions) {
96
+ lines.push(theme.muted("Use childStyle to override style for children"));
97
+ lines.push("");
98
+ }
99
+ const mixedItems = [
100
+ {
101
+ text: "Requirements",
102
+ childStyle: "bullet",
103
+ children: ["Must be fast", "Must be reliable"]
104
+ },
105
+ {
106
+ text: "Tasks",
107
+ childStyle: "checkbox",
108
+ children: [
109
+ { text: "Write tests", checked: true },
110
+ { text: "Deploy to prod", checked: false }
111
+ ]
112
+ }
113
+ ];
114
+ if (showCode) {
115
+ lines.push("renderList([");
116
+ lines.push(' { text: "Requirements", childStyle: "bullet", children: [...] },');
117
+ lines.push(' { text: "Tasks", childStyle: "checkbox", children: [...] },');
118
+ lines.push('], { style: "number" })');
119
+ lines.push("");
120
+ }
121
+ lines.push(renderList(mixedItems, { style: "number" }));
122
+ return lines.join(`
123
+ `);
124
+ }
125
+
126
+ export { renderListDemo };
@@ -0,0 +1,36 @@
1
+ import { CancelledError, PromptResult } from "./cli-3f12z5kf";
2
+ import { Result } from "better-result";
3
+ /**
4
+ * A step in a prompt group.
5
+ */
6
+ type PromptStep<T> = () => PromptResult<T>;
7
+ /**
8
+ * Collects multiple prompts into a single result object.
9
+ *
10
+ * If any prompt is cancelled, the entire group fails with CancelledError.
11
+ *
12
+ * @param steps - Object of named prompt steps
13
+ * @returns Ok with collected values or Err with CancelledError
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * import { promptGroup, promptText, promptSelect } from "@outfitter/cli/prompt";
18
+ *
19
+ * const result = await promptGroup({
20
+ * name: () => promptText({ message: "Name:" }),
21
+ * role: () => promptSelect({
22
+ * message: "Role:",
23
+ * options: [
24
+ * { value: "admin", label: "Admin" },
25
+ * { value: "user", label: "User" },
26
+ * ],
27
+ * }),
28
+ * });
29
+ *
30
+ * if (result.isOk()) {
31
+ * console.log(`Creating ${result.value.role}: ${result.value.name}`);
32
+ * }
33
+ * ```
34
+ */
35
+ declare function promptGroup<T extends Record<string, unknown>>(steps: { [K in keyof T] : PromptStep<T[K]> }): Promise<Result<T, CancelledError>>;
36
+ export { PromptStep, promptGroup };
@@ -0,0 +1,20 @@
1
+ // @bun
2
+ // packages/cli/src/demo/types.ts
3
+ function isPrimitiveId(value) {
4
+ const validIds = [
5
+ "colors",
6
+ "borders",
7
+ "spinner",
8
+ "list",
9
+ "box",
10
+ "table",
11
+ "progress",
12
+ "tree",
13
+ "text",
14
+ "markdown",
15
+ "indicators"
16
+ ];
17
+ return validIds.includes(value);
18
+ }
19
+
20
+ export { isPrimitiveId };
@@ -0,0 +1,32 @@
1
+ // @bun
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __moduleCache = /* @__PURE__ */ new WeakMap;
7
+ var __toCommonJS = (from) => {
8
+ var entry = __moduleCache.get(from), desc;
9
+ if (entry)
10
+ return entry;
11
+ entry = __defProp({}, "__esModule", { value: true });
12
+ if (from && typeof from === "object" || typeof from === "function")
13
+ __getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
14
+ get: () => from[key],
15
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
16
+ }));
17
+ __moduleCache.set(from, entry);
18
+ return entry;
19
+ };
20
+ var __export = (target, all) => {
21
+ for (var name in all)
22
+ __defProp(target, name, {
23
+ get: all[name],
24
+ enumerable: true,
25
+ configurable: true,
26
+ set: (newValue) => all[name] = () => newValue
27
+ });
28
+ };
29
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
30
+ var __require = import.meta.require;
31
+
32
+ export { __toCommonJS, __export, __esm, __require };
@@ -0,0 +1 @@
1
+ // @bun
@@ -0,0 +1,279 @@
1
+ // @bun
2
+ import {
3
+ getStringWidth,
4
+ init_text,
5
+ truncateText,
6
+ wrapText
7
+ } from "./cli-jjemfdta.js";
8
+ import {
9
+ getBorderCharacters,
10
+ init_borders
11
+ } from "./cli-85fg2vr5.js";
12
+ import {
13
+ __esm,
14
+ __export
15
+ } from "./cli-v1tzwxkt.js";
16
+
17
+ // packages/cli/src/render/box.ts
18
+ var exports_box = {};
19
+ __export(exports_box, {
20
+ renderBox: () => renderBox,
21
+ normalizePadding: () => normalizePadding,
22
+ normalizeMargin: () => normalizeMargin,
23
+ normalizeBorders: () => normalizeBorders,
24
+ createBox: () => createBox
25
+ });
26
+ function alignLine(line, width, align) {
27
+ const lineWidth = getStringWidth(line);
28
+ const padding = width - lineWidth;
29
+ if (padding <= 0) {
30
+ return line;
31
+ }
32
+ switch (align) {
33
+ case "center": {
34
+ const leftPad = Math.floor(padding / 2);
35
+ const rightPad = padding - leftPad;
36
+ return " ".repeat(leftPad) + line + " ".repeat(rightPad);
37
+ }
38
+ case "right":
39
+ return " ".repeat(padding) + line;
40
+ default:
41
+ return line + " ".repeat(padding);
42
+ }
43
+ }
44
+ function normalizePadding(padding, defaultValue) {
45
+ if (padding === undefined) {
46
+ return { top: 0, right: defaultValue, bottom: 0, left: defaultValue };
47
+ }
48
+ if (typeof padding === "number") {
49
+ return { top: 0, right: padding, bottom: 0, left: padding };
50
+ }
51
+ return {
52
+ top: padding.top ?? 0,
53
+ right: padding.right ?? defaultValue,
54
+ bottom: padding.bottom ?? 0,
55
+ left: padding.left ?? defaultValue
56
+ };
57
+ }
58
+ function normalizeMargin(margin, defaultValue) {
59
+ if (margin === undefined) {
60
+ return {
61
+ top: defaultValue,
62
+ right: defaultValue,
63
+ bottom: defaultValue,
64
+ left: defaultValue
65
+ };
66
+ }
67
+ if (typeof margin === "number") {
68
+ return { top: margin, right: margin, bottom: margin, left: margin };
69
+ }
70
+ return {
71
+ top: margin.top ?? defaultValue,
72
+ right: margin.right ?? defaultValue,
73
+ bottom: margin.bottom ?? defaultValue,
74
+ left: margin.left ?? defaultValue
75
+ };
76
+ }
77
+ function normalizeBorders(borders) {
78
+ if (borders === undefined) {
79
+ return { top: true, right: true, bottom: true, left: true };
80
+ }
81
+ return {
82
+ top: borders.top ?? true,
83
+ right: borders.right ?? true,
84
+ bottom: borders.bottom ?? true,
85
+ left: borders.left ?? true
86
+ };
87
+ }
88
+ function renderBox(content, options) {
89
+ const border = options?.border ?? "single";
90
+ const title = options?.title;
91
+ const align = options?.align ?? "left";
92
+ const fixedWidth = options?.width;
93
+ const sections = options?.sections;
94
+ const pad = normalizePadding(options?.padding, 1);
95
+ const margin = normalizeMargin(options?.margin, 0);
96
+ const borders = normalizeBorders(options?.borders);
97
+ const chars = getBorderCharacters(border);
98
+ let lines;
99
+ let sectionBoundaries = [];
100
+ if (sections && sections.length > 0) {
101
+ lines = [];
102
+ for (const [idx, section] of sections.entries()) {
103
+ const sectionLines = typeof section === "string" ? section.split(`
104
+ `) : section;
105
+ lines.push(...sectionLines);
106
+ if (idx < sections.length - 1) {
107
+ sectionBoundaries.push(lines.length);
108
+ }
109
+ }
110
+ } else if (typeof content === "string") {
111
+ lines = content.split(`
112
+ `);
113
+ } else {
114
+ lines = content;
115
+ }
116
+ const leftOverhead = (borders.left ? 1 : 0) + pad.left;
117
+ const rightOverhead = (borders.right ? 1 : 0) + pad.right;
118
+ const horizontalOverhead = leftOverhead + rightOverhead;
119
+ if (fixedWidth) {
120
+ const contentWidthForWrap = fixedWidth - horizontalOverhead;
121
+ if (contentWidthForWrap > 0) {
122
+ const wrappedLines = [];
123
+ const newBoundaries = [];
124
+ let boundaryIdx2 = 0;
125
+ let originalLineCount = 0;
126
+ for (const line of lines) {
127
+ if (getStringWidth(line) > contentWidthForWrap) {
128
+ const wrapped = wrapText(line, contentWidthForWrap);
129
+ wrappedLines.push(...wrapped.split(`
130
+ `));
131
+ } else {
132
+ wrappedLines.push(line);
133
+ }
134
+ originalLineCount++;
135
+ const boundary = sectionBoundaries[boundaryIdx2];
136
+ if (boundary !== undefined && originalLineCount === boundary) {
137
+ newBoundaries.push(wrappedLines.length);
138
+ boundaryIdx2++;
139
+ }
140
+ }
141
+ lines = wrappedLines;
142
+ sectionBoundaries = newBoundaries;
143
+ }
144
+ }
145
+ let contentWidth = 0;
146
+ for (const line of lines) {
147
+ const w = getStringWidth(line);
148
+ if (w > contentWidth) {
149
+ contentWidth = w;
150
+ }
151
+ }
152
+ let boxWidth;
153
+ if (fixedWidth) {
154
+ boxWidth = fixedWidth;
155
+ contentWidth = fixedWidth - horizontalOverhead;
156
+ } else {
157
+ boxWidth = horizontalOverhead + contentWidth;
158
+ if (title && borders.top) {
159
+ const minBoxWidthForTitle = getStringWidth(title) + 4 + (borders.left ? 1 : 0) + (borders.right ? 1 : 0);
160
+ if (boxWidth < minBoxWidthForTitle) {
161
+ boxWidth = minBoxWidthForTitle;
162
+ contentWidth = boxWidth - horizontalOverhead;
163
+ }
164
+ }
165
+ }
166
+ const output = [];
167
+ const leftPaddingStr = " ".repeat(pad.left);
168
+ const rightPaddingStr = " ".repeat(pad.right);
169
+ const marginLeftStr = " ".repeat(margin.left);
170
+ const marginRightStr = " ".repeat(margin.right);
171
+ const buildContentLine = (lineContent) => {
172
+ const aligned = alignLine(lineContent, contentWidth, align);
173
+ const leftBorder = borders.left ? chars.vertical : "";
174
+ const rightBorder = borders.right ? chars.vertical : "";
175
+ return marginLeftStr + leftBorder + leftPaddingStr + aligned + rightPaddingStr + rightBorder + marginRightStr;
176
+ };
177
+ const innerWidth = boxWidth - (borders.left ? 1 : 0) - (borders.right ? 1 : 0);
178
+ for (let i = 0;i < margin.top; i++) {
179
+ output.push("");
180
+ }
181
+ if (borders.top) {
182
+ let topBorder;
183
+ if (title) {
184
+ const maxTitleWidth = Math.max(0, innerWidth - 4);
185
+ let displayTitle = title;
186
+ if (maxTitleWidth === 0) {
187
+ topBorder = marginLeftStr + (borders.left ? chars.topLeft : "") + chars.horizontal.repeat(Math.max(0, innerWidth)) + (borders.right ? chars.topRight : "") + marginRightStr;
188
+ } else {
189
+ if (getStringWidth(title) > maxTitleWidth) {
190
+ displayTitle = truncateText(title, maxTitleWidth);
191
+ }
192
+ const titlePart = `${chars.horizontal} ${displayTitle} `;
193
+ const remainingWidth = Math.max(0, innerWidth - getStringWidth(titlePart));
194
+ topBorder = marginLeftStr + (borders.left ? chars.topLeft : "") + titlePart + chars.horizontal.repeat(remainingWidth) + (borders.right ? chars.topRight : "") + marginRightStr;
195
+ }
196
+ } else {
197
+ topBorder = marginLeftStr + (borders.left ? chars.topLeft : "") + chars.horizontal.repeat(innerWidth) + (borders.right ? chars.topRight : "") + marginRightStr;
198
+ }
199
+ output.push(topBorder);
200
+ }
201
+ for (let i = 0;i < pad.top; i++) {
202
+ output.push(buildContentLine(""));
203
+ }
204
+ let boundaryIdx = 0;
205
+ for (const [idx, line] of lines.entries()) {
206
+ output.push(buildContentLine(line));
207
+ const boundary = sectionBoundaries[boundaryIdx];
208
+ if (boundary !== undefined && idx + 1 === boundary) {
209
+ const divider = marginLeftStr + (borders.left ? chars.leftT : "") + chars.horizontal.repeat(innerWidth) + (borders.right ? chars.rightT : "") + marginRightStr;
210
+ output.push(divider);
211
+ boundaryIdx++;
212
+ }
213
+ }
214
+ for (let i = 0;i < pad.bottom; i++) {
215
+ output.push(buildContentLine(""));
216
+ }
217
+ if (borders.bottom) {
218
+ const bottomBorder = marginLeftStr + (borders.left ? chars.bottomLeft : "") + chars.horizontal.repeat(innerWidth) + (borders.right ? chars.bottomRight : "") + marginRightStr;
219
+ output.push(bottomBorder);
220
+ }
221
+ for (let i = 0;i < margin.bottom; i++) {
222
+ output.push("");
223
+ }
224
+ return output.join(`
225
+ `);
226
+ }
227
+ function isBox(value) {
228
+ return typeof value === "object" && value !== null && "output" in value && "width" in value && "height" in value && typeof value.output === "string" && typeof value.width === "number" && typeof value.height === "number";
229
+ }
230
+ function contentToLines(content) {
231
+ if (Array.isArray(content)) {
232
+ const lines = [];
233
+ for (const item of content) {
234
+ if (isBox(item)) {
235
+ lines.push(...item.output.split(`
236
+ `));
237
+ } else if (Array.isArray(item)) {
238
+ lines.push(...item);
239
+ } else {
240
+ lines.push(...item.split(`
241
+ `));
242
+ }
243
+ }
244
+ return lines;
245
+ }
246
+ if (isBox(content)) {
247
+ return content.output.split(`
248
+ `);
249
+ }
250
+ if (typeof content === "string") {
251
+ return content.split(`
252
+ `);
253
+ }
254
+ return content;
255
+ }
256
+ function createBox(content, options) {
257
+ const lines = contentToLines(content);
258
+ const output = renderBox(lines, options);
259
+ const outputLines = output.split(`
260
+ `);
261
+ let maxWidth = 0;
262
+ for (const line of outputLines) {
263
+ const lineWidth = getStringWidth(line);
264
+ if (lineWidth > maxWidth) {
265
+ maxWidth = lineWidth;
266
+ }
267
+ }
268
+ return {
269
+ output,
270
+ width: maxWidth,
271
+ height: outputLines.length
272
+ };
273
+ }
274
+ var init_box = __esm(() => {
275
+ init_borders();
276
+ init_text();
277
+ });
278
+
279
+ export { normalizePadding, normalizeMargin, normalizeBorders, renderBox, createBox, exports_box, init_box };
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Validator factories for prompt input validation.
3
+ *
4
+ * @packageDocumentation
5
+ */
6
+ /**
7
+ * A validator function that returns an error message or undefined.
8
+ */
9
+ type Validator = (value: string) => string | undefined;
10
+ /**
11
+ * Collection of validator factory functions.
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * import { validators } from "@outfitter/cli/prompt";
16
+ *
17
+ * const validate = validators.compose(
18
+ * validators.required(),
19
+ * validators.minLength(3),
20
+ * validators.email()
21
+ * );
22
+ *
23
+ * const error = validate("ab");
24
+ * // "Minimum 3 characters"
25
+ * ```
26
+ */
27
+ declare const validators: {
28
+ /**
29
+ * Requires a non-empty value.
30
+ *
31
+ * @param message - Custom error message
32
+ * @returns Validator function
33
+ */
34
+ required: (message?: string) => Validator;
35
+ /**
36
+ * Requires minimum character length.
37
+ *
38
+ * @param length - Minimum length
39
+ * @param message - Custom error message
40
+ * @returns Validator function
41
+ */
42
+ minLength: (length: number, message?: string) => Validator;
43
+ /**
44
+ * Requires maximum character length.
45
+ *
46
+ * @param length - Maximum length
47
+ * @param message - Custom error message
48
+ * @returns Validator function
49
+ */
50
+ maxLength: (length: number, message?: string) => Validator;
51
+ /**
52
+ * Requires value to match a regex pattern.
53
+ *
54
+ * @param regex - Pattern to match
55
+ * @param message - Error message when pattern doesn't match
56
+ * @returns Validator function
57
+ */
58
+ pattern: (regex: RegExp, message: string) => Validator;
59
+ /**
60
+ * Validates email format.
61
+ *
62
+ * @param message - Custom error message
63
+ * @returns Validator function
64
+ */
65
+ email: (message?: string) => Validator;
66
+ /**
67
+ * Composes multiple validators, returning the first error.
68
+ *
69
+ * @param fns - Validators to compose
70
+ * @returns Combined validator function
71
+ */
72
+ compose: (...fns: Validator[]) => Validator;
73
+ };
74
+ export { Validator, validators };