@promptctl/rich-js 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 (318) hide show
  1. package/README.md +418 -0
  2. package/dist/core/box.d.ts +91 -0
  3. package/dist/core/box.d.ts.map +1 -0
  4. package/dist/core/box.js +534 -0
  5. package/dist/core/box.js.map +1 -0
  6. package/dist/core/cells.d.ts +24 -0
  7. package/dist/core/cells.d.ts.map +1 -0
  8. package/dist/core/cells.js +114 -0
  9. package/dist/core/cells.js.map +1 -0
  10. package/dist/core/color.d.ts +158 -0
  11. package/dist/core/color.d.ts.map +1 -0
  12. package/dist/core/color.js +825 -0
  13. package/dist/core/color.js.map +1 -0
  14. package/dist/core/console.d.ts +100 -0
  15. package/dist/core/console.d.ts.map +1 -0
  16. package/dist/core/console.js +353 -0
  17. package/dist/core/console.js.map +1 -0
  18. package/dist/core/emoji.d.ts +25 -0
  19. package/dist/core/emoji.d.ts.map +1 -0
  20. package/dist/core/emoji.js +392 -0
  21. package/dist/core/emoji.js.map +1 -0
  22. package/dist/core/highlighter.d.ts +33 -0
  23. package/dist/core/highlighter.d.ts.map +1 -0
  24. package/dist/core/highlighter.js +103 -0
  25. package/dist/core/highlighter.js.map +1 -0
  26. package/dist/core/markup.d.ts +69 -0
  27. package/dist/core/markup.d.ts.map +1 -0
  28. package/dist/core/markup.js +401 -0
  29. package/dist/core/markup.js.map +1 -0
  30. package/dist/core/measure.d.ts +17 -0
  31. package/dist/core/measure.d.ts.map +1 -0
  32. package/dist/core/measure.js +50 -0
  33. package/dist/core/measure.js.map +1 -0
  34. package/dist/core/protocol.d.ts +32 -0
  35. package/dist/core/protocol.d.ts.map +1 -0
  36. package/dist/core/protocol.js +17 -0
  37. package/dist/core/protocol.js.map +1 -0
  38. package/dist/core/render.d.ts +51 -0
  39. package/dist/core/render.d.ts.map +1 -0
  40. package/dist/core/render.js +69 -0
  41. package/dist/core/render.js.map +1 -0
  42. package/dist/core/segment.d.ts +104 -0
  43. package/dist/core/segment.d.ts.map +1 -0
  44. package/dist/core/segment.js +364 -0
  45. package/dist/core/segment.js.map +1 -0
  46. package/dist/core/spinnerData.d.ts +11 -0
  47. package/dist/core/spinnerData.d.ts.map +1 -0
  48. package/dist/core/spinnerData.js +116 -0
  49. package/dist/core/spinnerData.js.map +1 -0
  50. package/dist/core/strip.d.ts +159 -0
  51. package/dist/core/strip.d.ts.map +1 -0
  52. package/dist/core/strip.js +237 -0
  53. package/dist/core/strip.js.map +1 -0
  54. package/dist/core/style.d.ts +115 -0
  55. package/dist/core/style.d.ts.map +1 -0
  56. package/dist/core/style.js +662 -0
  57. package/dist/core/style.js.map +1 -0
  58. package/dist/core/text.d.ts +91 -0
  59. package/dist/core/text.d.ts.map +1 -0
  60. package/dist/core/text.js +610 -0
  61. package/dist/core/text.js.map +1 -0
  62. package/dist/index.d.ts +99 -0
  63. package/dist/index.d.ts.map +1 -0
  64. package/dist/index.js +72 -0
  65. package/dist/index.js.map +1 -0
  66. package/dist/renderables/align.d.ts +17 -0
  67. package/dist/renderables/align.d.ts.map +1 -0
  68. package/dist/renderables/align.js +47 -0
  69. package/dist/renderables/align.js.map +1 -0
  70. package/dist/renderables/columns.d.ts +28 -0
  71. package/dist/renderables/columns.d.ts.map +1 -0
  72. package/dist/renderables/columns.js +92 -0
  73. package/dist/renderables/columns.js.map +1 -0
  74. package/dist/renderables/constrain.d.ts +16 -0
  75. package/dist/renderables/constrain.d.ts.map +1 -0
  76. package/dist/renderables/constrain.js +38 -0
  77. package/dist/renderables/constrain.js.map +1 -0
  78. package/dist/renderables/flexStrip.d.ts +42 -0
  79. package/dist/renderables/flexStrip.d.ts.map +1 -0
  80. package/dist/renderables/flexStrip.js +201 -0
  81. package/dist/renderables/flexStrip.js.map +1 -0
  82. package/dist/renderables/group.d.ts +12 -0
  83. package/dist/renderables/group.d.ts.map +1 -0
  84. package/dist/renderables/group.js +16 -0
  85. package/dist/renderables/group.js.map +1 -0
  86. package/dist/renderables/json.d.ts +23 -0
  87. package/dist/renderables/json.d.ts.map +1 -0
  88. package/dist/renderables/json.js +49 -0
  89. package/dist/renderables/json.js.map +1 -0
  90. package/dist/renderables/layout.d.ts +37 -0
  91. package/dist/renderables/layout.d.ts.map +1 -0
  92. package/dist/renderables/layout.js +151 -0
  93. package/dist/renderables/layout.js.map +1 -0
  94. package/dist/renderables/live.d.ts +48 -0
  95. package/dist/renderables/live.d.ts.map +1 -0
  96. package/dist/renderables/live.js +131 -0
  97. package/dist/renderables/live.js.map +1 -0
  98. package/dist/renderables/markdown.d.ts +25 -0
  99. package/dist/renderables/markdown.d.ts.map +1 -0
  100. package/dist/renderables/markdown.js +190 -0
  101. package/dist/renderables/markdown.js.map +1 -0
  102. package/dist/renderables/padding.d.ts +26 -0
  103. package/dist/renderables/padding.d.ts.map +1 -0
  104. package/dist/renderables/padding.js +92 -0
  105. package/dist/renderables/padding.js.map +1 -0
  106. package/dist/renderables/panel.d.ts +42 -0
  107. package/dist/renderables/panel.d.ts.map +1 -0
  108. package/dist/renderables/panel.js +202 -0
  109. package/dist/renderables/panel.js.map +1 -0
  110. package/dist/renderables/pretty.d.ts +29 -0
  111. package/dist/renderables/pretty.d.ts.map +1 -0
  112. package/dist/renderables/pretty.js +141 -0
  113. package/dist/renderables/pretty.js.map +1 -0
  114. package/dist/renderables/progress.d.ts +91 -0
  115. package/dist/renderables/progress.d.ts.map +1 -0
  116. package/dist/renderables/progress.js +234 -0
  117. package/dist/renderables/progress.js.map +1 -0
  118. package/dist/renderables/progressBar.d.ts +32 -0
  119. package/dist/renderables/progressBar.d.ts.map +1 -0
  120. package/dist/renderables/progressBar.js +59 -0
  121. package/dist/renderables/progressBar.js.map +1 -0
  122. package/dist/renderables/prompt.d.ts +25 -0
  123. package/dist/renderables/prompt.d.ts.map +1 -0
  124. package/dist/renderables/prompt.js +109 -0
  125. package/dist/renderables/prompt.js.map +1 -0
  126. package/dist/renderables/rule.d.ts +25 -0
  127. package/dist/renderables/rule.d.ts.map +1 -0
  128. package/dist/renderables/rule.js +96 -0
  129. package/dist/renderables/rule.js.map +1 -0
  130. package/dist/renderables/spinner.d.ts +30 -0
  131. package/dist/renderables/spinner.d.ts.map +1 -0
  132. package/dist/renderables/spinner.js +70 -0
  133. package/dist/renderables/spinner.js.map +1 -0
  134. package/dist/renderables/status.d.ts +24 -0
  135. package/dist/renderables/status.d.ts.map +1 -0
  136. package/dist/renderables/status.js +67 -0
  137. package/dist/renderables/status.js.map +1 -0
  138. package/dist/renderables/syntax.d.ts +36 -0
  139. package/dist/renderables/syntax.d.ts.map +1 -0
  140. package/dist/renderables/syntax.js +115 -0
  141. package/dist/renderables/syntax.js.map +1 -0
  142. package/dist/renderables/table.d.ts +109 -0
  143. package/dist/renderables/table.d.ts.map +1 -0
  144. package/dist/renderables/table.js +434 -0
  145. package/dist/renderables/table.js.map +1 -0
  146. package/dist/renderables/traceback.d.ts +26 -0
  147. package/dist/renderables/traceback.d.ts.map +1 -0
  148. package/dist/renderables/traceback.js +108 -0
  149. package/dist/renderables/traceback.js.map +1 -0
  150. package/dist/renderables/tree.d.ts +30 -0
  151. package/dist/renderables/tree.d.ts.map +1 -0
  152. package/dist/renderables/tree.js +107 -0
  153. package/dist/renderables/tree.js.map +1 -0
  154. package/dist/template-bindings/index.d.ts +61 -0
  155. package/dist/template-bindings/index.d.ts.map +1 -0
  156. package/dist/template-bindings/index.js +70 -0
  157. package/dist/template-bindings/index.js.map +1 -0
  158. package/dist/template-bindings/style-funcs.d.ts +30 -0
  159. package/dist/template-bindings/style-funcs.d.ts.map +1 -0
  160. package/dist/template-bindings/style-funcs.js +172 -0
  161. package/dist/template-bindings/style-funcs.js.map +1 -0
  162. package/dist/themes/buildPalette.d.ts +31 -0
  163. package/dist/themes/buildPalette.d.ts.map +1 -0
  164. package/dist/themes/buildPalette.js +43 -0
  165. package/dist/themes/buildPalette.js.map +1 -0
  166. package/dist/themes/colorMath.d.ts +23 -0
  167. package/dist/themes/colorMath.d.ts.map +1 -0
  168. package/dist/themes/colorMath.js +99 -0
  169. package/dist/themes/colorMath.js.map +1 -0
  170. package/dist/themes/data/atom-one-dark.d.ts +4 -0
  171. package/dist/themes/data/atom-one-dark.d.ts.map +1 -0
  172. package/dist/themes/data/atom-one-dark.js +159 -0
  173. package/dist/themes/data/atom-one-dark.js.map +1 -0
  174. package/dist/themes/data/atom-one-light.d.ts +4 -0
  175. package/dist/themes/data/atom-one-light.d.ts.map +1 -0
  176. package/dist/themes/data/atom-one-light.js +159 -0
  177. package/dist/themes/data/atom-one-light.js.map +1 -0
  178. package/dist/themes/data/catppuccin-latte.d.ts +4 -0
  179. package/dist/themes/data/catppuccin-latte.d.ts.map +1 -0
  180. package/dist/themes/data/catppuccin-latte.js +159 -0
  181. package/dist/themes/data/catppuccin-latte.js.map +1 -0
  182. package/dist/themes/data/catppuccin-mocha.d.ts +4 -0
  183. package/dist/themes/data/catppuccin-mocha.d.ts.map +1 -0
  184. package/dist/themes/data/catppuccin-mocha.js +159 -0
  185. package/dist/themes/data/catppuccin-mocha.js.map +1 -0
  186. package/dist/themes/data/dracula.d.ts +4 -0
  187. package/dist/themes/data/dracula.d.ts.map +1 -0
  188. package/dist/themes/data/dracula.js +159 -0
  189. package/dist/themes/data/dracula.js.map +1 -0
  190. package/dist/themes/data/flexoki.d.ts +4 -0
  191. package/dist/themes/data/flexoki.d.ts.map +1 -0
  192. package/dist/themes/data/flexoki.js +159 -0
  193. package/dist/themes/data/flexoki.js.map +1 -0
  194. package/dist/themes/data/gruvbox.d.ts +4 -0
  195. package/dist/themes/data/gruvbox.d.ts.map +1 -0
  196. package/dist/themes/data/gruvbox.js +159 -0
  197. package/dist/themes/data/gruvbox.js.map +1 -0
  198. package/dist/themes/data/index.d.ts +29 -0
  199. package/dist/themes/data/index.d.ts.map +1 -0
  200. package/dist/themes/data/index.js +48 -0
  201. package/dist/themes/data/index.js.map +1 -0
  202. package/dist/themes/data/monokai.d.ts +4 -0
  203. package/dist/themes/data/monokai.d.ts.map +1 -0
  204. package/dist/themes/data/monokai.js +159 -0
  205. package/dist/themes/data/monokai.js.map +1 -0
  206. package/dist/themes/data/nord.d.ts +4 -0
  207. package/dist/themes/data/nord.d.ts.map +1 -0
  208. package/dist/themes/data/nord.js +159 -0
  209. package/dist/themes/data/nord.js.map +1 -0
  210. package/dist/themes/data/rose-pine-dawn.d.ts +4 -0
  211. package/dist/themes/data/rose-pine-dawn.d.ts.map +1 -0
  212. package/dist/themes/data/rose-pine-dawn.js +159 -0
  213. package/dist/themes/data/rose-pine-dawn.js.map +1 -0
  214. package/dist/themes/data/rose-pine-moon.d.ts +4 -0
  215. package/dist/themes/data/rose-pine-moon.d.ts.map +1 -0
  216. package/dist/themes/data/rose-pine-moon.js +159 -0
  217. package/dist/themes/data/rose-pine-moon.js.map +1 -0
  218. package/dist/themes/data/rose-pine.d.ts +4 -0
  219. package/dist/themes/data/rose-pine.d.ts.map +1 -0
  220. package/dist/themes/data/rose-pine.js +159 -0
  221. package/dist/themes/data/rose-pine.js.map +1 -0
  222. package/dist/themes/data/solarized-dark.d.ts +4 -0
  223. package/dist/themes/data/solarized-dark.d.ts.map +1 -0
  224. package/dist/themes/data/solarized-dark.js +159 -0
  225. package/dist/themes/data/solarized-dark.js.map +1 -0
  226. package/dist/themes/data/solarized-light.d.ts +4 -0
  227. package/dist/themes/data/solarized-light.d.ts.map +1 -0
  228. package/dist/themes/data/solarized-light.js +159 -0
  229. package/dist/themes/data/solarized-light.js.map +1 -0
  230. package/dist/themes/data/textual-ansi.d.ts +4 -0
  231. package/dist/themes/data/textual-ansi.d.ts.map +1 -0
  232. package/dist/themes/data/textual-ansi.js +159 -0
  233. package/dist/themes/data/textual-ansi.js.map +1 -0
  234. package/dist/themes/data/textual-dark.d.ts +4 -0
  235. package/dist/themes/data/textual-dark.d.ts.map +1 -0
  236. package/dist/themes/data/textual-dark.js +159 -0
  237. package/dist/themes/data/textual-dark.js.map +1 -0
  238. package/dist/themes/data/textual-light.d.ts +4 -0
  239. package/dist/themes/data/textual-light.d.ts.map +1 -0
  240. package/dist/themes/data/textual-light.js +159 -0
  241. package/dist/themes/data/textual-light.js.map +1 -0
  242. package/dist/themes/data/tokyo-night.d.ts +4 -0
  243. package/dist/themes/data/tokyo-night.d.ts.map +1 -0
  244. package/dist/themes/data/tokyo-night.js +159 -0
  245. package/dist/themes/data/tokyo-night.js.map +1 -0
  246. package/dist/themes/data/types.d.ts +15 -0
  247. package/dist/themes/data/types.d.ts.map +1 -0
  248. package/dist/themes/data/types.js +2 -0
  249. package/dist/themes/data/types.js.map +1 -0
  250. package/dist/themes/palette.d.ts +20 -0
  251. package/dist/themes/palette.d.ts.map +1 -0
  252. package/dist/themes/palette.js +27 -0
  253. package/dist/themes/palette.js.map +1 -0
  254. package/dist/themes/paletteResolver.d.ts +35 -0
  255. package/dist/themes/paletteResolver.d.ts.map +1 -0
  256. package/dist/themes/paletteResolver.js +88 -0
  257. package/dist/themes/paletteResolver.js.map +1 -0
  258. package/dist/themes/registry.d.ts +17 -0
  259. package/dist/themes/registry.d.ts.map +1 -0
  260. package/dist/themes/registry.js +33 -0
  261. package/dist/themes/registry.js.map +1 -0
  262. package/dist/themes/terminalThemes.d.ts +46 -0
  263. package/dist/themes/terminalThemes.d.ts.map +1 -0
  264. package/dist/themes/terminalThemes.js +268 -0
  265. package/dist/themes/terminalThemes.js.map +1 -0
  266. package/dist/widgets/button.d.ts +47 -0
  267. package/dist/widgets/button.d.ts.map +1 -0
  268. package/dist/widgets/button.js +183 -0
  269. package/dist/widgets/button.js.map +1 -0
  270. package/dist/widgets/checkbox.d.ts +43 -0
  271. package/dist/widgets/checkbox.d.ts.map +1 -0
  272. package/dist/widgets/checkbox.js +144 -0
  273. package/dist/widgets/checkbox.js.map +1 -0
  274. package/dist/widgets/dropdown.d.ts +67 -0
  275. package/dist/widgets/dropdown.d.ts.map +1 -0
  276. package/dist/widgets/dropdown.js +373 -0
  277. package/dist/widgets/dropdown.js.map +1 -0
  278. package/dist/widgets/event-router.d.ts +73 -0
  279. package/dist/widgets/event-router.d.ts.map +1 -0
  280. package/dist/widgets/event-router.js +479 -0
  281. package/dist/widgets/event-router.js.map +1 -0
  282. package/dist/widgets/focus-manager.d.ts +26 -0
  283. package/dist/widgets/focus-manager.d.ts.map +1 -0
  284. package/dist/widgets/focus-manager.js +179 -0
  285. package/dist/widgets/focus-manager.js.map +1 -0
  286. package/dist/widgets/index.d.ts +23 -0
  287. package/dist/widgets/index.d.ts.map +1 -0
  288. package/dist/widgets/index.js +13 -0
  289. package/dist/widgets/index.js.map +1 -0
  290. package/dist/widgets/screen.d.ts +90 -0
  291. package/dist/widgets/screen.d.ts.map +1 -0
  292. package/dist/widgets/screen.js +440 -0
  293. package/dist/widgets/screen.js.map +1 -0
  294. package/dist/widgets/slider.d.ts +55 -0
  295. package/dist/widgets/slider.d.ts.map +1 -0
  296. package/dist/widgets/slider.js +248 -0
  297. package/dist/widgets/slider.js.map +1 -0
  298. package/dist/widgets/static-item.d.ts +41 -0
  299. package/dist/widgets/static-item.d.ts.map +1 -0
  300. package/dist/widgets/static-item.js +62 -0
  301. package/dist/widgets/static-item.js.map +1 -0
  302. package/dist/widgets/text-input.d.ts +50 -0
  303. package/dist/widgets/text-input.d.ts.map +1 -0
  304. package/dist/widgets/text-input.js +242 -0
  305. package/dist/widgets/text-input.js.map +1 -0
  306. package/dist/widgets/toggle.d.ts +46 -0
  307. package/dist/widgets/toggle.d.ts.map +1 -0
  308. package/dist/widgets/toggle.js +169 -0
  309. package/dist/widgets/toggle.js.map +1 -0
  310. package/dist/widgets/types.d.ts +92 -0
  311. package/dist/widgets/types.d.ts.map +1 -0
  312. package/dist/widgets/types.js +13 -0
  313. package/dist/widgets/types.js.map +1 -0
  314. package/dist/widgets/widget-base.d.ts +41 -0
  315. package/dist/widgets/widget-base.d.ts.map +1 -0
  316. package/dist/widgets/widget-base.js +159 -0
  317. package/dist/widgets/widget-base.js.map +1 -0
  318. package/package.json +76 -0
@@ -0,0 +1,234 @@
1
+ /**
2
+ * Progress — displays continuously updated progress bars.
3
+ */
4
+ import { Segment } from "../core/segment.js";
5
+ import { Style } from "../core/style.js";
6
+ import { RichText } from "../core/text.js";
7
+ import { Console } from "../core/console.js";
8
+ import { escape as escapeMarkup, renderMarkup } from "../core/markup.js";
9
+ import { ProgressBar } from "./progressBar.js";
10
+ import { Spinner } from "./spinner.js";
11
+ import { Live } from "./live.js";
12
+ import { Table } from "./table.js";
13
+ export class TextColumn {
14
+ format;
15
+ constructor(format) {
16
+ this.format = format ?? "{task.description}";
17
+ }
18
+ *render(options, task) {
19
+ // [LAW:single-enforcer] Format strings flow through the markup parser so
20
+ // tags like `[progress.description]` become Style spans, not literal text.
21
+ // Task descriptions are escaped first to prevent injection of stray tags.
22
+ const description = escapeMarkup(task?.description ?? "");
23
+ // Use a callback so `$&`/`$1`/`$$` in the task description aren't
24
+ // reinterpreted by String.replace as replacement patterns.
25
+ const formatted = this.format.replace(/\{task\.description\}/g, () => description);
26
+ yield* renderMarkup(formatted).render(options);
27
+ }
28
+ }
29
+ export class BarColumn {
30
+ barWidth;
31
+ constructor(barWidth) {
32
+ this.barWidth = barWidth ?? 40;
33
+ }
34
+ *render(_options, task) {
35
+ const bar = new ProgressBar({
36
+ total: task?.total ?? 100,
37
+ completed: task?.completed ?? 0,
38
+ width: this.barWidth,
39
+ });
40
+ yield* bar.render(_options);
41
+ }
42
+ }
43
+ export class TaskProgressColumn {
44
+ *render(_options, task) {
45
+ const percent = task && task.total
46
+ ? Math.min(100, Math.round((task.completed / task.total) * 100))
47
+ : 0;
48
+ yield new Segment(`${percent}%`, Style.parse("progress.percentage"));
49
+ }
50
+ }
51
+ export class TimeRemainingColumn {
52
+ *render(_options, task) {
53
+ if (!task || !task.total || !task.started || task.completed <= 0) {
54
+ yield new Segment("-:--:--", Style.parse("progress.remaining"));
55
+ return;
56
+ }
57
+ const elapsed = (Date.now() - task.startTime) / 1000;
58
+ const rate = task.completed / elapsed;
59
+ const remaining = (task.total - task.completed) / rate;
60
+ yield new Segment(formatTime(remaining), Style.parse("progress.remaining"));
61
+ }
62
+ }
63
+ export class TimeElapsedColumn {
64
+ *render(_options, task) {
65
+ if (!task || !task.started) {
66
+ yield new Segment("0:00:00", Style.parse("progress.elapsed"));
67
+ return;
68
+ }
69
+ const elapsed = (Date.now() - task.startTime) / 1000;
70
+ yield new Segment(formatTime(elapsed), Style.parse("progress.elapsed"));
71
+ }
72
+ }
73
+ export class SpinnerColumn {
74
+ _spinner;
75
+ constructor(spinnerName) {
76
+ this._spinner = new Spinner(spinnerName);
77
+ }
78
+ *render(options, _task) {
79
+ yield* this._spinner.render(options);
80
+ }
81
+ }
82
+ export class MofNCompleteColumn {
83
+ *render(_options, task) {
84
+ const completed = task?.completed ?? 0;
85
+ const total = task?.total ?? "?";
86
+ yield new Segment(`${completed}/${total}`);
87
+ }
88
+ }
89
+ function formatTime(seconds) {
90
+ const h = Math.floor(seconds / 3600);
91
+ const m = Math.floor((seconds % 3600) / 60);
92
+ const s = Math.floor(seconds % 60);
93
+ return `${h}:${String(m).padStart(2, "0")}:${String(s).padStart(2, "0")}`;
94
+ }
95
+ export class Progress {
96
+ _columns;
97
+ _tasks;
98
+ _nextId;
99
+ _live;
100
+ _console;
101
+ expand;
102
+ constructor(...columns) {
103
+ // Last arg might be options
104
+ let opts = {};
105
+ const cols = [];
106
+ for (const arg of columns) {
107
+ if ("render" in arg) {
108
+ cols.push(arg);
109
+ }
110
+ else {
111
+ opts = arg;
112
+ }
113
+ }
114
+ if (cols.length === 0) {
115
+ cols.push(new TextColumn("[progress.description]{task.description}"), new BarColumn(), new TaskProgressColumn(), new TimeRemainingColumn());
116
+ }
117
+ this._columns = cols;
118
+ this._tasks = new Map();
119
+ this._nextId = 1;
120
+ this._console = opts.console ?? new Console({ forceTerminal: true });
121
+ this.expand = opts.expand ?? false;
122
+ this._live = new Live(this, {
123
+ console: this._console,
124
+ refreshPerSecond: opts.refreshPerSecond ?? 10,
125
+ autoRefresh: opts.autoRefresh,
126
+ transient: opts.transient,
127
+ });
128
+ }
129
+ get console() {
130
+ return this._console;
131
+ }
132
+ get finished() {
133
+ for (const task of this._tasks.values()) {
134
+ if (!task.started || (task.total !== undefined && task.completed < task.total)) {
135
+ return false;
136
+ }
137
+ }
138
+ return this._tasks.size > 0;
139
+ }
140
+ static getDefaultColumns() {
141
+ return [
142
+ new TextColumn("[progress.description]{task.description}"),
143
+ new BarColumn(),
144
+ new TaskProgressColumn(),
145
+ new TimeRemainingColumn(),
146
+ ];
147
+ }
148
+ addTask(description, options) {
149
+ const id = this._nextId++;
150
+ const task = {
151
+ id,
152
+ description,
153
+ total: options?.total,
154
+ completed: 0,
155
+ started: options?.start !== false,
156
+ visible: options?.visible !== false,
157
+ startTime: Date.now(),
158
+ elapsed: 0,
159
+ };
160
+ this._tasks.set(id, task);
161
+ return id;
162
+ }
163
+ updateTask(taskId, options) {
164
+ const task = this._tasks.get(taskId);
165
+ if (!task)
166
+ return;
167
+ if (options.completed !== undefined)
168
+ task.completed = options.completed;
169
+ if (options.advance !== undefined)
170
+ task.completed += options.advance;
171
+ if (options.description !== undefined)
172
+ task.description = options.description;
173
+ if (options.visible !== undefined)
174
+ task.visible = options.visible;
175
+ if (options.refresh) {
176
+ this._live.update(this, { refresh: true });
177
+ }
178
+ }
179
+ startTask(taskId) {
180
+ const task = this._tasks.get(taskId);
181
+ if (task) {
182
+ task.started = true;
183
+ task.startTime = Date.now();
184
+ }
185
+ }
186
+ start() {
187
+ this._live.start();
188
+ }
189
+ stop() {
190
+ this._live.stop();
191
+ }
192
+ refresh() {
193
+ this._live.refresh();
194
+ }
195
+ *render(options) {
196
+ const table = Table.grid({ expand: this.expand });
197
+ for (const _col of this._columns) {
198
+ table.addColumn();
199
+ }
200
+ for (const task of this._tasks.values()) {
201
+ if (!task.visible)
202
+ continue;
203
+ const cells = this._columns.map((col) => {
204
+ const segs = [...col.render(options, task)];
205
+ // Build a RichText that preserves segment styles as spans
206
+ const text = new RichText("", { end: "" });
207
+ for (const seg of segs) {
208
+ text.append(seg.text, seg.style);
209
+ }
210
+ return text;
211
+ });
212
+ table.addRow(...cells);
213
+ }
214
+ yield* table.render(options);
215
+ }
216
+ }
217
+ // --- track ---
218
+ export function* track(iterable, options) {
219
+ const items = [...iterable];
220
+ const total = options?.total ?? items.length;
221
+ const progress = new Progress({ console: options?.console });
222
+ const taskId = progress.addTask(options?.description ?? "Working...", { total });
223
+ progress.start();
224
+ try {
225
+ for (let i = 0; i < items.length; i++) {
226
+ yield items[i];
227
+ progress.updateTask(taskId, { completed: i + 1 });
228
+ }
229
+ }
230
+ finally {
231
+ progress.stop();
232
+ }
233
+ }
234
+ //# sourceMappingURL=progress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress.js","sourceRoot":"","sources":["../../src/renderables/progress.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAoCnC,MAAM,OAAO,UAAU;IACZ,MAAM,CAAS;IAExB,YAAY,MAAe;QACzB,IAAI,CAAC,MAAM,GAAG,MAAM,IAAI,oBAAoB,CAAC;IAC/C,CAAC;IAED,CAAC,MAAM,CAAC,OAAsB,EAAE,IAAW;QACzC,yEAAyE;QACzE,2EAA2E;QAC3E,0EAA0E;QAC1E,MAAM,WAAW,GAAG,YAAY,CAAC,IAAI,EAAE,WAAW,IAAI,EAAE,CAAC,CAAC;QAC1D,kEAAkE;QAClE,2DAA2D;QAC3D,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,wBAAwB,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,CAAC;QACnF,KAAK,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACjD,CAAC;CACF;AAED,MAAM,OAAO,SAAS;IACX,QAAQ,CAAS;IAE1B,YAAY,QAAiB;QAC3B,IAAI,CAAC,QAAQ,GAAG,QAAQ,IAAI,EAAE,CAAC;IACjC,CAAC;IAED,CAAC,MAAM,CAAC,QAAuB,EAAE,IAAW;QAC1C,MAAM,GAAG,GAAG,IAAI,WAAW,CAAC;YAC1B,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,GAAG;YACzB,SAAS,EAAE,IAAI,EAAE,SAAS,IAAI,CAAC;YAC/B,KAAK,EAAE,IAAI,CAAC,QAAQ;SACrB,CAAC,CAAC;QACH,KAAK,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC9B,CAAC;CACF;AAED,MAAM,OAAO,kBAAkB;IAC7B,CAAC,MAAM,CAAC,QAAuB,EAAE,IAAW;QAC1C,MAAM,OAAO,GAAG,IAAI,IAAI,IAAI,CAAC,KAAK;YAChC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC;YAChE,CAAC,CAAC,CAAC,CAAC;QACN,MAAM,IAAI,OAAO,CAAC,GAAG,OAAO,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC;IACvE,CAAC;CACF;AAED,MAAM,OAAO,mBAAmB;IAC9B,CAAC,MAAM,CAAC,QAAuB,EAAE,IAAW;QAC1C,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,SAAS,IAAI,CAAC,EAAE,CAAC;YACjE,MAAM,IAAI,OAAO,CAAC,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,CAAC;YAChE,OAAO;QACT,CAAC;QACD,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;QACrD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC;QACtC,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;QACvD,MAAM,IAAI,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,CAAC;IAC9E,CAAC;CACF;AAED,MAAM,OAAO,iBAAiB;IAC5B,CAAC,MAAM,CAAC,QAAuB,EAAE,IAAW;QAC1C,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAC3B,MAAM,IAAI,OAAO,CAAC,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC;YAC9D,OAAO;QACT,CAAC;QACD,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;QACrD,MAAM,IAAI,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC;IAC1E,CAAC;CACF;AAED,MAAM,OAAO,aAAa;IAChB,QAAQ,CAAU;IAE1B,YAAY,WAAoB;QAC9B,IAAI,CAAC,QAAQ,GAAG,IAAI,OAAO,CAAC,WAAW,CAAC,CAAC;IAC3C,CAAC;IAED,CAAC,MAAM,CAAC,OAAsB,EAAE,KAAY;QAC1C,KAAK,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACvC,CAAC;CACF;AAED,MAAM,OAAO,kBAAkB;IAC7B,CAAC,MAAM,CAAC,QAAuB,EAAE,IAAW;QAC1C,MAAM,SAAS,GAAG,IAAI,EAAE,SAAS,IAAI,CAAC,CAAC;QACvC,MAAM,KAAK,GAAG,IAAI,EAAE,KAAK,IAAI,GAAG,CAAC;QACjC,MAAM,IAAI,OAAO,CAAC,GAAG,SAAS,IAAI,KAAK,EAAE,CAAC,CAAC;IAC7C,CAAC;CACF;AAED,SAAS,UAAU,CAAC,OAAe;IACjC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IACrC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAC5C,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;IACnC,OAAO,GAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;AAC5E,CAAC;AAYD,MAAM,OAAO,QAAQ;IACX,QAAQ,CAAmB;IAC3B,MAAM,CAAoB;IAC1B,OAAO,CAAS;IAChB,KAAK,CAAO;IACZ,QAAQ,CAAU;IACjB,MAAM,CAAU;IAEzB,YAAY,GAAG,OAA6C;QAC1D,4BAA4B;QAC5B,IAAI,IAAI,GAAoB,EAAE,CAAC;QAC/B,MAAM,IAAI,GAAqB,EAAE,CAAC;QAElC,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YAC1B,IAAI,QAAQ,IAAI,GAAG,EAAE,CAAC;gBACpB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACjB,CAAC;iBAAM,CAAC;gBACN,IAAI,GAAG,GAAG,CAAC;YACb,CAAC;QACH,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,IAAI,CAAC,IAAI,CACP,IAAI,UAAU,CAAC,0CAA0C,CAAC,EAC1D,IAAI,SAAS,EAAE,EACf,IAAI,kBAAkB,EAAE,EACxB,IAAI,mBAAmB,EAAE,CAC1B,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC,MAAM,GAAG,IAAI,GAAG,EAAE,CAAC;QACxB,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;QACjB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,OAAO,IAAI,IAAI,OAAO,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QACrE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC;QACnC,IAAI,CAAC,KAAK,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE;YAC1B,OAAO,EAAE,IAAI,CAAC,QAAQ;YACtB,gBAAgB,EAAE,IAAI,CAAC,gBAAgB,IAAI,EAAE;YAC7C,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,SAAS,EAAE,IAAI,CAAC,SAAS;SAC1B,CAAC,CAAC;IACL,CAAC;IAED,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED,IAAI,QAAQ;QACV,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;YACxC,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,KAAK,SAAS,IAAI,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC/E,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC;IAC9B,CAAC;IAED,MAAM,CAAC,iBAAiB;QACtB,OAAO;YACL,IAAI,UAAU,CAAC,0CAA0C,CAAC;YAC1D,IAAI,SAAS,EAAE;YACf,IAAI,kBAAkB,EAAE;YACxB,IAAI,mBAAmB,EAAE;SAC1B,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,WAAmB,EAAE,OAAqB;QAChD,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QAC1B,MAAM,IAAI,GAAS;YACjB,EAAE;YACF,WAAW;YACX,KAAK,EAAE,OAAO,EAAE,KAAK;YACrB,SAAS,EAAE,CAAC;YACZ,OAAO,EAAE,OAAO,EAAE,KAAK,KAAK,KAAK;YACjC,OAAO,EAAE,OAAO,EAAE,OAAO,KAAK,KAAK;YACnC,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;YACrB,OAAO,EAAE,CAAC;SACX,CAAC;QACF,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QAC1B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,UAAU,CAAC,MAAc,EAAE,OAA0B;QACnD,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACrC,IAAI,CAAC,IAAI;YAAE,OAAO;QAElB,IAAI,OAAO,CAAC,SAAS,KAAK,SAAS;YAAE,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QACxE,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS;YAAE,IAAI,CAAC,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;QACrE,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS;YAAE,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;QAC9E,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS;YAAE,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;QAElE,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACpB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;IAED,SAAS,CAAC,MAAc;QACtB,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACrC,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YACpB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,KAAK;QACH,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;IAED,IAAI;QACF,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IACpB,CAAC;IAED,OAAO;QACL,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;IACvB,CAAC;IAED,CAAC,MAAM,CAAC,OAAsB;QAC5B,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QAClD,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACjC,KAAK,CAAC,SAAS,EAAE,CAAC;QACpB,CAAC;QAED,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;YACxC,IAAI,CAAC,IAAI,CAAC,OAAO;gBAAE,SAAS;YAC5B,MAAM,KAAK,GAAc,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;gBACjD,MAAM,IAAI,GAAG,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;gBAC5C,0DAA0D;gBAC1D,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC;gBAC3C,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;oBACvB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;gBACnC,CAAC;gBACD,OAAO,IAAI,CAAC;YACd,CAAC,CAAC,CAAC;YACH,KAAK,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC;QACzB,CAAC;QAED,KAAK,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;CACF;AAED,gBAAgB;AAEhB,MAAM,SAAS,CAAC,CAAC,KAAK,CACpB,QAAqB,EACrB,OAAqE;IAErE,MAAM,KAAK,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC;IAC5B,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,KAAK,CAAC,MAAM,CAAC;IAC7C,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IAC7D,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,WAAW,IAAI,YAAY,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IACjF,QAAQ,CAAC,KAAK,EAAE,CAAC;IAEjB,IAAI,CAAC;QACH,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,MAAM,KAAK,CAAC,CAAC,CAAE,CAAC;YAChB,QAAQ,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;YAAS,CAAC;QACT,QAAQ,CAAC,IAAI,EAAE,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * ProgressBar — a visual progress bar rendered with block characters.
3
+ */
4
+ import { Segment } from "../core/segment.js";
5
+ import { Style } from "../core/style.js";
6
+ import type { Renderable, Measurable, RenderOptions } from "../core/protocol.js";
7
+ export interface ProgressBarOptions {
8
+ total?: number;
9
+ completed?: number;
10
+ width?: number;
11
+ pulse?: boolean;
12
+ style?: string | Style;
13
+ completeStyle?: string | Style;
14
+ finishedStyle?: string | Style;
15
+ }
16
+ export declare class ProgressBar implements Renderable, Measurable {
17
+ total: number;
18
+ completed: number;
19
+ readonly width: number | undefined;
20
+ readonly pulse: boolean;
21
+ readonly style: Style;
22
+ readonly completeStyle: Style;
23
+ readonly finishedStyle: Style;
24
+ constructor(options?: ProgressBarOptions);
25
+ get percentComplete(): number;
26
+ render(options: RenderOptions): Iterable<Segment>;
27
+ measure(_options: RenderOptions): {
28
+ minimum: number;
29
+ maximum: number;
30
+ };
31
+ }
32
+ //# sourceMappingURL=progressBar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progressBar.d.ts","sourceRoot":"","sources":["../../src/renderables/progressBar.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAc,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EACV,UAAU,EACV,UAAU,EACV,aAAa,EACd,MAAM,qBAAqB,CAAC;AAK7B,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAC/B,aAAa,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;CAChC;AAQD,qBAAa,WAAY,YAAW,UAAU,EAAE,UAAU;IACxD,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,aAAa,EAAE,KAAK,CAAC;IAC9B,QAAQ,CAAC,aAAa,EAAE,KAAK,CAAC;gBAElB,OAAO,CAAC,EAAE,kBAAkB;IAUxC,IAAI,eAAe,IAAI,MAAM,CAG5B;IAEA,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,QAAQ,CAAC,OAAO,CAAC;IAoBlD,OAAO,CAAC,QAAQ,EAAE,aAAa,GAAG;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;CAIvE"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * ProgressBar — a visual progress bar rendered with block characters.
3
+ */
4
+ import { Segment } from "../core/segment.js";
5
+ import { Style, NULL_STYLE } from "../core/style.js";
6
+ const FULL_BLOCK = "━";
7
+ const EMPTY_BLOCK = "━";
8
+ function resolveStyle(style) {
9
+ if (style === undefined)
10
+ return NULL_STYLE;
11
+ if (typeof style === "string")
12
+ return Style.parse(style);
13
+ return style;
14
+ }
15
+ export class ProgressBar {
16
+ total;
17
+ completed;
18
+ width;
19
+ pulse;
20
+ style;
21
+ completeStyle;
22
+ finishedStyle;
23
+ constructor(options) {
24
+ this.total = options?.total ?? 100;
25
+ this.completed = options?.completed ?? 0;
26
+ this.width = options?.width;
27
+ this.pulse = options?.pulse ?? false;
28
+ this.style = resolveStyle(options?.style);
29
+ this.completeStyle = resolveStyle(options?.completeStyle ?? "bar.complete");
30
+ this.finishedStyle = resolveStyle(options?.finishedStyle ?? "bar.finished");
31
+ }
32
+ get percentComplete() {
33
+ if (this.total <= 0)
34
+ return 0;
35
+ return Math.min(1, Math.max(0, this.completed / this.total));
36
+ }
37
+ *render(options) {
38
+ const barWidth = this.width ?? Math.min(40, options.maxWidth);
39
+ const percent = this.percentComplete;
40
+ const isFinished = percent >= 1;
41
+ const filledWidth = Math.round(barWidth * percent);
42
+ const emptyWidth = barWidth - filledWidth;
43
+ const fillStyle = isFinished
44
+ ? (this.finishedStyle.isNull ? undefined : this.finishedStyle)
45
+ : (this.completeStyle.isNull ? undefined : this.completeStyle);
46
+ const bgStyle = this.style.isNull ? undefined : this.style;
47
+ if (filledWidth > 0) {
48
+ yield new Segment(FULL_BLOCK.repeat(filledWidth), fillStyle);
49
+ }
50
+ if (emptyWidth > 0) {
51
+ yield new Segment(EMPTY_BLOCK.repeat(emptyWidth), bgStyle);
52
+ }
53
+ }
54
+ measure(_options) {
55
+ const w = this.width ?? 40;
56
+ return { minimum: 4, maximum: w };
57
+ }
58
+ }
59
+ //# sourceMappingURL=progressBar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progressBar.js","sourceRoot":"","sources":["../../src/renderables/progressBar.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Prompt — interactive prompts for user input.
3
+ */
4
+ import { Console } from "../core/console.js";
5
+ export interface PromptOptions<T> {
6
+ default?: T;
7
+ choices?: string[];
8
+ caseSensitive?: boolean;
9
+ console?: Console;
10
+ showChoices?: boolean;
11
+ showDefault?: boolean;
12
+ }
13
+ export declare class Prompt {
14
+ static ask(promptText: string, options?: PromptOptions<string>): Promise<string>;
15
+ }
16
+ export declare class IntPrompt {
17
+ static ask(promptText: string, options?: PromptOptions<number>): Promise<number>;
18
+ }
19
+ export declare class FloatPrompt {
20
+ static ask(promptText: string, options?: PromptOptions<number>): Promise<number>;
21
+ }
22
+ export declare class Confirm {
23
+ static ask(promptText: string, options?: PromptOptions<boolean>): Promise<boolean>;
24
+ }
25
+ //# sourceMappingURL=prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/renderables/prompt.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAK7C,MAAM,WAAW,aAAa,CAAC,CAAC;IAC9B,OAAO,CAAC,EAAE,CAAC,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAwBD,qBAAa,MAAM;WACJ,GAAG,CACd,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,GAC9B,OAAO,CAAC,MAAM,CAAC;CAkCnB;AAED,qBAAa,SAAS;WACP,GAAG,CACd,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,GAC9B,OAAO,CAAC,MAAM,CAAC;CAqBnB;AAED,qBAAa,WAAW;WACT,GAAG,CACd,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,GAC9B,OAAO,CAAC,MAAM,CAAC;CAoBnB;AAED,qBAAa,OAAO;WACL,GAAG,CACd,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,GAC/B,OAAO,CAAC,OAAO,CAAC;CAcpB"}
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Prompt — interactive prompts for user input.
3
+ */
4
+ import * as readline from "node:readline";
5
+ import { render as renderMarkup } from "../core/markup.js";
6
+ // --- Base ---
7
+ function ask(promptText, _options) {
8
+ const rendered = renderMarkup(promptText);
9
+ return new Promise((resolve) => {
10
+ const rl = readline.createInterface({
11
+ input: process.stdin,
12
+ output: process.stdout,
13
+ });
14
+ rl.question(rendered.plain + " ", (answer) => {
15
+ rl.close();
16
+ resolve(answer);
17
+ });
18
+ });
19
+ }
20
+ // --- Prompt ---
21
+ export class Prompt {
22
+ static async ask(promptText, options) {
23
+ const showDefault = options?.showDefault !== false;
24
+ const showChoices = options?.showChoices !== false;
25
+ let display = promptText;
26
+ if (showChoices && options?.choices) {
27
+ display += ` [${options.choices.join("/")}]`;
28
+ }
29
+ if (showDefault && options?.default !== undefined) {
30
+ display += ` (${options.default})`;
31
+ }
32
+ display += ":";
33
+ while (true) {
34
+ const answer = await ask(display, { console: options?.console });
35
+ const value = answer.trim();
36
+ if (value === "" && options?.default !== undefined) {
37
+ return options.default;
38
+ }
39
+ if (options?.choices) {
40
+ const caseSensitive = options.caseSensitive !== false;
41
+ const match = options.choices.find((c) => caseSensitive ? c === value : c.toLowerCase() === value.toLowerCase());
42
+ if (match)
43
+ return match;
44
+ // Invalid choice — retry
45
+ continue;
46
+ }
47
+ return value;
48
+ }
49
+ }
50
+ }
51
+ export class IntPrompt {
52
+ static async ask(promptText, options) {
53
+ const showDefault = options?.showDefault !== false;
54
+ let display = promptText;
55
+ if (showDefault && options?.default !== undefined) {
56
+ display += ` (${options.default})`;
57
+ }
58
+ display += ":";
59
+ while (true) {
60
+ const answer = await ask(display, { console: options?.console });
61
+ const value = answer.trim();
62
+ if (value === "" && options?.default !== undefined) {
63
+ return options.default;
64
+ }
65
+ const num = parseInt(value, 10);
66
+ if (!isNaN(num) && String(num) === value)
67
+ return num;
68
+ // Invalid — retry
69
+ }
70
+ }
71
+ }
72
+ export class FloatPrompt {
73
+ static async ask(promptText, options) {
74
+ const showDefault = options?.showDefault !== false;
75
+ let display = promptText;
76
+ if (showDefault && options?.default !== undefined) {
77
+ display += ` (${options.default})`;
78
+ }
79
+ display += ":";
80
+ while (true) {
81
+ const answer = await ask(display, { console: options?.console });
82
+ const value = answer.trim();
83
+ if (value === "" && options?.default !== undefined) {
84
+ return options.default;
85
+ }
86
+ const num = parseFloat(value);
87
+ if (!isNaN(num))
88
+ return num;
89
+ }
90
+ }
91
+ }
92
+ export class Confirm {
93
+ static async ask(promptText, options) {
94
+ const defaultVal = options?.default;
95
+ const yesNo = defaultVal === true ? "Y/n" : defaultVal === false ? "y/N" : "y/n";
96
+ const display = `${promptText} [${yesNo}]:`;
97
+ while (true) {
98
+ const answer = await ask(display, { console: options?.console });
99
+ const value = answer.trim().toLowerCase();
100
+ if (value === "" && defaultVal !== undefined)
101
+ return defaultVal;
102
+ if (value === "y" || value === "yes")
103
+ return true;
104
+ if (value === "n" || value === "no")
105
+ return false;
106
+ }
107
+ }
108
+ }
109
+ //# sourceMappingURL=prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/renderables/prompt.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Rule — a horizontal divider line, optionally with a centered title.
3
+ */
4
+ import { Segment } from "../core/segment.js";
5
+ import { Style } from "../core/style.js";
6
+ import type { Renderable, Measurable, RenderOptions } from "../core/protocol.js";
7
+ export type RuleAlign = "left" | "center" | "right";
8
+ export interface RuleOptions {
9
+ characters?: string;
10
+ align?: RuleAlign;
11
+ style?: string | Style;
12
+ }
13
+ export declare class Rule implements Renderable, Measurable {
14
+ readonly title: string | undefined;
15
+ readonly characters: string;
16
+ readonly align: RuleAlign;
17
+ readonly style: Style;
18
+ constructor(title?: string, options?: RuleOptions);
19
+ render(options: RenderOptions): Iterable<Segment>;
20
+ measure(_options: RenderOptions): {
21
+ minimum: number;
22
+ maximum: number;
23
+ };
24
+ }
25
+ //# sourceMappingURL=rule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rule.d.ts","sourceRoot":"","sources":["../../src/renderables/rule.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAc,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EACV,UAAU,EACV,UAAU,EACV,aAAa,EACd,MAAM,qBAAqB,CAAC;AAE7B,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEpD,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;CACxB;AAKD,qBAAa,IAAK,YAAW,UAAU,EAAE,UAAU;IACjD,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;gBAEV,KAAK,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW;IAgBhD,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,QAAQ,CAAC,OAAO,CAAC;IA4ClD,OAAO,CAAC,QAAQ,EAAE,aAAa,GAAG;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;CAGvE"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Rule — a horizontal divider line, optionally with a centered title.
3
+ */
4
+ import { cellLen } from "../core/cells.js";
5
+ import { Segment } from "../core/segment.js";
6
+ import { Style, NULL_STYLE } from "../core/style.js";
7
+ const ASCII_RULE_CHAR = "-";
8
+ const DEFAULT_RULE_CHAR = "\u2500"; // ─
9
+ export class Rule {
10
+ title;
11
+ characters;
12
+ align;
13
+ style;
14
+ constructor(title, options) {
15
+ const chars = options?.characters ?? DEFAULT_RULE_CHAR;
16
+ if (chars.length === 0) {
17
+ throw new Error("Rule characters must not be empty");
18
+ }
19
+ const align = options?.align;
20
+ if (align !== undefined && align !== "left" && align !== "center" && align !== "right") {
21
+ throw new Error(`Invalid align value: "${align}"`);
22
+ }
23
+ this.title = title;
24
+ this.characters = chars;
25
+ this.align = align ?? "center";
26
+ this.style = resolveStyle(options?.style);
27
+ }
28
+ *render(options) {
29
+ const maxWidth = options.maxWidth;
30
+ const ruleChar = options.asciiOnly ? ASCII_RULE_CHAR : this.characters;
31
+ const ruleStyle = this.style.isNull ? undefined : this.style;
32
+ if (!this.title) {
33
+ // No title — just a line of repeated characters
34
+ yield new Segment(repeatToWidth(ruleChar, maxWidth), ruleStyle);
35
+ yield Segment.line();
36
+ return;
37
+ }
38
+ // With title
39
+ const titleText = ` ${this.title} `;
40
+ const titleWidth = cellLen(titleText);
41
+ if (titleWidth >= maxWidth) {
42
+ // Title fills the whole width
43
+ yield new Segment(titleText.slice(0, maxWidth), ruleStyle);
44
+ yield Segment.line();
45
+ return;
46
+ }
47
+ const remaining = maxWidth - titleWidth;
48
+ // [LAW:dataflow-not-control-flow] Always compute both sides; alignment determines distribution
49
+ const leftWidth = this.align === "right"
50
+ ? remaining
51
+ : this.align === "center"
52
+ ? Math.floor(remaining / 2)
53
+ : 0;
54
+ const rightWidth = remaining - leftWidth;
55
+ if (leftWidth > 0) {
56
+ yield new Segment(repeatToWidth(ruleChar, leftWidth), ruleStyle);
57
+ }
58
+ yield new Segment(titleText, ruleStyle);
59
+ if (rightWidth > 0) {
60
+ yield new Segment(repeatToWidth(ruleChar, rightWidth), ruleStyle);
61
+ }
62
+ yield Segment.line();
63
+ }
64
+ measure(_options) {
65
+ return { minimum: 1, maximum: _options.maxWidth };
66
+ }
67
+ }
68
+ function repeatToWidth(char, width) {
69
+ const charWidth = cellLen(char);
70
+ if (charWidth === 0)
71
+ return " ".repeat(width);
72
+ const repeats = Math.ceil(width / charWidth);
73
+ const full = char.repeat(repeats);
74
+ // Trim to exact width
75
+ let w = 0;
76
+ let i = 0;
77
+ for (const c of full) {
78
+ const cw = cellLen(c);
79
+ if (w + cw > width)
80
+ break;
81
+ w += cw;
82
+ i += c.length;
83
+ }
84
+ const result = full.slice(0, i);
85
+ // Pad if needed (wide char couldn't fill exact width)
86
+ const gap = width - w;
87
+ return gap > 0 ? result + " ".repeat(gap) : result;
88
+ }
89
+ function resolveStyle(style) {
90
+ if (style === undefined)
91
+ return NULL_STYLE;
92
+ if (typeof style === "string")
93
+ return Style.parse(style);
94
+ return style;
95
+ }
96
+ //# sourceMappingURL=rule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rule.js","sourceRoot":"","sources":["../../src/renderables/rule.ts"],"names":[],"mappings":"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"}