padrone 1.9.0 → 2.0.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 (328) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +2 -2
  3. package/dist/codegen/code-builder.d.mts +10 -0
  4. package/dist/codegen/code-builder.d.mts.map +1 -0
  5. package/dist/codegen/code-builder.mjs +185 -0
  6. package/dist/codegen/code-builder.mjs.map +1 -0
  7. package/dist/codegen/discovery.d.mts +44 -0
  8. package/dist/codegen/discovery.d.mts.map +1 -0
  9. package/dist/codegen/discovery.mjs +179 -0
  10. package/dist/codegen/discovery.mjs.map +1 -0
  11. package/dist/codegen/file-emitter.d.mts +10 -0
  12. package/dist/codegen/file-emitter.d.mts.map +1 -0
  13. package/dist/codegen/file-emitter.mjs +58 -0
  14. package/dist/codegen/file-emitter.mjs.map +1 -0
  15. package/dist/codegen/generators/barrel-file.d.mts +10 -0
  16. package/dist/codegen/generators/barrel-file.d.mts.map +1 -0
  17. package/dist/codegen/generators/barrel-file.mjs +16 -0
  18. package/dist/codegen/generators/barrel-file.mjs.map +1 -0
  19. package/dist/codegen/generators/command-file.d.mts +25 -0
  20. package/dist/codegen/generators/command-file.d.mts.map +1 -0
  21. package/dist/codegen/generators/command-file.mjs +130 -0
  22. package/dist/codegen/generators/command-file.mjs.map +1 -0
  23. package/dist/codegen/generators/command-tree.d.mts +17 -0
  24. package/dist/codegen/generators/command-tree.d.mts.map +1 -0
  25. package/dist/codegen/generators/command-tree.mjs +72 -0
  26. package/dist/codegen/generators/command-tree.mjs.map +1 -0
  27. package/dist/codegen/index.d.mts +15 -330
  28. package/dist/codegen/index.mjs +13 -1507
  29. package/dist/codegen/parsers/bash.d.mts +19 -0
  30. package/dist/codegen/parsers/bash.d.mts.map +1 -0
  31. package/dist/codegen/parsers/bash.mjs +112 -0
  32. package/dist/codegen/parsers/bash.mjs.map +1 -0
  33. package/dist/codegen/parsers/fish.d.mts +13 -0
  34. package/dist/codegen/parsers/fish.d.mts.map +1 -0
  35. package/dist/codegen/parsers/fish.mjs +108 -0
  36. package/dist/codegen/parsers/fish.mjs.map +1 -0
  37. package/dist/codegen/parsers/help.d.mts +15 -0
  38. package/dist/codegen/parsers/help.d.mts.map +1 -0
  39. package/dist/codegen/parsers/help.mjs +271 -0
  40. package/dist/codegen/parsers/help.mjs.map +1 -0
  41. package/dist/codegen/parsers/merge.d.mts +14 -0
  42. package/dist/codegen/parsers/merge.d.mts.map +1 -0
  43. package/dist/codegen/parsers/merge.mjs +76 -0
  44. package/dist/codegen/parsers/merge.mjs.map +1 -0
  45. package/dist/codegen/parsers/zsh.d.mts +16 -0
  46. package/dist/codegen/parsers/zsh.d.mts.map +1 -0
  47. package/dist/codegen/parsers/zsh.mjs +161 -0
  48. package/dist/codegen/parsers/zsh.mjs.map +1 -0
  49. package/dist/codegen/schema-to-code.d.mts +24 -0
  50. package/dist/codegen/schema-to-code.d.mts.map +1 -0
  51. package/dist/codegen/schema-to-code.mjs +147 -0
  52. package/dist/codegen/schema-to-code.mjs.map +1 -0
  53. package/dist/codegen/template.d.mts +18 -0
  54. package/dist/codegen/template.d.mts.map +1 -0
  55. package/dist/codegen/template.mjs +37 -0
  56. package/dist/codegen/template.mjs.map +1 -0
  57. package/dist/codegen/types.d.mts +144 -0
  58. package/dist/codegen/types.d.mts.map +1 -0
  59. package/dist/completion.d.mts +2 -0
  60. package/dist/completion.mjs +2 -0
  61. package/dist/core/args.d.mts +3 -0
  62. package/dist/{args-WmyGc59s.mjs → core/args.mjs} +5 -81
  63. package/dist/core/args.mjs.map +1 -0
  64. package/dist/core/commands.d.mts +13 -0
  65. package/dist/core/commands.d.mts.map +1 -0
  66. package/dist/{commands-ohEApqIw.mjs → core/commands.mjs} +4 -232
  67. package/dist/core/commands.mjs.map +1 -0
  68. package/dist/core/create.d.mts +63 -0
  69. package/dist/core/create.d.mts.map +1 -0
  70. package/dist/core/create.mjs +230 -0
  71. package/dist/core/create.mjs.map +1 -0
  72. package/dist/core/default-runtime.mjs +198 -0
  73. package/dist/core/default-runtime.mjs.map +1 -0
  74. package/dist/core/errors.d.mts +107 -0
  75. package/dist/core/errors.d.mts.map +1 -0
  76. package/dist/{errors-DA4KzK1M.mjs → core/errors.mjs} +2 -2
  77. package/dist/core/errors.mjs.map +1 -0
  78. package/dist/core/exec.mjs +191 -0
  79. package/dist/core/exec.mjs.map +1 -0
  80. package/dist/core/interceptors.d.mts +33 -0
  81. package/dist/core/interceptors.d.mts.map +1 -0
  82. package/dist/core/interceptors.mjs +253 -0
  83. package/dist/core/interceptors.mjs.map +1 -0
  84. package/dist/core/parse.mjs +181 -0
  85. package/dist/core/parse.mjs.map +1 -0
  86. package/dist/core/program-methods.mjs +256 -0
  87. package/dist/core/program-methods.mjs.map +1 -0
  88. package/dist/core/results.d.mts +13 -0
  89. package/dist/core/results.d.mts.map +1 -0
  90. package/dist/core/results.mjs +150 -0
  91. package/dist/core/results.mjs.map +1 -0
  92. package/dist/core/runtime.d.mts +213 -0
  93. package/dist/core/runtime.d.mts.map +1 -0
  94. package/dist/core/runtime.mjs +10 -0
  95. package/dist/core/runtime.mjs.map +1 -0
  96. package/dist/core/validate.mjs +220 -0
  97. package/dist/core/validate.mjs.map +1 -0
  98. package/dist/docs/index.d.mts +1 -1
  99. package/dist/docs/index.d.mts.map +1 -1
  100. package/dist/docs/index.mjs +2 -2
  101. package/dist/docs/index.mjs.map +1 -1
  102. package/dist/extension/auto-output.d.mts +53 -0
  103. package/dist/extension/auto-output.d.mts.map +1 -0
  104. package/dist/extension/auto-output.mjs +116 -0
  105. package/dist/extension/auto-output.mjs.map +1 -0
  106. package/dist/extension/color.d.mts +19 -0
  107. package/dist/extension/color.d.mts.map +1 -0
  108. package/dist/extension/color.mjs +37 -0
  109. package/dist/extension/color.mjs.map +1 -0
  110. package/dist/extension/completion.d.mts +25 -0
  111. package/dist/extension/completion.d.mts.map +1 -0
  112. package/dist/extension/completion.mjs +40 -0
  113. package/dist/extension/completion.mjs.map +1 -0
  114. package/dist/extension/config.d.mts +55 -0
  115. package/dist/extension/config.d.mts.map +1 -0
  116. package/dist/extension/config.mjs +162 -0
  117. package/dist/extension/config.mjs.map +1 -0
  118. package/dist/extension/env.d.mts +42 -0
  119. package/dist/extension/env.d.mts.map +1 -0
  120. package/dist/extension/env.mjs +44 -0
  121. package/dist/extension/env.mjs.map +1 -0
  122. package/dist/extension/help.d.mts +29 -0
  123. package/dist/extension/help.d.mts.map +1 -0
  124. package/dist/extension/help.mjs +161 -0
  125. package/dist/extension/help.mjs.map +1 -0
  126. package/dist/extension/index.d.mts +18 -0
  127. package/dist/extension/ink.d.mts +31 -0
  128. package/dist/extension/ink.d.mts.map +1 -0
  129. package/dist/extension/ink.mjs +69 -0
  130. package/dist/extension/ink.mjs.map +1 -0
  131. package/dist/extension/interactive.d.mts +16 -0
  132. package/dist/extension/interactive.d.mts.map +1 -0
  133. package/dist/extension/interactive.mjs +89 -0
  134. package/dist/extension/interactive.mjs.map +1 -0
  135. package/dist/extension/logger.d.mts +67 -0
  136. package/dist/extension/logger.d.mts.map +1 -0
  137. package/dist/extension/logger.mjs +188 -0
  138. package/dist/extension/logger.mjs.map +1 -0
  139. package/dist/extension/man.d.mts +25 -0
  140. package/dist/extension/man.d.mts.map +1 -0
  141. package/dist/extension/man.mjs +41 -0
  142. package/dist/extension/man.mjs.map +1 -0
  143. package/dist/extension/mcp.d.mts +28 -0
  144. package/dist/extension/mcp.d.mts.map +1 -0
  145. package/dist/extension/mcp.mjs +44 -0
  146. package/dist/extension/mcp.mjs.map +1 -0
  147. package/dist/extension/progress-renderer.d.mts +13 -0
  148. package/dist/extension/progress-renderer.d.mts.map +1 -0
  149. package/dist/extension/progress-renderer.mjs +351 -0
  150. package/dist/extension/progress-renderer.mjs.map +1 -0
  151. package/dist/extension/progress.d.mts +76 -0
  152. package/dist/extension/progress.d.mts.map +1 -0
  153. package/dist/extension/progress.mjs +225 -0
  154. package/dist/extension/progress.mjs.map +1 -0
  155. package/dist/extension/repl.d.mts +26 -0
  156. package/dist/extension/repl.d.mts.map +1 -0
  157. package/dist/extension/repl.mjs +67 -0
  158. package/dist/extension/repl.mjs.map +1 -0
  159. package/dist/extension/serve.d.mts +27 -0
  160. package/dist/extension/serve.d.mts.map +1 -0
  161. package/dist/extension/serve.mjs +41 -0
  162. package/dist/extension/serve.mjs.map +1 -0
  163. package/dist/extension/signal.d.mts +19 -0
  164. package/dist/extension/signal.d.mts.map +1 -0
  165. package/dist/extension/signal.mjs +81 -0
  166. package/dist/extension/signal.mjs.map +1 -0
  167. package/dist/extension/stdin.d.mts +19 -0
  168. package/dist/extension/stdin.d.mts.map +1 -0
  169. package/dist/extension/stdin.mjs +52 -0
  170. package/dist/extension/stdin.mjs.map +1 -0
  171. package/dist/extension/suggestions.d.mts +6 -0
  172. package/dist/extension/suggestions.d.mts.map +1 -0
  173. package/dist/extension/suggestions.mjs +113 -0
  174. package/dist/extension/suggestions.mjs.map +1 -0
  175. package/dist/extension/timing.d.mts +27 -0
  176. package/dist/extension/timing.d.mts.map +1 -0
  177. package/dist/extension/timing.mjs +71 -0
  178. package/dist/extension/timing.mjs.map +1 -0
  179. package/dist/extension/tracing.d.mts +85 -0
  180. package/dist/extension/tracing.d.mts.map +1 -0
  181. package/dist/extension/tracing.mjs +107 -0
  182. package/dist/extension/tracing.mjs.map +1 -0
  183. package/dist/extension/update-check.d.mts +20 -0
  184. package/dist/extension/update-check.d.mts.map +1 -0
  185. package/dist/extension/update-check.mjs +62 -0
  186. package/dist/extension/update-check.mjs.map +1 -0
  187. package/dist/extension/utils.mjs +43 -0
  188. package/dist/extension/utils.mjs.map +1 -0
  189. package/dist/extension/version.d.mts +20 -0
  190. package/dist/extension/version.d.mts.map +1 -0
  191. package/dist/extension/version.mjs +51 -0
  192. package/dist/extension/version.mjs.map +1 -0
  193. package/dist/{completion-D8qkAinX.mjs → feature/completion.mjs} +4 -3
  194. package/dist/feature/completion.mjs.map +1 -0
  195. package/dist/feature/interactive.mjs +145 -0
  196. package/dist/feature/interactive.mjs.map +1 -0
  197. package/dist/feature/mcp.d.mts +18 -0
  198. package/dist/feature/mcp.d.mts.map +1 -0
  199. package/dist/{mcp-wCoVFTXz.mjs → feature/mcp.mjs} +6 -6
  200. package/dist/feature/mcp.mjs.map +1 -0
  201. package/dist/feature/repl-loop.mjs +217 -0
  202. package/dist/feature/repl-loop.mjs.map +1 -0
  203. package/dist/feature/serve.d.mts +18 -0
  204. package/dist/feature/serve.d.mts.map +1 -0
  205. package/dist/{serve-ICZFl3xr.mjs → feature/serve.mjs} +7 -7
  206. package/dist/feature/serve.mjs.map +1 -0
  207. package/dist/feature/test.d.mts +109 -0
  208. package/dist/feature/test.d.mts.map +1 -0
  209. package/dist/feature/test.mjs +116 -0
  210. package/dist/feature/test.mjs.map +1 -0
  211. package/dist/feature/update-check.d.mts +35 -0
  212. package/dist/feature/update-check.d.mts.map +1 -0
  213. package/dist/{update-check-CZ2VqjnV.mjs → feature/update-check.mjs} +2 -2
  214. package/dist/feature/update-check.mjs.map +1 -0
  215. package/dist/feature/wrap.d.mts +58 -0
  216. package/dist/feature/wrap.d.mts.map +1 -0
  217. package/dist/feature/wrap.mjs +77 -0
  218. package/dist/feature/wrap.mjs.map +1 -0
  219. package/dist/index.d.mts +38 -902
  220. package/dist/index.mjs +25 -4377
  221. package/dist/ink.d.mts +2 -0
  222. package/dist/ink.mjs +2 -0
  223. package/dist/man.d.mts +2 -0
  224. package/dist/man.mjs +2 -0
  225. package/dist/mcp.d.mts +3 -0
  226. package/dist/mcp.mjs +2 -0
  227. package/dist/output/colorizer.d.mts +28 -0
  228. package/dist/output/colorizer.d.mts.map +1 -0
  229. package/dist/output/colorizer.mjs +94 -0
  230. package/dist/output/colorizer.mjs.map +1 -0
  231. package/dist/{formatter-CY3KrOEd.d.mts → output/formatter.d.mts} +2 -28
  232. package/dist/output/formatter.d.mts.map +1 -0
  233. package/dist/output/formatter.mjs +360 -0
  234. package/dist/output/formatter.mjs.map +1 -0
  235. package/dist/output/help.d.mts +18 -0
  236. package/dist/output/help.d.mts.map +1 -0
  237. package/dist/output/help.mjs +267 -0
  238. package/dist/output/help.mjs.map +1 -0
  239. package/dist/output/output-indicator.d.mts +27 -0
  240. package/dist/output/output-indicator.d.mts.map +1 -0
  241. package/dist/output/output-indicator.mjs +54 -0
  242. package/dist/output/output-indicator.mjs.map +1 -0
  243. package/dist/output/primitives.d.mts +33 -0
  244. package/dist/output/primitives.d.mts.map +1 -0
  245. package/dist/output/primitives.mjs +206 -0
  246. package/dist/output/primitives.mjs.map +1 -0
  247. package/dist/output/styling.d.mts +38 -0
  248. package/dist/output/styling.d.mts.map +1 -0
  249. package/dist/output/styling.mjs +146 -0
  250. package/dist/output/styling.mjs.map +1 -0
  251. package/dist/schema/zod.d.mts +6 -0
  252. package/dist/schema/zod.d.mts.map +1 -0
  253. package/dist/schema/zod.mjs +50 -0
  254. package/dist/schema/zod.mjs.map +1 -0
  255. package/dist/serve.d.mts +2 -0
  256. package/dist/serve.mjs +2 -0
  257. package/dist/test.d.mts +2 -109
  258. package/dist/test.mjs +1 -115
  259. package/dist/tracing.d.mts +2 -0
  260. package/dist/tracing.mjs +2 -0
  261. package/dist/types/args-meta.d.mts +129 -0
  262. package/dist/types/args-meta.d.mts.map +1 -0
  263. package/dist/types/builder.d.mts +212 -0
  264. package/dist/types/builder.d.mts.map +1 -0
  265. package/dist/types/command.d.mts +112 -0
  266. package/dist/types/command.d.mts.map +1 -0
  267. package/dist/types/index.d.mts +8 -0
  268. package/dist/types/interceptor.d.mts +232 -0
  269. package/dist/types/interceptor.d.mts.map +1 -0
  270. package/dist/types/preferences.d.mts +79 -0
  271. package/dist/types/preferences.d.mts.map +1 -0
  272. package/dist/types/result.d.mts +61 -0
  273. package/dist/types/result.d.mts.map +1 -0
  274. package/dist/types/schema.d.mts +24 -0
  275. package/dist/types/schema.d.mts.map +1 -0
  276. package/dist/util/dotenv.mjs +174 -0
  277. package/dist/util/dotenv.mjs.map +1 -0
  278. package/dist/util/shell-utils.mjs +80 -0
  279. package/dist/util/shell-utils.mjs.map +1 -0
  280. package/dist/util/stream.d.mts +33 -0
  281. package/dist/util/stream.d.mts.map +1 -0
  282. package/dist/{stream-DC4H8YTx.mjs → util/stream.mjs} +2 -2
  283. package/dist/util/stream.mjs.map +1 -0
  284. package/dist/util/type-helpers.d.mts +74 -0
  285. package/dist/util/type-helpers.d.mts.map +1 -0
  286. package/dist/util/type-utils.d.mts +186 -0
  287. package/dist/util/type-utils.d.mts.map +1 -0
  288. package/dist/util/utils.mjs +43 -0
  289. package/dist/util/utils.mjs.map +1 -0
  290. package/dist/zod.d.mts +1 -32
  291. package/dist/zod.mjs +1 -49
  292. package/package.json +65 -17
  293. package/src/completion.ts +2 -0
  294. package/src/extension/completion.ts +3 -0
  295. package/src/extension/index.ts +0 -12
  296. package/src/extension/ink.ts +2 -1
  297. package/src/extension/man.ts +3 -0
  298. package/src/extension/mcp.ts +3 -0
  299. package/src/extension/serve.ts +3 -0
  300. package/src/extension/tracing.ts +2 -0
  301. package/src/index.ts +0 -19
  302. package/src/ink.ts +2 -0
  303. package/src/man.ts +2 -0
  304. package/src/mcp.ts +3 -0
  305. package/src/serve.ts +2 -0
  306. package/src/tracing.ts +9 -0
  307. package/src/zod.ts +1 -1
  308. package/dist/args-WmyGc59s.mjs.map +0 -1
  309. package/dist/codegen/index.d.mts.map +0 -1
  310. package/dist/codegen/index.mjs.map +0 -1
  311. package/dist/commands-ohEApqIw.mjs.map +0 -1
  312. package/dist/completion-D8qkAinX.mjs.map +0 -1
  313. package/dist/errors-DA4KzK1M.mjs.map +0 -1
  314. package/dist/formatter-CY3KrOEd.d.mts.map +0 -1
  315. package/dist/help-CeI45CJx.mjs +0 -892
  316. package/dist/help-CeI45CJx.mjs.map +0 -1
  317. package/dist/index-C3Ed1LYN.d.mts +0 -1432
  318. package/dist/index-C3Ed1LYN.d.mts.map +0 -1
  319. package/dist/index.d.mts.map +0 -1
  320. package/dist/index.mjs.map +0 -1
  321. package/dist/mcp-wCoVFTXz.mjs.map +0 -1
  322. package/dist/serve-ICZFl3xr.mjs.map +0 -1
  323. package/dist/stream-DC4H8YTx.mjs.map +0 -1
  324. package/dist/test.d.mts.map +0 -1
  325. package/dist/test.mjs.map +0 -1
  326. package/dist/update-check-CZ2VqjnV.mjs.map +0 -1
  327. package/dist/zod.d.mts.map +0 -1
  328. package/dist/zod.mjs.map +0 -1
@@ -0,0 +1,351 @@
1
+ //#region src/extension/progress-renderer.ts
2
+ const spinnerPresets = {
3
+ dots: [
4
+ "⠋",
5
+ "⠙",
6
+ "⠹",
7
+ "⠸",
8
+ "⠼",
9
+ "⠴",
10
+ "⠦",
11
+ "⠧",
12
+ "⠇",
13
+ "⠏"
14
+ ],
15
+ line: [
16
+ "-",
17
+ "\\",
18
+ "|",
19
+ "/"
20
+ ],
21
+ arc: [
22
+ "◜",
23
+ "◠",
24
+ "◝",
25
+ "◞",
26
+ "◡",
27
+ "◟"
28
+ ],
29
+ bounce: [
30
+ "⠁",
31
+ "⠂",
32
+ "⠄",
33
+ "⡀",
34
+ "⢀",
35
+ "⠠",
36
+ "⠐",
37
+ "⠈"
38
+ ]
39
+ };
40
+ function resolveSpinnerConfig(config) {
41
+ if (config === false) return {
42
+ frames: [],
43
+ interval: 80,
44
+ show: "never"
45
+ };
46
+ if (config === true) return {
47
+ frames: spinnerPresets.dots,
48
+ interval: 80,
49
+ show: "always"
50
+ };
51
+ if (typeof config === "string") return {
52
+ frames: spinnerPresets[config],
53
+ interval: 80,
54
+ show: "auto"
55
+ };
56
+ if (typeof config === "object") return {
57
+ frames: config.frames ?? spinnerPresets.dots,
58
+ interval: config.interval ?? 80,
59
+ show: config.show ?? "auto"
60
+ };
61
+ return {
62
+ frames: spinnerPresets.dots,
63
+ interval: 80,
64
+ show: "auto"
65
+ };
66
+ }
67
+ const defaultBarConfig = {
68
+ width: 20,
69
+ filled: "█",
70
+ empty: "░",
71
+ animation: "bounce",
72
+ show: "auto"
73
+ };
74
+ function resolveBarConfig(bar) {
75
+ if (bar === false) return void 0;
76
+ if (!bar) return { ...defaultBarConfig };
77
+ if (bar === true) return {
78
+ ...defaultBarConfig,
79
+ show: "always"
80
+ };
81
+ return {
82
+ width: bar.width ?? 20,
83
+ filled: bar.filled ?? "█",
84
+ empty: bar.empty ?? "░",
85
+ animation: bar.animation ?? "bounce",
86
+ show: bar.show ?? "always"
87
+ };
88
+ }
89
+ const SEGMENT_RATIO = .25;
90
+ const pulseGradient = [
91
+ "░",
92
+ "▒",
93
+ "▓",
94
+ "█",
95
+ "▓",
96
+ "▒",
97
+ "░"
98
+ ];
99
+ function formatIndeterminate(cfg, frame) {
100
+ const { width, filled, empty, animation } = cfg;
101
+ const pad = "".padStart(4);
102
+ if (animation === "pulse") return `${pad} ${pulseGradient[frame % pulseGradient.length].repeat(width)}`;
103
+ const seg = Math.max(2, Math.round(width * SEGMENT_RATIO));
104
+ const travel = width - seg;
105
+ if (animation === "slide") {
106
+ const offset = frame % (travel + 1);
107
+ return `${pad} ${empty.repeat(offset)}${filled.repeat(seg)}${empty.repeat(travel - offset)}`;
108
+ }
109
+ const cycle = travel * 2;
110
+ const pos = frame % cycle;
111
+ const offset = pos <= travel ? pos : cycle - pos;
112
+ return `${pad} ${empty.repeat(offset)}${filled.repeat(seg)}${empty.repeat(width - offset - seg)}`;
113
+ }
114
+ function formatBar(progress, cfg, frame) {
115
+ if (progress === void 0) return formatIndeterminate(cfg, frame);
116
+ const { width, filled, empty } = cfg;
117
+ const clamped = Math.max(0, Math.min(1, progress));
118
+ const filledCount = Math.round(clamped * width);
119
+ return `${`${Math.round(clamped * 100)}%`.padStart(4)} ${filled.repeat(filledCount)}${empty.repeat(width - filledCount)}`;
120
+ }
121
+ function parseUpdate(value) {
122
+ if (typeof value === "string") return { message: value };
123
+ if (typeof value === "number") return { progress: value };
124
+ return value;
125
+ }
126
+ function formatDuration(ms) {
127
+ const totalSeconds = Math.floor(ms / 1e3);
128
+ const hours = Math.floor(totalSeconds / 3600);
129
+ const minutes = Math.floor(totalSeconds % 3600 / 60);
130
+ const seconds = totalSeconds % 60;
131
+ if (hours > 0) return `${hours}:${String(minutes).padStart(2, "0")}:${String(seconds).padStart(2, "0")}`;
132
+ return `${minutes}:${String(seconds).padStart(2, "0")}`;
133
+ }
134
+ function estimateEta(samples) {
135
+ if (samples.length < 2) return void 0;
136
+ const first = samples[0];
137
+ const last = samples[samples.length - 1];
138
+ const progressDelta = last.progress - first.progress;
139
+ if (progressDelta <= 0) return void 0;
140
+ const rate = progressDelta / (last.time - first.time);
141
+ const remaining = 1 - last.progress;
142
+ if (remaining <= 0) return 0;
143
+ return remaining / rate;
144
+ }
145
+ /**
146
+ * Creates a terminal progress indicator (spinner, bar, or both).
147
+ * Returns a no-op indicator in non-TTY/CI environments.
148
+ */
149
+ function createTerminalProgress(message, options) {
150
+ const spinnerCfg = resolveSpinnerConfig(options?.spinner);
151
+ const successIcon = options?.successIndicator ?? "✔";
152
+ const errorIcon = options?.errorIndicator ?? "✖";
153
+ const barCfg = resolveBarConfig(options?.bar);
154
+ const formatFinal = (icon, msg) => icon ? `${icon} ${msg}\n` : `${msg}\n`;
155
+ if (typeof process === "undefined" || !process.stderr?.isTTY) return {
156
+ update() {},
157
+ eta: {
158
+ start() {},
159
+ stop() {},
160
+ reset() {}
161
+ },
162
+ succeed(msg, opts) {
163
+ if (msg === null) return;
164
+ const icon = opts?.indicator ?? successIcon;
165
+ if (msg || message) process?.stderr?.write?.(formatFinal(icon, msg || message));
166
+ },
167
+ fail(msg, opts) {
168
+ if (msg === null) return;
169
+ const icon = opts?.indicator ?? errorIcon;
170
+ if (msg || message) process?.stderr?.write?.(formatFinal(icon, msg || message));
171
+ },
172
+ stop() {},
173
+ pause() {},
174
+ resume() {}
175
+ };
176
+ const ansiPattern = /\x1b\[[0-9;]*m/g;
177
+ if (spinnerCfg.show === "never" && (!barCfg || barCfg.show === "never") && !message) return {
178
+ update() {},
179
+ eta: {
180
+ start() {},
181
+ stop() {},
182
+ reset() {}
183
+ },
184
+ succeed() {},
185
+ fail() {},
186
+ stop() {},
187
+ pause() {},
188
+ resume() {}
189
+ };
190
+ const showTime = options?.time ?? false;
191
+ let etaEnabled = options?.eta ?? false;
192
+ let spinnerFrame = 0;
193
+ let barFrame = 0;
194
+ let text = message;
195
+ let progress;
196
+ let indeterminate = false;
197
+ let stopped = false;
198
+ let paused = false;
199
+ let timeEnabled = showTime;
200
+ let startTime = showTime ? Date.now() : 0;
201
+ const etaSamples = [];
202
+ let etaMs;
203
+ let etaCalculatedAt = 0;
204
+ const writeStderr = process.stderr.write.bind(process.stderr);
205
+ const writeStdout = process.stdout.write.bind(process.stdout);
206
+ let prevLineCount = 0;
207
+ const clearLines = () => {
208
+ if (prevLineCount > 1) for (let i = 1; i < prevLineCount; i++) writeStderr("\x1B[1A\x1B[2K");
209
+ writeStderr("\x1B[2K\r");
210
+ prevLineCount = 0;
211
+ };
212
+ /** Count how many terminal rows `str` occupies, accounting for line wrapping. */
213
+ const lineCount = (str) => {
214
+ const cols = process.stderr.columns || 80;
215
+ const visible = str.replace(ansiPattern, "");
216
+ return Math.max(1, Math.ceil(visible.length / cols));
217
+ };
218
+ const render = () => {
219
+ if (paused || stopped) return;
220
+ const barVisible = barCfg && (barCfg.show === "always" || barCfg.show === "auto" && (progress !== void 0 || indeterminate));
221
+ const spinnerVisible = spinnerCfg.show === "always" || spinnerCfg.show === "auto" && !barVisible;
222
+ let line = "";
223
+ if (barVisible) line += formatBar(progress, barCfg, barFrame);
224
+ const hasEta = etaEnabled && progress !== void 0 && progress < 1 && etaMs !== void 0;
225
+ if (timeEnabled || hasEta) {
226
+ const parts = [];
227
+ if (timeEnabled) parts.push(`⏱ ${formatDuration(Date.now() - startTime)}`);
228
+ if (hasEta) {
229
+ const elapsed = Date.now() - etaCalculatedAt;
230
+ parts.push(`ETA ${formatDuration(Math.max(0, etaMs - elapsed))}`);
231
+ }
232
+ if (line) line += " ";
233
+ line += parts.join(" | ");
234
+ }
235
+ if (spinnerVisible) {
236
+ if (line) line += " ";
237
+ line += frames[spinnerFrame] ?? "";
238
+ }
239
+ if (text) {
240
+ if (line) line += " ";
241
+ line += text;
242
+ }
243
+ if (line) {
244
+ clearLines();
245
+ writeStderr(line);
246
+ prevLineCount = lineCount(line);
247
+ } else clearLines();
248
+ };
249
+ const { frames } = spinnerCfg;
250
+ const needsAnimation = spinnerCfg.show !== "never" || barCfg && barCfg.show !== "never";
251
+ const tickInterval = barCfg && barCfg.show !== "never" ? Math.min(80, spinnerCfg.interval) : spinnerCfg.interval;
252
+ const timer = needsAnimation ? setInterval(() => {
253
+ spinnerFrame = (spinnerFrame + 1) % (frames.length || 1);
254
+ barFrame++;
255
+ render();
256
+ }, tickInterval) : void 0;
257
+ if (timer && typeof timer === "object" && "unref" in timer) timer.unref();
258
+ render();
259
+ const clear = () => {
260
+ if (stopped) return;
261
+ stopped = true;
262
+ paused = false;
263
+ if (timer) clearInterval(timer);
264
+ clearLines();
265
+ };
266
+ return {
267
+ update(value) {
268
+ if (stopped) return;
269
+ const parsed = parseUpdate(value);
270
+ if (parsed.message !== void 0) text = parsed.message;
271
+ if (parsed.progress !== void 0) {
272
+ progress = parsed.progress;
273
+ if (etaEnabled) {
274
+ const now = Date.now();
275
+ etaSamples.push({
276
+ time: now,
277
+ progress: parsed.progress
278
+ });
279
+ const estimated = estimateEta(etaSamples);
280
+ if (estimated !== void 0) {
281
+ etaMs = estimated;
282
+ etaCalculatedAt = now;
283
+ }
284
+ }
285
+ }
286
+ if (parsed.indeterminate !== void 0) {
287
+ indeterminate = parsed.indeterminate;
288
+ if (indeterminate) progress = void 0;
289
+ }
290
+ if (parsed.time !== void 0) {
291
+ if (parsed.time && !timeEnabled) {
292
+ timeEnabled = true;
293
+ startTime = Date.now();
294
+ } else if (!parsed.time) timeEnabled = false;
295
+ }
296
+ render();
297
+ },
298
+ eta: {
299
+ start() {
300
+ if (stopped) return;
301
+ etaEnabled = true;
302
+ render();
303
+ },
304
+ stop() {
305
+ if (stopped) return;
306
+ etaEnabled = false;
307
+ etaMs = void 0;
308
+ render();
309
+ },
310
+ reset() {
311
+ if (stopped) return;
312
+ etaSamples.length = 0;
313
+ etaMs = void 0;
314
+ etaCalculatedAt = 0;
315
+ render();
316
+ }
317
+ },
318
+ succeed(msg, opts) {
319
+ clear();
320
+ if (msg === null) return;
321
+ const finalMsg = msg ?? text;
322
+ const icon = opts?.indicator ?? successIcon;
323
+ if (finalMsg) writeStderr(formatFinal(icon, finalMsg));
324
+ },
325
+ fail(msg, opts) {
326
+ clear();
327
+ if (msg === null) return;
328
+ const finalMsg = msg ?? text;
329
+ const icon = opts?.indicator ?? errorIcon;
330
+ if (finalMsg) writeStderr(formatFinal(icon, finalMsg));
331
+ },
332
+ stop() {
333
+ clear();
334
+ },
335
+ pause() {
336
+ if (stopped || paused) return;
337
+ paused = true;
338
+ clearLines();
339
+ writeStdout("\x1B[2K\r");
340
+ },
341
+ resume() {
342
+ if (stopped || !paused) return;
343
+ paused = false;
344
+ render();
345
+ }
346
+ };
347
+ }
348
+ //#endregion
349
+ export { createTerminalProgress };
350
+
351
+ //# sourceMappingURL=progress-renderer.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress-renderer.mjs","names":[],"sources":["../../src/extension/progress-renderer.ts"],"sourcesContent":["import type {\n PadroneBarConfig,\n PadroneProgress,\n PadroneProgressOptions,\n PadroneProgressShow,\n PadroneProgressUpdate,\n PadroneSpinnerConfig,\n PadroneSpinnerPreset,\n} from '../core/runtime.ts';\n\n// ---------------------------------------------------------------------------\n// Spinner presets & resolution\n// ---------------------------------------------------------------------------\n\nconst spinnerPresets: Record<PadroneSpinnerPreset, string[]> = {\n dots: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'],\n line: ['-', '\\\\', '|', '/'],\n arc: ['◜', '◠', '◝', '◞', '◡', '◟'],\n bounce: ['⠁', '⠂', '⠄', '⡀', '⢀', '⠠', '⠐', '⠈'],\n};\n\ntype ResolvedSpinnerConfig = { frames: string[]; interval: number; show: PadroneProgressShow };\n\nfunction resolveSpinnerConfig(config?: PadroneSpinnerConfig): ResolvedSpinnerConfig {\n if (config === false) return { frames: [], interval: 80, show: 'never' };\n if (config === true) return { frames: spinnerPresets.dots, interval: 80, show: 'always' };\n if (typeof config === 'string') return { frames: spinnerPresets[config], interval: 80, show: 'auto' };\n if (typeof config === 'object') {\n return {\n frames: config.frames ?? spinnerPresets.dots,\n interval: config.interval ?? 80,\n show: config.show ?? 'auto',\n };\n }\n return { frames: spinnerPresets.dots, interval: 80, show: 'auto' };\n}\n\n// ---------------------------------------------------------------------------\n// Bar resolution & rendering\n// ---------------------------------------------------------------------------\n\ntype ResolvedBarConfig = {\n width: number;\n filled: string;\n empty: string;\n animation: 'bounce' | 'slide' | 'pulse';\n show: PadroneProgressShow;\n};\n\nconst defaultBarConfig: ResolvedBarConfig = { width: 20, filled: '█', empty: '░', animation: 'bounce', show: 'auto' };\n\nfunction resolveBarConfig(bar: boolean | PadroneBarConfig | undefined): ResolvedBarConfig | undefined {\n if (bar === false) return undefined;\n if (!bar) return { ...defaultBarConfig };\n if (bar === true) return { ...defaultBarConfig, show: 'always' };\n return {\n width: bar.width ?? 20,\n filled: bar.filled ?? '█',\n empty: bar.empty ?? '░',\n animation: bar.animation ?? 'bounce',\n show: bar.show ?? 'always',\n };\n}\n\nconst SEGMENT_RATIO = 0.25;\nconst pulseGradient = ['░', '▒', '▓', '█', '▓', '▒', '░'];\n\nfunction formatIndeterminate(cfg: ResolvedBarConfig, frame: number): string {\n const { width, filled, empty, animation } = cfg;\n const pad = ''.padStart(4);\n\n if (animation === 'pulse') {\n const idx = frame % pulseGradient.length;\n return `${pad} ${pulseGradient[idx]!.repeat(width)}`;\n }\n\n const seg = Math.max(2, Math.round(width * SEGMENT_RATIO));\n const travel = width - seg;\n\n if (animation === 'slide') {\n const offset = frame % (travel + 1);\n return `${pad} ${empty.repeat(offset)}${filled.repeat(seg)}${empty.repeat(travel - offset)}`;\n }\n\n // bounce (default)\n const cycle = travel * 2;\n const pos = frame % cycle;\n const offset = pos <= travel ? pos : cycle - pos;\n return `${pad} ${empty.repeat(offset)}${filled.repeat(seg)}${empty.repeat(width - offset - seg)}`;\n}\n\nfunction formatBar(progress: number | undefined, cfg: ResolvedBarConfig, frame: number): string {\n if (progress === undefined) return formatIndeterminate(cfg, frame);\n const { width, filled, empty } = cfg;\n const clamped = Math.max(0, Math.min(1, progress));\n const filledCount = Math.round(clamped * width);\n const pct = `${Math.round(clamped * 100)}%`.padStart(4);\n return `${pct} ${filled.repeat(filledCount)}${empty.repeat(width - filledCount)}`;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction parseUpdate(value: PadroneProgressUpdate): { message?: string; progress?: number; indeterminate?: boolean; time?: boolean } {\n if (typeof value === 'string') return { message: value };\n if (typeof value === 'number') return { progress: value };\n return value;\n}\n\nfunction formatDuration(ms: number): string {\n const totalSeconds = Math.floor(ms / 1000);\n const hours = Math.floor(totalSeconds / 3600);\n const minutes = Math.floor((totalSeconds % 3600) / 60);\n const seconds = totalSeconds % 60;\n if (hours > 0) return `${hours}:${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;\n return `${minutes}:${String(seconds).padStart(2, '0')}`;\n}\n\nfunction estimateEta(samples: { time: number; progress: number }[]): number | undefined {\n if (samples.length < 2) return undefined;\n const first = samples[0]!;\n const last = samples[samples.length - 1]!;\n const progressDelta = last.progress - first.progress;\n if (progressDelta <= 0) return undefined;\n const timeDelta = last.time - first.time;\n const rate = progressDelta / timeDelta;\n const remaining = 1 - last.progress;\n if (remaining <= 0) return 0;\n return remaining / rate;\n}\n\n// ---------------------------------------------------------------------------\n// Factory type\n// ---------------------------------------------------------------------------\n\n/** Factory function that creates a `PadroneProgress`. */\nexport type PadroneProgressRenderer = (message: string, options?: PadroneProgressOptions) => PadroneProgress;\n\n// ---------------------------------------------------------------------------\n// Default terminal renderer\n// ---------------------------------------------------------------------------\n\n/**\n * Creates a terminal progress indicator (spinner, bar, or both).\n * Returns a no-op indicator in non-TTY/CI environments.\n */\nexport function createTerminalProgress(message: string, options?: PadroneProgressOptions): PadroneProgress {\n const spinnerCfg = resolveSpinnerConfig(options?.spinner);\n const successIcon = options?.successIndicator ?? '✔';\n const errorIcon = options?.errorIndicator ?? '✖';\n const barCfg = resolveBarConfig(options?.bar);\n\n const formatFinal = (icon: string, msg: string) => (icon ? `${icon} ${msg}\\n` : `${msg}\\n`);\n\n if (typeof process === 'undefined' || !process.stderr?.isTTY) {\n const noopEta = { start() {}, stop() {}, reset() {} };\n return {\n update() {},\n eta: noopEta,\n succeed(msg, opts) {\n if (msg === null) return;\n const icon = opts?.indicator ?? successIcon;\n if (msg || message) process?.stderr?.write?.(formatFinal(icon, msg || message));\n },\n fail(msg, opts) {\n if (msg === null) return;\n const icon = opts?.indicator ?? errorIcon;\n if (msg || message) process?.stderr?.write?.(formatFinal(icon, msg || message));\n },\n stop() {},\n pause() {},\n resume() {},\n };\n }\n\n // biome-ignore lint/suspicious/noControlCharactersInRegex: ANSI escape stripping requires matching ESC\n const ansiPattern = /\\x1b\\[[0-9;]*m/g;\n\n if (spinnerCfg.show === 'never' && (!barCfg || barCfg.show === 'never') && !message) {\n return { update() {}, eta: { start() {}, stop() {}, reset() {} }, succeed() {}, fail() {}, stop() {}, pause() {}, resume() {} };\n }\n\n const showTime = options?.time ?? false;\n let etaEnabled = options?.eta ?? false;\n\n let spinnerFrame = 0;\n let barFrame = 0;\n let text = message;\n let progress: number | undefined;\n let indeterminate = false;\n let stopped = false;\n let paused = false;\n let timeEnabled = showTime;\n let startTime = showTime ? Date.now() : 0;\n const etaSamples: { time: number; progress: number }[] = [];\n let etaMs: number | undefined;\n let etaCalculatedAt = 0;\n\n const writeStderr = process.stderr.write.bind(process.stderr);\n const writeStdout = process.stdout.write.bind(process.stdout);\n let prevLineCount = 0;\n\n const clearLines = () => {\n if (prevLineCount > 1) {\n // Move cursor up and clear each wrapped line above the current one\n for (let i = 1; i < prevLineCount; i++) writeStderr('\\x1b[1A\\x1b[2K');\n }\n writeStderr('\\x1b[2K\\r');\n prevLineCount = 0;\n };\n\n /** Count how many terminal rows `str` occupies, accounting for line wrapping. */\n const lineCount = (str: string): number => {\n const cols = process.stderr.columns || 80;\n // Strip ANSI escape sequences for accurate width measurement\n const visible = str.replace(ansiPattern, '');\n return Math.max(1, Math.ceil(visible.length / cols));\n };\n\n const render = () => {\n if (paused || stopped) return;\n\n const barVisible = barCfg && (barCfg.show === 'always' || (barCfg.show === 'auto' && (progress !== undefined || indeterminate)));\n const spinnerVisible = spinnerCfg.show === 'always' || (spinnerCfg.show === 'auto' && !barVisible);\n\n let line = '';\n if (barVisible) line += formatBar(progress, barCfg!, barFrame);\n const hasEta = etaEnabled && progress !== undefined && progress < 1 && etaMs !== undefined;\n if (timeEnabled || hasEta) {\n const parts: string[] = [];\n if (timeEnabled) parts.push(`⏱ ${formatDuration(Date.now() - startTime)}`);\n if (hasEta) {\n const elapsed = Date.now() - etaCalculatedAt;\n parts.push(`ETA ${formatDuration(Math.max(0, etaMs! - elapsed))}`);\n }\n if (line) line += ' ';\n line += parts.join(' | ');\n }\n if (spinnerVisible) {\n if (line) line += ' ';\n line += frames[spinnerFrame] ?? '';\n }\n if (text) {\n if (line) line += ' ';\n line += text;\n }\n\n if (line) {\n clearLines();\n writeStderr(line);\n prevLineCount = lineCount(line);\n } else {\n clearLines();\n }\n };\n\n const { frames } = spinnerCfg;\n const needsAnimation = spinnerCfg.show !== 'never' || (barCfg && barCfg.show !== 'never');\n const tickInterval = barCfg && barCfg.show !== 'never' ? Math.min(80, spinnerCfg.interval) : spinnerCfg.interval;\n\n const timer = needsAnimation\n ? setInterval(() => {\n spinnerFrame = (spinnerFrame + 1) % (frames.length || 1);\n barFrame++;\n render();\n }, tickInterval)\n : undefined;\n\n // Prevent the spinner timer from keeping the process alive on uncaught errors\n if (timer && typeof timer === 'object' && 'unref' in timer) (timer as NodeJS.Timeout).unref();\n\n render();\n\n const clear = () => {\n if (stopped) return;\n stopped = true;\n paused = false;\n if (timer) clearInterval(timer);\n clearLines();\n };\n\n const eta = {\n start() {\n if (stopped) return;\n etaEnabled = true;\n render();\n },\n stop() {\n if (stopped) return;\n etaEnabled = false;\n etaMs = undefined;\n render();\n },\n reset() {\n if (stopped) return;\n etaSamples.length = 0;\n etaMs = undefined;\n etaCalculatedAt = 0;\n render();\n },\n };\n\n return {\n update(value) {\n if (stopped) return;\n const parsed = parseUpdate(value);\n if (parsed.message !== undefined) text = parsed.message;\n if (parsed.progress !== undefined) {\n progress = parsed.progress;\n if (etaEnabled) {\n const now = Date.now();\n etaSamples.push({ time: now, progress: parsed.progress });\n const estimated = estimateEta(etaSamples);\n if (estimated !== undefined) {\n etaMs = estimated;\n etaCalculatedAt = now;\n }\n }\n }\n if (parsed.indeterminate !== undefined) {\n indeterminate = parsed.indeterminate;\n if (indeterminate) progress = undefined;\n }\n if (parsed.time !== undefined) {\n if (parsed.time && !timeEnabled) {\n timeEnabled = true;\n startTime = Date.now();\n } else if (!parsed.time) {\n timeEnabled = false;\n }\n }\n render();\n },\n eta,\n succeed(msg, opts) {\n clear();\n if (msg === null) return;\n const finalMsg = msg ?? text;\n const icon = opts?.indicator ?? successIcon;\n if (finalMsg) writeStderr(formatFinal(icon, finalMsg));\n },\n fail(msg, opts) {\n clear();\n if (msg === null) return;\n const finalMsg = msg ?? text;\n const icon = opts?.indicator ?? errorIcon;\n if (finalMsg) writeStderr(formatFinal(icon, finalMsg));\n },\n stop() {\n clear();\n },\n pause() {\n if (stopped || paused) return;\n paused = true;\n clearLines();\n writeStdout('\\x1b[2K\\r');\n },\n resume() {\n if (stopped || !paused) return;\n paused = false;\n render();\n },\n };\n}\n"],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ import { PadroneBarConfig, PadroneProgress, PadroneSpinnerConfig } from "../core/runtime.mjs";
2
+ import { WithInterceptor } from "../util/type-utils.mjs";
3
+ import { CommandTypesBase } from "../types/command.mjs";
4
+ import { PadroneProgressRenderer } from "./progress-renderer.mjs";
5
+
6
+ //#region src/extension/progress.d.ts
7
+ /** A progress message value: a plain string, `null` to suppress, or an object with a message and custom indicator icon. */
8
+ type PadroneProgressMessage = string | null | {
9
+ message?: string | null;
10
+ indicator?: string;
11
+ };
12
+ /** Per-phase message configuration for progress indicators. */
13
+ type PadroneProgressMessages<TRes = unknown> = {
14
+ /** Message shown during async validation. Defaults to `''` (spinner only). */validation?: string; /** Message shown while the command's action is running. */
15
+ progress?: string; /** Message shown when the command succeeds. `null` to suppress. Defaults to the `progress` message. */
16
+ success?: PadroneProgressMessage | ((result: TRes) => PadroneProgressMessage); /** Message shown when the command fails. `null` to suppress. Defaults to the error message. */
17
+ error?: PadroneProgressMessage | ((error: unknown) => PadroneProgressMessage);
18
+ };
19
+ /**
20
+ * Progress indicator configuration with messages, visual options, and renderer.
21
+ */
22
+ type PadroneProgressConfig<TRes = unknown> = {
23
+ /** Per-phase messages. A string sets the `progress` message; an object configures individual phases. */message?: string | PadroneProgressMessages<TRes>; /** Spinner configuration. Default `show` is `'auto'` (visible when bar is not shown). `true` forces spinner to always show (even alongside a bar). */
24
+ spinner?: PadroneSpinnerConfig; /** Enable a progress bar. `true` for defaults (`show: 'always'`), or a `PadroneBarConfig` object. `false` to disable entirely. When omitted, bar defaults to `show: 'auto'`. */
25
+ bar?: boolean | PadroneBarConfig; /** Show elapsed time since the indicator started. Can also be started on demand via `update({ time: true })`. */
26
+ time?: boolean; /** Show estimated time remaining based on progress rate. Requires numeric `update()` calls. */
27
+ eta?: boolean;
28
+ /**
29
+ * Custom renderer factory. Called to create the progress indicator.
30
+ * Defaults to the built-in terminal renderer (`createTerminalProgress`).
31
+ */
32
+ renderer?: PadroneProgressRenderer; /** Suppress all progress output. The `progress` interface is still provided on the context as a no-op. */
33
+ silent?: boolean;
34
+ };
35
+ /**
36
+ * Shared progress defaults that can be provided via context instead of repeating
37
+ * at each call site. Per-instance message fields are excluded — those always come
38
+ * from the constructor argument.
39
+ *
40
+ * Provide via context as `{ progressConfig: PadroneProgressDefaults }`.
41
+ */
42
+ type PadroneProgressDefaults = Pick<PadroneProgressConfig, 'message' | 'spinner' | 'bar' | 'time' | 'eta' | 'renderer' | 'silent'>;
43
+ /** Builder/program type after applying `padroneProgress()`. Adds `{ progress: PadroneProgress }` to the command context. */
44
+ type WithProgress<T> = WithInterceptor<T, {
45
+ progress: PadroneProgress;
46
+ }>;
47
+ /**
48
+ * Extension that adds an auto-managed progress indicator to the command pipeline.
49
+ *
50
+ * - `string` — a single message used for all states.
51
+ * - `PadroneProgressConfig` — separate messages for validation, progress, success, and error.
52
+ *
53
+ * The indicator is automatically started before validation, updated at each phase transition,
54
+ * and stopped on success (`.succeed()`) or failure (`.fail()`).
55
+ *
56
+ * Provides `{ progress: PadroneProgress }` on the command context.
57
+ * Access it in action handlers as `ctx.context.progress`.
58
+ *
59
+ * Uses the built-in terminal renderer by default. Pass a custom `renderer` for non-terminal
60
+ * environments (web UIs, testing, etc).
61
+ *
62
+ * Usage:
63
+ * ```ts
64
+ * createPadrone('my-cli')
65
+ * .command('sync', (c) =>
66
+ * c.extend(padroneProgress('Syncing...'))
67
+ * .action((_args, ctx) => {
68
+ * ctx.context.progress.update('halfway');
69
+ * })
70
+ * )
71
+ * ```
72
+ */
73
+ declare function padroneProgress<T extends CommandTypesBase>(config?: string | PadroneProgressConfig): (builder: T) => WithProgress<T>;
74
+ //#endregion
75
+ export { PadroneProgressConfig, PadroneProgressDefaults, PadroneProgressMessage, PadroneProgressMessages, WithProgress, padroneProgress };
76
+ //# sourceMappingURL=progress.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress.d.mts","names":[],"sources":["../../src/extension/progress.ts"],"mappings":";;;;;;;KAYY,sBAAA;EAA2C,OAAA;EAAyB,SAAS;AAAA;;KAG7E,uBAAA;EAH6E,8EAKvF,UAAA,WAFiC;EAIjC,QAAA,WAEU;EAAV,OAAA,GAAU,sBAAA,KAA2B,MAAA,EAAQ,IAAA,KAAS,sBAAA,GAAA;EAEtD,KAAA,GAAQ,sBAAA,KAA2B,KAAA,cAAmB,sBAAA;AAAA;;;;KAM5C,qBAAA;EAVV,wGAYA,OAAA,YAAmB,uBAAA,CAAwB,IAAA,GAVjC;EAYV,OAAA,GAAU,oBAAA,EAZ2B;EAcrC,GAAA,aAAgB,gBAAA,EAZhB;EAcA,IAAA,YAdmC;EAgBnC,GAAA;EAhB4E;AAAA;AAM9E;;EAeE,QAAA,GAAW,uBAAA,EAbgC;EAe3C,MAAA;AAAA;;;;;;;;KAUU,uBAAA,GAA0B,IAAI,CAAC,qBAAA;;KAG/B,YAAA,MAAkB,eAAA,CAAgB,CAAA;EAAK,QAAA,EAAU,eAAA;AAAA;;;;;;;AAbrD;AAUR;;;;AAAgE;AAGhE;;;;;;;;;;;;;;iBAyRgB,eAAA,WAA0B,gBAAA,EAAkB,MAAA,YAAkB,qBAAA,IAAyB,OAAA,EAAS,CAAA,KAAM,YAAA,CAAa,CAAA"}