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,181 @@
1
+ //#region src/core/parse.ts
2
+ /**
3
+ * Split a string by a delimiter, respecting quoted segments and optional bracket nesting.
4
+ * Handles escape sequences within quotes (\\" and \\\\).
5
+ */
6
+ function splitQuoteAware(input, delimiter, opts) {
7
+ const results = [];
8
+ let current = "";
9
+ let inQuote = null;
10
+ let bracketDepth = 0;
11
+ let i = 0;
12
+ while (i < input.length) {
13
+ const char = input[i];
14
+ if (inQuote) {
15
+ if (char === "\\" && i + 1 < input.length) {
16
+ const nextChar = input[i + 1];
17
+ if (nextChar === inQuote || nextChar === "\\") {
18
+ current += nextChar;
19
+ i += 2;
20
+ continue;
21
+ }
22
+ }
23
+ if (char === inQuote) inQuote = null;
24
+ else current += char;
25
+ } else if (opts?.brackets && char === "[") {
26
+ bracketDepth++;
27
+ current += char;
28
+ } else if (opts?.brackets && char === "]") {
29
+ bracketDepth = Math.max(0, bracketDepth - 1);
30
+ current += char;
31
+ } else if (bracketDepth > 0) current += char;
32
+ else if (char === "\"" || char === "'" || char === "`") inQuote = char;
33
+ else if (char === delimiter || delimiter === " " && char === " ") {
34
+ if (delimiter === " " ? current : true) {
35
+ results.push(opts?.trim ? current.trim() : current);
36
+ current = "";
37
+ }
38
+ } else current += char;
39
+ i++;
40
+ }
41
+ if (delimiter === " " ? current : current || results.length > 0) results.push(opts?.trim ? current.trim() : current);
42
+ return results;
43
+ }
44
+ function parseCliInputToParts(input) {
45
+ const parts = splitQuoteAware(input.trim(), " ", { brackets: true });
46
+ const result = [];
47
+ let pendingIdx = -1;
48
+ let allowTerm = true;
49
+ let afterDoubleDash = false;
50
+ for (const part of parts) {
51
+ if (!part) continue;
52
+ if (part === "--" && !afterDoubleDash) {
53
+ pendingIdx = -1;
54
+ afterDoubleDash = true;
55
+ allowTerm = false;
56
+ continue;
57
+ }
58
+ if (afterDoubleDash) {
59
+ result.push({
60
+ type: "arg",
61
+ value: part
62
+ });
63
+ continue;
64
+ }
65
+ const hadPending = pendingIdx;
66
+ pendingIdx = -1;
67
+ if (part.startsWith("--no-") && part.length > 5) {
68
+ const key = part.slice(5).split(".");
69
+ result.push({
70
+ type: "named",
71
+ key,
72
+ value: void 0,
73
+ negated: true
74
+ });
75
+ } else if (part.startsWith("--")) {
76
+ const [keyStr = "", value] = splitNamedArgValue(part.slice(2));
77
+ const key = keyStr.split(".");
78
+ result.push({
79
+ type: "named",
80
+ key,
81
+ value
82
+ });
83
+ if (typeof value === "undefined") pendingIdx = result.length - 1;
84
+ } else if (part.startsWith("-") && part.length > 1 && !/^-\d/.test(part)) {
85
+ const [keyStr = "", value] = splitNamedArgValue(part.slice(1));
86
+ if (keyStr.length > 1 && typeof value === "undefined") {
87
+ for (let ci = 0; ci < keyStr.length - 1; ci++) result.push({
88
+ type: "alias",
89
+ key: [keyStr[ci]],
90
+ value: void 0
91
+ });
92
+ result.push({
93
+ type: "alias",
94
+ key: [keyStr[keyStr.length - 1]],
95
+ value: void 0
96
+ });
97
+ pendingIdx = result.length - 1;
98
+ } else if (keyStr.length > 1 && typeof value !== "undefined") {
99
+ for (let ci = 0; ci < keyStr.length - 1; ci++) result.push({
100
+ type: "alias",
101
+ key: [keyStr[ci]],
102
+ value: void 0
103
+ });
104
+ result.push({
105
+ type: "alias",
106
+ key: [keyStr[keyStr.length - 1]],
107
+ value
108
+ });
109
+ } else {
110
+ result.push({
111
+ type: "alias",
112
+ key: [keyStr],
113
+ value
114
+ });
115
+ if (typeof value === "undefined") pendingIdx = result.length - 1;
116
+ }
117
+ } else if (hadPending >= 0) result[hadPending].value = part;
118
+ else if (/^[a-zA-Z0-9_-]+$/.test(part) && allowTerm) result.push({
119
+ type: "term",
120
+ value: part
121
+ });
122
+ else {
123
+ result.push({
124
+ type: "arg",
125
+ value: part
126
+ });
127
+ allowTerm = false;
128
+ }
129
+ }
130
+ return result;
131
+ }
132
+ /**
133
+ * Split named arg key and value, handling quoted values after =.
134
+ */
135
+ function splitNamedArgValue(str) {
136
+ const eqIndex = str.indexOf("=");
137
+ if (eqIndex === -1) return [str, void 0];
138
+ const key = str.slice(0, eqIndex);
139
+ let value = str.slice(eqIndex + 1);
140
+ if (value.startsWith("\"") && value.endsWith("\"") || value.startsWith("'") && value.endsWith("'") || value.startsWith("`") && value.endsWith("`")) {
141
+ value = value.slice(1, -1);
142
+ return [key, value];
143
+ }
144
+ if (value.startsWith("[") && value.endsWith("]")) {
145
+ const inner = value.slice(1, -1);
146
+ if (inner === "") return [key, []];
147
+ return [key, splitQuoteAware(inner, ",", { trim: true })];
148
+ }
149
+ return [key, value];
150
+ }
151
+ /**
152
+ * Sets a value at a nested path in an object.
153
+ * For example: setNestedValue(obj, ['user', 'profile', 'name'], 'John')
154
+ * Creates intermediate objects as needed.
155
+ */
156
+ function setNestedValue(obj, path, value) {
157
+ let current = obj;
158
+ for (let i = 0; i < path.length - 1; i++) {
159
+ const part = path[i];
160
+ if (!(part in current) || typeof current[part] !== "object" || current[part] === null) current[part] = {};
161
+ current = current[part];
162
+ }
163
+ const lastPart = path[path.length - 1];
164
+ current[lastPart] = value;
165
+ }
166
+ /**
167
+ * Gets a value at a nested path in an object.
168
+ * Returns undefined if the path doesn't exist.
169
+ */
170
+ function getNestedValue(obj, path) {
171
+ let current = obj;
172
+ for (const part of path) {
173
+ if (current === null || current === void 0 || typeof current !== "object") return;
174
+ current = current[part];
175
+ }
176
+ return current;
177
+ }
178
+ //#endregion
179
+ export { getNestedValue, parseCliInputToParts, setNestedValue };
180
+
181
+ //# sourceMappingURL=parse.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.mjs","names":[],"sources":["../../src/core/parse.ts"],"sourcesContent":["type ParseParts = {\n /**\n * An alphanumeric term representing a command, subcommand, or positional argument.\n * Note that a term can be ambiguous until fully matched within the command hierarchy.\n * We cannot fully distinguish between a nested command or a positional argument until\n * the command structure is known.\n */\n term: {\n type: 'term';\n value: string;\n };\n /**\n * A positional argument provided to the command.\n * Unlike `term`, this is definitively an argument. This can be determined when\n * the argument is non-alphanumeric, like a path or a number.\n */\n arg: {\n type: 'arg';\n value: string;\n };\n /**\n * An arg provided to the command, prefixed with `--`.\n * If the arg has an `=` sign, the value after it is used as the arg's value.\n * Otherwise, the value is obtained from the next part or set to `true` if no value is provided.\n * The key is an array representing the path for nested args (e.g., `--user.id=123` becomes `['user', 'id']`).\n */\n named: {\n type: 'named';\n key: string[];\n value?: string | string[];\n negated?: boolean;\n };\n /**\n * An alias arg provided to the command, prefixed with `-`.\n * Which arg it maps to cannot be determined until the command structure is known.\n * Aliases cannot be nested, so the key is always a single-element array.\n */\n alias: {\n type: 'alias';\n key: string[];\n value?: string | string[];\n };\n};\n\ntype ParsePart = ParseParts[keyof ParseParts];\n\ntype QuoteChar = '\"' | \"'\" | '`';\n\n/**\n * Split a string by a delimiter, respecting quoted segments and optional bracket nesting.\n * Handles escape sequences within quotes (\\\\\" and \\\\\\\\).\n */\nfunction splitQuoteAware(input: string, delimiter: ' ' | ',', opts?: { brackets?: boolean; trim?: boolean }): string[] {\n const results: string[] = [];\n let current = '';\n let inQuote: QuoteChar | null = null;\n let bracketDepth = 0;\n let i = 0;\n\n while (i < input.length) {\n const char = input[i];\n\n if (inQuote) {\n if (char === '\\\\' && i + 1 < input.length) {\n const nextChar = input[i + 1];\n if (nextChar === inQuote || nextChar === '\\\\') {\n current += nextChar;\n i += 2;\n continue;\n }\n }\n if (char === inQuote) {\n inQuote = null;\n } else {\n current += char;\n }\n } else if (opts?.brackets && char === '[') {\n bracketDepth++;\n current += char;\n } else if (opts?.brackets && char === ']') {\n bracketDepth = Math.max(0, bracketDepth - 1);\n current += char;\n } else if (bracketDepth > 0) {\n current += char;\n } else if (char === '\"' || char === \"'\" || char === '`') {\n inQuote = char;\n } else if (char === delimiter || (delimiter === ' ' && char === '\\t')) {\n if (delimiter === ' ' ? current : true) {\n results.push(opts?.trim ? current.trim() : current);\n current = '';\n }\n } else {\n current += char;\n }\n i++;\n }\n\n if (delimiter === ' ' ? current : current || results.length > 0) {\n results.push(opts?.trim ? current.trim() : current);\n }\n\n return results;\n}\n\nexport function parseCliInputToParts(input: string): ParsePart[] {\n const parts = splitQuoteAware(input.trim(), ' ', { brackets: true });\n const result: ParsePart[] = [];\n\n // Index into `result` of the last part that can accept a pending value (-1 = none)\n let pendingIdx = -1;\n // Once a non-term positional arg appears, all subsequent bare values become args\n let allowTerm = true;\n let afterDoubleDash = false;\n\n for (const part of parts) {\n if (!part) continue;\n\n // Bare `--` separator: everything after is a literal positional arg\n if (part === '--' && !afterDoubleDash) {\n pendingIdx = -1;\n afterDoubleDash = true;\n allowTerm = false;\n continue;\n }\n\n if (afterDoubleDash) {\n result.push({ type: 'arg', value: part });\n continue;\n }\n\n const hadPending = pendingIdx;\n pendingIdx = -1;\n\n if (part.startsWith('--no-') && part.length > 5) {\n // Negated boolean arg (--no-verbose or --no-config.debug)\n const key = part.slice(5).split('.');\n result.push({ type: 'named', key, value: undefined, negated: true });\n } else if (part.startsWith('--')) {\n const [keyStr = '', value] = splitNamedArgValue(part.slice(2));\n const key = keyStr.split('.');\n result.push({ type: 'named', key, value });\n if (typeof value === 'undefined') pendingIdx = result.length - 1;\n } else if (part.startsWith('-') && part.length > 1 && !/^-\\d/.test(part)) {\n // Short flag(s) (but not negative numbers like -5)\n // Supports flag stacking: -abc → -a -b -c (last flag can take a value)\n const [keyStr = '', value] = splitNamedArgValue(part.slice(1));\n\n if (keyStr.length > 1 && typeof value === 'undefined') {\n // Flag stacking: -abc → -a, -b, -c (all set to true except last which can take next arg's value)\n for (let ci = 0; ci < keyStr.length - 1; ci++) {\n result.push({ type: 'alias', key: [keyStr[ci]!], value: undefined });\n }\n result.push({ type: 'alias', key: [keyStr[keyStr.length - 1]!], value: undefined });\n pendingIdx = result.length - 1;\n } else if (keyStr.length > 1 && typeof value !== 'undefined') {\n // -abc=val → -a, -b, -c=val (stacked with value on last)\n for (let ci = 0; ci < keyStr.length - 1; ci++) {\n result.push({ type: 'alias', key: [keyStr[ci]!], value: undefined });\n }\n result.push({ type: 'alias', key: [keyStr[keyStr.length - 1]!], value });\n } else {\n // Single char: -v or -v=value\n result.push({ type: 'alias', key: [keyStr], value });\n if (typeof value === 'undefined') pendingIdx = result.length - 1;\n }\n } else if (hadPending >= 0) {\n result[hadPending]!.value = part;\n } else if (/^[a-zA-Z0-9_-]+$/.test(part) && allowTerm) {\n result.push({ type: 'term', value: part });\n } else {\n result.push({ type: 'arg', value: part });\n allowTerm = false;\n }\n }\n return result;\n}\n\n/**\n * Split named arg key and value, handling quoted values after =.\n */\nfunction splitNamedArgValue(str: string): [string, string | string[] | undefined] {\n const eqIndex = str.indexOf('=');\n if (eqIndex === -1) return [str, undefined];\n\n const key = str.slice(0, eqIndex);\n let value = str.slice(eqIndex + 1);\n\n // Remove surrounding quotes from value if present\n if (\n (value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\")) ||\n (value.startsWith('`') && value.endsWith('`'))\n ) {\n value = value.slice(1, -1);\n return [key, value];\n }\n\n // Handle array syntax: [a,b,c] -> ['a', 'b', 'c']\n if (value.startsWith('[') && value.endsWith(']')) {\n const inner = value.slice(1, -1);\n if (inner === '') return [key, []];\n return [key, splitQuoteAware(inner, ',', { trim: true })];\n }\n\n return [key, value];\n}\n\n/**\n * Sets a value at a nested path in an object.\n * For example: setNestedValue(obj, ['user', 'profile', 'name'], 'John')\n * Creates intermediate objects as needed.\n */\nexport function setNestedValue(obj: Record<string, unknown>, path: string[], value: unknown): void {\n let current: Record<string, unknown> = obj;\n\n for (let i = 0; i < path.length - 1; i++) {\n const part = path[i]!;\n if (!(part in current) || typeof current[part] !== 'object' || current[part] === null) {\n current[part] = {};\n }\n current = current[part] as Record<string, unknown>;\n }\n\n const lastPart = path[path.length - 1]!;\n current[lastPart] = value;\n}\n\n/**\n * Gets a value at a nested path in an object.\n * Returns undefined if the path doesn't exist.\n */\nexport function getNestedValue(obj: Record<string, unknown>, path: string[]): unknown {\n let current: unknown = obj;\n\n for (const part of path) {\n if (current === null || current === undefined || typeof current !== 'object') {\n return undefined;\n }\n current = (current as Record<string, unknown>)[part];\n }\n\n return current;\n}\n"],"mappings":"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"}
@@ -0,0 +1,256 @@
1
+ import { extractSchemaMetadata, parsePositionalConfig } from "./args.mjs";
2
+ import { findCommandByName, getCommandRuntime, resolveAllCommands } from "./commands.mjs";
3
+ import { errorResult, makeThenable, thenMaybe, warnIfUnexpectedAsync, withDrain, withPromiseDrain } from "./results.mjs";
4
+ import { resolveRegisteredInterceptors, runInterceptorChain } from "./interceptors.mjs";
5
+ import { RoutingError } from "./errors.mjs";
6
+ import { coreValidateForParse } from "./validate.mjs";
7
+ import { generateHelp } from "../output/help.mjs";
8
+ import { collectInterceptors, errorResultWithSignal, execCommand } from "./exec.mjs";
9
+ import { createReplIterator } from "../feature/repl-loop.mjs";
10
+ //#region src/core/program-methods.ts
11
+ function createProgramMethods(ctx, evalCommand) {
12
+ const { rootCommand } = ctx;
13
+ const inertSignal = new AbortController().signal;
14
+ const stringify = (command = "", args) => {
15
+ const commandObj = typeof command === "string" ? findCommandByName(command, rootCommand.commands) : command;
16
+ if (!commandObj) throw new RoutingError(`Command "${command ?? ""}" not found`);
17
+ const parts = [];
18
+ if (commandObj.path) parts.push(commandObj.path);
19
+ const positionalConfig = commandObj.meta?.positional ? parsePositionalConfig(commandObj.meta.positional) : [];
20
+ const positionalNames = new Set(positionalConfig.map((p) => p.name));
21
+ const negativeKeyword = {};
22
+ if (commandObj.argsSchema) {
23
+ const { negatives } = extractSchemaMetadata(commandObj.argsSchema, commandObj.meta?.fields, commandObj.meta?.autoAlias);
24
+ for (const [keyword, argName] of Object.entries(negatives)) if (!(argName in negativeKeyword)) negativeKeyword[argName] = keyword;
25
+ }
26
+ if (args && typeof args === "object") {
27
+ for (const { name, variadic } of positionalConfig) {
28
+ const value = args[name];
29
+ if (value === void 0) continue;
30
+ if (variadic && Array.isArray(value)) for (const v of value) {
31
+ const vStr = String(v);
32
+ if (vStr.includes(" ")) parts.push(`"${vStr}"`);
33
+ else parts.push(vStr);
34
+ }
35
+ else {
36
+ const argStr = String(value);
37
+ if (argStr.includes(" ")) parts.push(`"${argStr}"`);
38
+ else parts.push(argStr);
39
+ }
40
+ }
41
+ const stringifyValue = (key, value) => {
42
+ if (value === void 0) return;
43
+ if (typeof value === "boolean") if (value) parts.push(`--${key}`);
44
+ else if (negativeKeyword[key]) parts.push(`--${negativeKeyword[key]}`);
45
+ else parts.push(`--no-${key}`);
46
+ else if (Array.isArray(value)) for (const v of value) {
47
+ const vStr = String(v);
48
+ if (vStr.includes(" ")) parts.push(`--${key}="${vStr}"`);
49
+ else parts.push(`--${key}=${vStr}`);
50
+ }
51
+ else if (typeof value === "object" && value !== null) for (const [nestedKey, nestedValue] of Object.entries(value)) stringifyValue(`${key}.${nestedKey}`, nestedValue);
52
+ else if (typeof value === "string") if (value.includes(" ")) parts.push(`--${key}="${value}"`);
53
+ else parts.push(`--${key}=${value}`);
54
+ else parts.push(`--${key}=${value}`);
55
+ };
56
+ for (const [key, value] of Object.entries(args)) {
57
+ if (value === void 0 || positionalNames.has(key)) continue;
58
+ stringifyValue(key, value);
59
+ }
60
+ }
61
+ return parts.join(" ");
62
+ };
63
+ const resolveContext = (command, initialContext) => {
64
+ const chain = [];
65
+ let current = command;
66
+ while (current) {
67
+ chain.unshift(current);
68
+ current = current.parent;
69
+ }
70
+ let resolved = initialContext;
71
+ for (const cmd of chain) if (cmd.contextTransform) resolved = cmd.contextTransform(resolved);
72
+ return resolved;
73
+ };
74
+ const run = (command, args, prefs) => {
75
+ try {
76
+ const commandObj = typeof command === "string" ? findCommandByName(command, rootCommand.commands) : command;
77
+ if (!commandObj) throw new RoutingError(`Command "${command ?? ""}" not found`);
78
+ if (!commandObj.action) throw new RoutingError(`Command "${commandObj.path}" has no action`, { command: commandObj.path });
79
+ const executeCtx = {
80
+ command: commandObj,
81
+ input: void 0,
82
+ rawArgs: {},
83
+ positionalArgs: [],
84
+ args,
85
+ signal: inertSignal,
86
+ context: resolveContext(commandObj, prefs?.context),
87
+ runtime: getCommandRuntime(commandObj),
88
+ program: ctx.builder,
89
+ caller: "run"
90
+ };
91
+ const coreExecute = (executeCtx) => {
92
+ const actionCtx = {
93
+ runtime: executeCtx.runtime,
94
+ command: executeCtx.command,
95
+ program: ctx.builder,
96
+ signal: inertSignal,
97
+ context: executeCtx.context,
98
+ caller: "run"
99
+ };
100
+ return { result: commandObj.action(executeCtx.args, actionCtx) };
101
+ };
102
+ const executedOrPromise = runInterceptorChain("execute", resolveRegisteredInterceptors(collectInterceptors(commandObj, rootCommand), /* @__PURE__ */ new Map()), executeCtx, coreExecute);
103
+ const toResult = (e) => withDrain({
104
+ command: commandObj,
105
+ args,
106
+ result: e.result
107
+ });
108
+ if (executedOrPromise instanceof Promise) return executedOrPromise.then(toResult).catch((err) => errorResult(err, {
109
+ command: commandObj,
110
+ args
111
+ }));
112
+ return toResult(executedOrPromise);
113
+ } catch (err) {
114
+ return errorResult(err);
115
+ }
116
+ };
117
+ const tool = () => {
118
+ resolveAllCommands(rootCommand);
119
+ const description = `Run a command. Pass the full command string including arguments. Use "help <command>" for detailed usage.\n\n${generateHelp(rootCommand, void 0, { format: "text" })}`;
120
+ return {
121
+ type: "function",
122
+ name: rootCommand.name,
123
+ strict: true,
124
+ title: rootCommand.description,
125
+ description,
126
+ inputExamples: [{ input: { command: "<command> [positionals...] [arguments...]" } }],
127
+ inputSchema: {
128
+ [Symbol.for("vercel.ai.schema")]: true,
129
+ jsonSchema: {
130
+ type: "object",
131
+ properties: { command: { type: "string" } },
132
+ additionalProperties: false
133
+ },
134
+ _type: void 0,
135
+ validate: (value) => {
136
+ const command = value?.command;
137
+ if (typeof command === "string") return {
138
+ success: true,
139
+ value: { command }
140
+ };
141
+ return {
142
+ success: false,
143
+ error: /* @__PURE__ */ new Error("Expected an object with command property as string.")
144
+ };
145
+ }
146
+ },
147
+ needsApproval: async (input) => {
148
+ const parsed = await parse(input.command);
149
+ if (typeof parsed.command.needsApproval === "function") return parsed.command.needsApproval(parsed.args);
150
+ if (parsed.command.needsApproval != null) return !!parsed.command.needsApproval;
151
+ return !!parsed.command.mutation;
152
+ },
153
+ execute: async (input) => {
154
+ const output = [];
155
+ const errors = [];
156
+ return {
157
+ result: (await evalCommand(input.command, {
158
+ caller: "tool",
159
+ runtime: {
160
+ output: (...args) => output.push(args.map(String).join(" ")),
161
+ error: (text) => errors.push(text),
162
+ interactive: "unsupported",
163
+ format: "text"
164
+ }
165
+ })).result,
166
+ logs: output.join("\n"),
167
+ error: errors.join("\n")
168
+ };
169
+ }
170
+ };
171
+ };
172
+ const replActiveRef = { value: false };
173
+ const replFn = (options) => createReplIterator({
174
+ existingCommand: rootCommand,
175
+ evalCommand,
176
+ replActiveRef
177
+ }, options);
178
+ const cli = (cliOptions) => {
179
+ try {
180
+ const result = execCommand(getCommandRuntime(rootCommand).argv().join(" ") || void 0, ctx, cliOptions, "hard", "cli");
181
+ if (result instanceof Promise) return withPromiseDrain(result.catch((err) => errorResultWithSignal(err)));
182
+ return makeThenable(result);
183
+ } catch (err) {
184
+ return makeThenable(errorResultWithSignal(err));
185
+ }
186
+ };
187
+ const find = (command) => {
188
+ if (typeof command !== "string") return findCommandByName(command.path, rootCommand.commands);
189
+ return findCommandByName(command, rootCommand.commands);
190
+ };
191
+ const parse = (input) => {
192
+ const { command, rawArgs, args } = ctx.parseCommandFn(input);
193
+ return makeThenable(warnIfUnexpectedAsync(thenMaybe(coreValidateForParse(command, rawArgs, args), (v) => ({
194
+ command,
195
+ args: v.args,
196
+ argsResult: v.argsResult
197
+ })), command));
198
+ };
199
+ const help = (command, prefs) => {
200
+ resolveAllCommands(rootCommand);
201
+ const commandObj = !command ? rootCommand : typeof command === "string" ? findCommandByName(command, rootCommand.commands) : command;
202
+ if (!commandObj) throw new RoutingError(`Command "${command ?? ""}" not found`);
203
+ const runtime = getCommandRuntime(rootCommand);
204
+ return generateHelp(rootCommand, commandObj, {
205
+ ...prefs,
206
+ format: prefs?.format ?? runtime.format,
207
+ theme: prefs?.theme ?? runtime.theme,
208
+ terminal: prefs?.terminal ?? runtime.terminal,
209
+ env: prefs?.env ?? runtime.env()
210
+ });
211
+ };
212
+ const api = () => {
213
+ resolveAllCommands(rootCommand);
214
+ function buildApi(command) {
215
+ const runCommand = ((args) => run(command, args).result);
216
+ if (!command.commands) return runCommand;
217
+ for (const cmd of command.commands) runCommand[cmd.name] = buildApi(cmd);
218
+ return runCommand;
219
+ }
220
+ return buildApi(rootCommand);
221
+ };
222
+ const completion = async (shell) => {
223
+ resolveAllCommands(rootCommand);
224
+ const { generateCompletionOutput } = await import("../feature/completion.mjs");
225
+ return generateCompletionOutput(rootCommand, shell);
226
+ };
227
+ const mcp = async (prefs) => {
228
+ resolveAllCommands(rootCommand);
229
+ const { startMcpServer } = await import("../feature/mcp.mjs");
230
+ return startMcpServer(ctx.builder, rootCommand, evalCommand, prefs);
231
+ };
232
+ const serve = async (prefs) => {
233
+ resolveAllCommands(rootCommand);
234
+ const { startServeServer } = await import("../feature/serve.mjs");
235
+ return startServeServer(ctx.builder, rootCommand, evalCommand, prefs);
236
+ };
237
+ return {
238
+ find,
239
+ parse,
240
+ stringify,
241
+ run,
242
+ eval: evalCommand,
243
+ cli,
244
+ tool,
245
+ repl: replFn,
246
+ api,
247
+ help,
248
+ completion,
249
+ mcp,
250
+ serve
251
+ };
252
+ }
253
+ //#endregion
254
+ export { createProgramMethods };
255
+
256
+ //# sourceMappingURL=program-methods.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"program-methods.mjs","names":[],"sources":["../../src/core/program-methods.ts"],"sourcesContent":["import type { Schema } from 'ai';\nimport type { ShellType } from '../feature/completion.ts';\nimport { createReplIterator } from '../feature/repl-loop.ts';\nimport { generateHelp } from '../output/help.ts';\nimport type {\n AnyPadroneCommand,\n AnyPadroneProgram,\n InterceptorExecuteContext,\n InterceptorExecuteResult,\n PadroneActionContext,\n PadroneAPI,\n PadroneReplPreferences,\n} from '../types/index.ts';\nimport { extractSchemaMetadata, parsePositionalConfig } from './args.ts';\nimport { findCommandByName, getCommandRuntime, resolveAllCommands } from './commands.ts';\nimport { RoutingError } from './errors.ts';\nimport type { ExecContext } from './exec.ts';\nimport { collectInterceptors, errorResultWithSignal, execCommand } from './exec.ts';\nimport { resolveRegisteredInterceptors, runInterceptorChain } from './interceptors.ts';\nimport { errorResult, makeThenable, thenMaybe, warnIfUnexpectedAsync, withDrain, withPromiseDrain } from './results.ts';\nimport { coreValidateForParse } from './validate.ts';\n\nexport function createProgramMethods(ctx: ExecContext, evalCommand: AnyPadroneProgram['eval']) {\n const { rootCommand } = ctx;\n\n // A never-aborted signal for contexts that don't need signal handling (parse, run).\n const inertSignal = new AbortController().signal;\n\n const stringify: AnyPadroneProgram['stringify'] = (command = '' as any, args) => {\n const commandObj = typeof command === 'string' ? findCommandByName(command, rootCommand.commands) : (command as AnyPadroneCommand);\n if (!commandObj) throw new RoutingError(`Command \"${command ?? ''}\" not found`);\n\n const parts: string[] = [];\n\n if (commandObj.path) parts.push(commandObj.path);\n\n const positionalConfig = commandObj.meta?.positional ? parsePositionalConfig(commandObj.meta.positional) : [];\n const positionalNames = new Set(positionalConfig.map((p) => p.name));\n\n // Build reverse map: arg name → first negative keyword (for stringify)\n const negativeKeyword: Record<string, string> = {};\n if (commandObj.argsSchema) {\n const { negatives } = extractSchemaMetadata(commandObj.argsSchema, commandObj.meta?.fields, commandObj.meta?.autoAlias);\n for (const [keyword, argName] of Object.entries(negatives)) {\n if (!(argName in negativeKeyword)) negativeKeyword[argName] = keyword;\n }\n }\n\n if (args && typeof args === 'object') {\n for (const { name, variadic } of positionalConfig) {\n const value = (args as Record<string, unknown>)[name];\n if (value === undefined) continue;\n\n if (variadic && Array.isArray(value)) {\n for (const v of value) {\n const vStr = String(v);\n if (vStr.includes(' ')) parts.push(`\"${vStr}\"`);\n else parts.push(vStr);\n }\n } else {\n const argStr = String(value);\n if (argStr.includes(' ')) parts.push(`\"${argStr}\"`);\n else parts.push(argStr);\n }\n }\n\n const stringifyValue = (key: string, value: unknown) => {\n if (value === undefined) return;\n\n if (typeof value === 'boolean') {\n if (value) parts.push(`--${key}`);\n else if (negativeKeyword[key]) parts.push(`--${negativeKeyword[key]}`);\n else parts.push(`--no-${key}`);\n } else if (Array.isArray(value)) {\n for (const v of value) {\n const vStr = String(v);\n if (vStr.includes(' ')) parts.push(`--${key}=\"${vStr}\"`);\n else parts.push(`--${key}=${vStr}`);\n }\n } else if (typeof value === 'object' && value !== null) {\n for (const [nestedKey, nestedValue] of Object.entries(value)) {\n stringifyValue(`${key}.${nestedKey}`, nestedValue);\n }\n } else if (typeof value === 'string') {\n if (value.includes(' ')) parts.push(`--${key}=\"${value}\"`);\n else parts.push(`--${key}=${value}`);\n } else {\n parts.push(`--${key}=${value}`);\n }\n };\n\n for (const [key, value] of Object.entries(args)) {\n if (value === undefined || positionalNames.has(key)) continue;\n stringifyValue(key, value);\n }\n }\n\n return parts.join(' ');\n };\n\n const resolveContext = (command: AnyPadroneCommand, initialContext: unknown): unknown => {\n const chain: AnyPadroneCommand[] = [];\n let current: AnyPadroneCommand | undefined = command;\n while (current) {\n chain.unshift(current);\n current = current.parent;\n }\n let resolved = initialContext;\n for (const cmd of chain) {\n if (cmd.contextTransform) resolved = cmd.contextTransform(resolved);\n }\n return resolved;\n };\n\n const run: AnyPadroneProgram['run'] = (command, args, prefs?: { context?: unknown }) => {\n try {\n const commandObj = typeof command === 'string' ? findCommandByName(command, rootCommand.commands) : (command as AnyPadroneCommand);\n if (!commandObj) throw new RoutingError(`Command \"${command ?? ''}\" not found`);\n if (!commandObj.action) throw new RoutingError(`Command \"${commandObj.path}\" has no action`, { command: commandObj.path });\n\n const resolvedCtx = resolveContext(commandObj, prefs?.context);\n const commandRuntime = getCommandRuntime(commandObj);\n const executeCtx: InterceptorExecuteContext = {\n command: commandObj,\n input: undefined,\n rawArgs: {},\n positionalArgs: [],\n args,\n signal: inertSignal,\n context: resolvedCtx as object,\n runtime: commandRuntime,\n program: ctx.builder as any,\n caller: 'run',\n };\n\n const coreExecute = (executeCtx: InterceptorExecuteContext): InterceptorExecuteResult => {\n const actionCtx: PadroneActionContext = {\n runtime: executeCtx.runtime,\n command: executeCtx.command,\n program: ctx.builder as any,\n signal: inertSignal,\n context: executeCtx.context,\n caller: 'run',\n };\n const result = commandObj.action!(executeCtx.args as any, actionCtx);\n return { result };\n };\n\n const commandInterceptors = resolveRegisteredInterceptors(collectInterceptors(commandObj, rootCommand), new Map());\n const executedOrPromise = runInterceptorChain('execute', commandInterceptors, executeCtx, coreExecute);\n\n const toResult = (e: InterceptorExecuteResult) => withDrain({ command: commandObj as any, args: args as any, result: e.result });\n\n if (executedOrPromise instanceof Promise) {\n return executedOrPromise.then(toResult).catch((err: unknown) => errorResult(err, { command: commandObj, args })) as any;\n }\n return toResult(executedOrPromise);\n } catch (err) {\n return errorResult(err) as any;\n }\n };\n\n const tool: AnyPadroneProgram['tool'] = () => {\n resolveAllCommands(rootCommand);\n const helpText = generateHelp(rootCommand, undefined, { format: 'text' });\n\n const description = `Run a command. Pass the full command string including arguments. Use \"help <command>\" for detailed usage.\\n\\n${helpText}`;\n\n return {\n type: 'function',\n name: rootCommand.name,\n strict: true,\n title: rootCommand.description,\n description,\n inputExamples: [{ input: { command: '<command> [positionals...] [arguments...]' } }],\n inputSchema: {\n [Symbol.for('vercel.ai.schema') as keyof Schema & symbol]: true,\n jsonSchema: {\n type: 'object',\n properties: { command: { type: 'string' } },\n additionalProperties: false,\n },\n _type: undefined as unknown as { command: string },\n validate: (value) => {\n const command = (value as any)?.command;\n if (typeof command === 'string') return { success: true, value: { command } };\n return { success: false, error: new Error('Expected an object with command property as string.') };\n },\n } satisfies Schema<{ command: string }> as Schema<{ command: string }>,\n needsApproval: async (input) => {\n const parsed = await parse(input.command);\n if (typeof parsed.command.needsApproval === 'function') return parsed.command.needsApproval(parsed.args);\n if (parsed.command.needsApproval != null) return !!parsed.command.needsApproval;\n return !!parsed.command.mutation;\n },\n execute: async (input) => {\n const output: string[] = [];\n const errors: string[] = [];\n const result = await evalCommand(input.command, {\n caller: 'tool',\n runtime: {\n output: (...args) => output.push(args.map(String).join(' ')),\n error: (text) => errors.push(text),\n interactive: 'unsupported',\n format: 'text',\n },\n });\n return { result: result.result, logs: output.join('\\n'), error: errors.join('\\n') };\n },\n };\n };\n\n const replActiveRef = { value: false };\n const replFn = (options?: PadroneReplPreferences) =>\n createReplIterator({ existingCommand: rootCommand, evalCommand, replActiveRef }, options);\n\n const cli: AnyPadroneProgram['cli'] = (cliOptions) => {\n try {\n const runtime = getCommandRuntime(rootCommand);\n const resolvedInput = (runtime.argv().join(' ') || undefined) as string | undefined;\n\n const result = execCommand(resolvedInput, ctx, cliOptions, 'hard', 'cli');\n\n if (result instanceof Promise) return withPromiseDrain(result.catch((err: unknown) => errorResultWithSignal(err))) as any;\n return makeThenable(result);\n } catch (err) {\n return makeThenable(errorResultWithSignal(err)) as any;\n }\n };\n\n const find: AnyPadroneProgram['find'] = (command) => {\n if (typeof command !== 'string') return findCommandByName(command.path, rootCommand.commands) as any;\n return findCommandByName(command, rootCommand.commands) as any;\n };\n\n const parse: AnyPadroneProgram['parse'] = (input) => {\n const { command, rawArgs, args } = ctx.parseCommandFn(input as string | undefined);\n\n const validatedOrPromise = coreValidateForParse(command, rawArgs, args);\n\n return makeThenable(\n warnIfUnexpectedAsync(\n thenMaybe(validatedOrPromise, (v: any) => ({ command: command as any, args: v.args, argsResult: v.argsResult })),\n command,\n ),\n ) as any;\n };\n\n const help: AnyPadroneProgram['help'] = (command, prefs) => {\n resolveAllCommands(rootCommand);\n const commandObj = !command\n ? rootCommand\n : typeof command === 'string'\n ? findCommandByName(command, rootCommand.commands)\n : (command as AnyPadroneCommand);\n if (!commandObj) throw new RoutingError(`Command \"${command ?? ''}\" not found`);\n const runtime = getCommandRuntime(rootCommand);\n return generateHelp(rootCommand, commandObj, {\n ...prefs,\n format: prefs?.format ?? runtime.format,\n theme: prefs?.theme ?? runtime.theme,\n terminal: prefs?.terminal ?? runtime.terminal,\n env: prefs?.env ?? runtime.env(),\n });\n };\n\n const api: AnyPadroneProgram['api'] = () => {\n resolveAllCommands(rootCommand);\n function buildApi(command: AnyPadroneCommand) {\n const runCommand = ((args) => run(command, args).result) as PadroneAPI<AnyPadroneCommand>;\n if (!command.commands) return runCommand;\n for (const cmd of command.commands) runCommand[cmd.name] = buildApi(cmd);\n return runCommand;\n }\n return buildApi(rootCommand);\n };\n\n const completion: AnyPadroneProgram['completion'] = async (shell) => {\n resolveAllCommands(rootCommand);\n const { generateCompletionOutput } = await import('../feature/completion.ts');\n return generateCompletionOutput(rootCommand, shell as ShellType | undefined);\n };\n\n const mcp: AnyPadroneProgram['mcp'] = async (prefs) => {\n resolveAllCommands(rootCommand);\n const { startMcpServer } = await import('../feature/mcp.ts');\n return startMcpServer(ctx.builder as any, rootCommand, evalCommand, prefs);\n };\n\n const serve: AnyPadroneProgram['serve'] = async (prefs) => {\n resolveAllCommands(rootCommand);\n const { startServeServer } = await import('../feature/serve.ts');\n return startServeServer(ctx.builder as any, rootCommand, evalCommand, prefs);\n };\n\n return {\n find,\n parse,\n stringify,\n run,\n eval: evalCommand,\n cli,\n tool,\n repl: replFn,\n api,\n help,\n completion,\n mcp,\n serve,\n };\n}\n"],"mappings":";;;;;;;;;;AAsBA,SAAgB,qBAAqB,KAAkB,aAAwC;CAC7F,MAAM,EAAE,gBAAgB;CAGxB,MAAM,cAAc,IAAI,gBAAgB,CAAC,CAAC;CAE1C,MAAM,aAA6C,UAAU,IAAW,SAAS;EAC/E,MAAM,aAAa,OAAO,YAAY,WAAW,kBAAkB,SAAS,YAAY,QAAQ,IAAK;EACrG,IAAI,CAAC,YAAY,MAAM,IAAI,aAAa,YAAY,WAAW,GAAG,YAAY;EAE9E,MAAM,QAAkB,CAAC;EAEzB,IAAI,WAAW,MAAM,MAAM,KAAK,WAAW,IAAI;EAE/C,MAAM,mBAAmB,WAAW,MAAM,aAAa,sBAAsB,WAAW,KAAK,UAAU,IAAI,CAAC;EAC5G,MAAM,kBAAkB,IAAI,IAAI,iBAAiB,KAAK,MAAM,EAAE,IAAI,CAAC;EAGnE,MAAM,kBAA0C,CAAC;EACjD,IAAI,WAAW,YAAY;GACzB,MAAM,EAAE,cAAc,sBAAsB,WAAW,YAAY,WAAW,MAAM,QAAQ,WAAW,MAAM,SAAS;GACtH,KAAK,MAAM,CAAC,SAAS,YAAY,OAAO,QAAQ,SAAS,GACvD,IAAI,EAAE,WAAW,kBAAkB,gBAAgB,WAAW;EAElE;EAEA,IAAI,QAAQ,OAAO,SAAS,UAAU;GACpC,KAAK,MAAM,EAAE,MAAM,cAAc,kBAAkB;IACjD,MAAM,QAAS,KAAiC;IAChD,IAAI,UAAU,KAAA,GAAW;IAEzB,IAAI,YAAY,MAAM,QAAQ,KAAK,GACjC,KAAK,MAAM,KAAK,OAAO;KACrB,MAAM,OAAO,OAAO,CAAC;KACrB,IAAI,KAAK,SAAS,GAAG,GAAG,MAAM,KAAK,IAAI,KAAK,EAAE;UACzC,MAAM,KAAK,IAAI;IACtB;SACK;KACL,MAAM,SAAS,OAAO,KAAK;KAC3B,IAAI,OAAO,SAAS,GAAG,GAAG,MAAM,KAAK,IAAI,OAAO,EAAE;UAC7C,MAAM,KAAK,MAAM;IACxB;GACF;GAEA,MAAM,kBAAkB,KAAa,UAAmB;IACtD,IAAI,UAAU,KAAA,GAAW;IAEzB,IAAI,OAAO,UAAU,WACnB,IAAI,OAAO,MAAM,KAAK,KAAK,KAAK;SAC3B,IAAI,gBAAgB,MAAM,MAAM,KAAK,KAAK,gBAAgB,MAAM;SAChE,MAAM,KAAK,QAAQ,KAAK;SACxB,IAAI,MAAM,QAAQ,KAAK,GAC5B,KAAK,MAAM,KAAK,OAAO;KACrB,MAAM,OAAO,OAAO,CAAC;KACrB,IAAI,KAAK,SAAS,GAAG,GAAG,MAAM,KAAK,KAAK,IAAI,IAAI,KAAK,EAAE;UAClD,MAAM,KAAK,KAAK,IAAI,GAAG,MAAM;IACpC;SACK,IAAI,OAAO,UAAU,YAAY,UAAU,MAChD,KAAK,MAAM,CAAC,WAAW,gBAAgB,OAAO,QAAQ,KAAK,GACzD,eAAe,GAAG,IAAI,GAAG,aAAa,WAAW;SAE9C,IAAI,OAAO,UAAU,UAC1B,IAAI,MAAM,SAAS,GAAG,GAAG,MAAM,KAAK,KAAK,IAAI,IAAI,MAAM,EAAE;SACpD,MAAM,KAAK,KAAK,IAAI,GAAG,OAAO;SAEnC,MAAM,KAAK,KAAK,IAAI,GAAG,OAAO;GAElC;GAEA,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,IAAI,GAAG;IAC/C,IAAI,UAAU,KAAA,KAAa,gBAAgB,IAAI,GAAG,GAAG;IACrD,eAAe,KAAK,KAAK;GAC3B;EACF;EAEA,OAAO,MAAM,KAAK,GAAG;CACvB;CAEA,MAAM,kBAAkB,SAA4B,mBAAqC;EACvF,MAAM,QAA6B,CAAC;EACpC,IAAI,UAAyC;EAC7C,OAAO,SAAS;GACd,MAAM,QAAQ,OAAO;GACrB,UAAU,QAAQ;EACpB;EACA,IAAI,WAAW;EACf,KAAK,MAAM,OAAO,OAChB,IAAI,IAAI,kBAAkB,WAAW,IAAI,iBAAiB,QAAQ;EAEpE,OAAO;CACT;CAEA,MAAM,OAAiC,SAAS,MAAM,UAAkC;EACtF,IAAI;GACF,MAAM,aAAa,OAAO,YAAY,WAAW,kBAAkB,SAAS,YAAY,QAAQ,IAAK;GACrG,IAAI,CAAC,YAAY,MAAM,IAAI,aAAa,YAAY,WAAW,GAAG,YAAY;GAC9E,IAAI,CAAC,WAAW,QAAQ,MAAM,IAAI,aAAa,YAAY,WAAW,KAAK,kBAAkB,EAAE,SAAS,WAAW,KAAK,CAAC;GAIzH,MAAM,aAAwC;IAC5C,SAAS;IACT,OAAO,KAAA;IACP,SAAS,CAAC;IACV,gBAAgB,CAAC;IACjB;IACA,QAAQ;IACR,SATkB,eAAe,YAAY,OAAO,OASjC;IACnB,SATqB,kBAAkB,UASjB;IACtB,SAAS,IAAI;IACb,QAAQ;GACV;GAEA,MAAM,eAAe,eAAoE;IACvF,MAAM,YAAkC;KACtC,SAAS,WAAW;KACpB,SAAS,WAAW;KACpB,SAAS,IAAI;KACb,QAAQ;KACR,SAAS,WAAW;KACpB,QAAQ;IACV;IAEA,OAAO,EAAE,QADM,WAAW,OAAQ,WAAW,MAAa,SAC5C,EAAE;GAClB;GAGA,MAAM,oBAAoB,oBAAoB,WADlB,8BAA8B,oBAAoB,YAAY,WAAW,mBAAG,IAAI,IAAI,CACrC,GAAG,YAAY,WAAW;GAErG,MAAM,YAAY,MAAgC,UAAU;IAAE,SAAS;IAAyB;IAAa,QAAQ,EAAE;GAAO,CAAC;GAE/H,IAAI,6BAA6B,SAC/B,OAAO,kBAAkB,KAAK,QAAQ,CAAC,CAAC,OAAO,QAAiB,YAAY,KAAK;IAAE,SAAS;IAAY;GAAK,CAAC,CAAC;GAEjH,OAAO,SAAS,iBAAiB;EACnC,SAAS,KAAK;GACZ,OAAO,YAAY,GAAG;EACxB;CACF;CAEA,MAAM,aAAwC;EAC5C,mBAAmB,WAAW;EAG9B,MAAM,cAAc,gHAFH,aAAa,aAAa,KAAA,GAAW,EAAE,QAAQ,OAAO,CAEoE;EAE3I,OAAO;GACL,MAAM;GACN,MAAM,YAAY;GAClB,QAAQ;GACR,OAAO,YAAY;GACnB;GACA,eAAe,CAAC,EAAE,OAAO,EAAE,SAAS,4CAA4C,EAAE,CAAC;GACnF,aAAa;KACV,OAAO,IAAI,kBAAkB,IAA6B;IAC3D,YAAY;KACV,MAAM;KACN,YAAY,EAAE,SAAS,EAAE,MAAM,SAAS,EAAE;KAC1C,sBAAsB;IACxB;IACA,OAAO,KAAA;IACP,WAAW,UAAU;KACnB,MAAM,UAAW,OAAe;KAChC,IAAI,OAAO,YAAY,UAAU,OAAO;MAAE,SAAS;MAAM,OAAO,EAAE,QAAQ;KAAE;KAC5E,OAAO;MAAE,SAAS;MAAO,uBAAO,IAAI,MAAM,qDAAqD;KAAE;IACnG;GACF;GACA,eAAe,OAAO,UAAU;IAC9B,MAAM,SAAS,MAAM,MAAM,MAAM,OAAO;IACxC,IAAI,OAAO,OAAO,QAAQ,kBAAkB,YAAY,OAAO,OAAO,QAAQ,cAAc,OAAO,IAAI;IACvG,IAAI,OAAO,QAAQ,iBAAiB,MAAM,OAAO,CAAC,CAAC,OAAO,QAAQ;IAClE,OAAO,CAAC,CAAC,OAAO,QAAQ;GAC1B;GACA,SAAS,OAAO,UAAU;IACxB,MAAM,SAAmB,CAAC;IAC1B,MAAM,SAAmB,CAAC;IAU1B,OAAO;KAAE,SAAQ,MATI,YAAY,MAAM,SAAS;MAC9C,QAAQ;MACR,SAAS;OACP,SAAS,GAAG,SAAS,OAAO,KAAK,KAAK,IAAI,MAAM,CAAC,CAAC,KAAK,GAAG,CAAC;OAC3D,QAAQ,SAAS,OAAO,KAAK,IAAI;OACjC,aAAa;OACb,QAAQ;MACV;KACF,CAAC,EAAA,CACuB;KAAQ,MAAM,OAAO,KAAK,IAAI;KAAG,OAAO,OAAO,KAAK,IAAI;IAAE;GACpF;EACF;CACF;CAEA,MAAM,gBAAgB,EAAE,OAAO,MAAM;CACrC,MAAM,UAAU,YACd,mBAAmB;EAAE,iBAAiB;EAAa;EAAa;CAAc,GAAG,OAAO;CAE1F,MAAM,OAAiC,eAAe;EACpD,IAAI;GAIF,MAAM,SAAS,YAHC,kBAAkB,WACL,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,KAAK,KAAA,GAET,KAAK,YAAY,QAAQ,KAAK;GAExE,IAAI,kBAAkB,SAAS,OAAO,iBAAiB,OAAO,OAAO,QAAiB,sBAAsB,GAAG,CAAC,CAAC;GACjH,OAAO,aAAa,MAAM;EAC5B,SAAS,KAAK;GACZ,OAAO,aAAa,sBAAsB,GAAG,CAAC;EAChD;CACF;CAEA,MAAM,QAAmC,YAAY;EACnD,IAAI,OAAO,YAAY,UAAU,OAAO,kBAAkB,QAAQ,MAAM,YAAY,QAAQ;EAC5F,OAAO,kBAAkB,SAAS,YAAY,QAAQ;CACxD;CAEA,MAAM,SAAqC,UAAU;EACnD,MAAM,EAAE,SAAS,SAAS,SAAS,IAAI,eAAe,KAA2B;EAIjF,OAAO,aACL,sBACE,UAJuB,qBAAqB,SAAS,SAAS,IAInC,IAAI,OAAY;GAAW;GAAgB,MAAM,EAAE;GAAM,YAAY,EAAE;EAAW,EAAE,GAC/G,OACF,CACF;CACF;CAEA,MAAM,QAAmC,SAAS,UAAU;EAC1D,mBAAmB,WAAW;EAC9B,MAAM,aAAa,CAAC,UAChB,cACA,OAAO,YAAY,WACjB,kBAAkB,SAAS,YAAY,QAAQ,IAC9C;EACP,IAAI,CAAC,YAAY,MAAM,IAAI,aAAa,YAAY,WAAW,GAAG,YAAY;EAC9E,MAAM,UAAU,kBAAkB,WAAW;EAC7C,OAAO,aAAa,aAAa,YAAY;GAC3C,GAAG;GACH,QAAQ,OAAO,UAAU,QAAQ;GACjC,OAAO,OAAO,SAAS,QAAQ;GAC/B,UAAU,OAAO,YAAY,QAAQ;GACrC,KAAK,OAAO,OAAO,QAAQ,IAAI;EACjC,CAAC;CACH;CAEA,MAAM,YAAsC;EAC1C,mBAAmB,WAAW;EAC9B,SAAS,SAAS,SAA4B;GAC5C,MAAM,eAAe,SAAS,IAAI,SAAS,IAAI,CAAC,CAAC;GACjD,IAAI,CAAC,QAAQ,UAAU,OAAO;GAC9B,KAAK,MAAM,OAAO,QAAQ,UAAU,WAAW,IAAI,QAAQ,SAAS,GAAG;GACvE,OAAO;EACT;EACA,OAAO,SAAS,WAAW;CAC7B;CAEA,MAAM,aAA8C,OAAO,UAAU;EACnE,mBAAmB,WAAW;EAC9B,MAAM,EAAE,6BAA6B,MAAM,OAAO;EAClD,OAAO,yBAAyB,aAAa,KAA8B;CAC7E;CAEA,MAAM,MAAgC,OAAO,UAAU;EACrD,mBAAmB,WAAW;EAC9B,MAAM,EAAE,mBAAmB,MAAM,OAAO;EACxC,OAAO,eAAe,IAAI,SAAgB,aAAa,aAAa,KAAK;CAC3E;CAEA,MAAM,QAAoC,OAAO,UAAU;EACzD,mBAAmB,WAAW;EAC9B,MAAM,EAAE,qBAAqB,MAAM,OAAO;EAC1C,OAAO,iBAAiB,IAAI,SAAgB,aAAa,aAAa,KAAK;CAC7E;CAEA,OAAO;EACL;EACA;EACA;EACA;EACA,MAAM;EACN;EACA;EACA,MAAM;EACN;EACA;EACA;EACA;EACA;CACF;AACF"}
@@ -0,0 +1,13 @@
1
+ import { PadroneSchema } from "../types/schema.mjs";
2
+ //#region src/core/results.d.ts
3
+ /**
4
+ * Brands a schema as async, signaling that its `validate()` may return a Promise.
5
+ * When an async-branded schema is passed to `.arguments()`, `.configFile()`, or `.env()`,
6
+ * the command's `parse()` and `cli()` will return Promises.
7
+ */
8
+ declare function asyncSchema<T extends PadroneSchema>(schema: T): T & {
9
+ '~async': true;
10
+ };
11
+ //#endregion
12
+ export { asyncSchema };
13
+ //# sourceMappingURL=results.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"results.d.mts","names":[],"sources":["../../src/core/results.ts"],"mappings":";;;;;AASA;;iBAAgB,WAAA,WAAsB,aAAA,EAAe,MAAA,EAAQ,CAAA,GAAI,CAAA;EAAM,QAAA;AAAA"}
@@ -0,0 +1,150 @@
1
+ import { getCommandRuntime } from "./commands.mjs";
2
+ //#region src/core/results.ts
3
+ /**
4
+ * Brands a schema as async, signaling that its `validate()` may return a Promise.
5
+ * When an async-branded schema is passed to `.arguments()`, `.configFile()`, or `.env()`,
6
+ * the command's `parse()` and `cli()` will return Promises.
7
+ */
8
+ function asyncSchema(schema) {
9
+ return Object.assign(schema, { "~async": true });
10
+ }
11
+ const noop = () => void 0;
12
+ /**
13
+ * Maps over a value that may or may not be a Promise.
14
+ * If the value is a Promise, chains with `.then()`. Otherwise, calls the function synchronously.
15
+ * This preserves sync behavior for sync schemas and async behavior for async schemas.
16
+ */
17
+ function thenMaybe(value, fn) {
18
+ if (value instanceof Promise) return value.then(fn);
19
+ return fn(value);
20
+ }
21
+ /**
22
+ * Makes a sync result object thenable by adding `.then()`, `.catch()`, and `.finally()` methods.
23
+ * If the value is already a Promise, returns it as-is.
24
+ * This allows users to write `await program.cli()` or `program.cli().then(...)` regardless of sync/async.
25
+ *
26
+ * The `.then()` resolves with a plain copy (without thenable methods) to avoid infinite
27
+ * recursive unwrapping by the Promise resolution algorithm.
28
+ */
29
+ function makeThenable(value) {
30
+ if (value instanceof Promise) return value;
31
+ if (value !== null && typeof value === "object" && !("then" in value)) {
32
+ const toPlain = () => {
33
+ const plain = { ...value };
34
+ delete plain.then;
35
+ delete plain.catch;
36
+ delete plain.finally;
37
+ return plain;
38
+ };
39
+ value.then = (onfulfilled, onrejected) => {
40
+ try {
41
+ const result = onfulfilled ? onfulfilled(toPlain()) : toPlain();
42
+ return Promise.resolve(result);
43
+ } catch (err) {
44
+ if (onrejected) return Promise.resolve(onrejected(err));
45
+ return Promise.reject(err);
46
+ }
47
+ };
48
+ value.catch = (onrejected) => value.then(void 0, onrejected);
49
+ value.finally = (onfinally) => value.then((v) => {
50
+ onfinally?.();
51
+ return v;
52
+ }, (err) => {
53
+ onfinally?.();
54
+ throw err;
55
+ });
56
+ }
57
+ return value;
58
+ }
59
+ /**
60
+ * Wraps a Promise to include a `drain()` method at the top level.
61
+ * This allows `await promise.drain()` without first awaiting the promise.
62
+ * Since cli/eval never reject, this just delegates to the resolved result's `drain()`.
63
+ */
64
+ function withPromiseDrain(promise) {
65
+ promise.drain = async () => {
66
+ return (await promise).drain();
67
+ };
68
+ return promise;
69
+ }
70
+ function isIterator(value) {
71
+ return typeof value === "object" && value !== null && Symbol.iterator in value && typeof value[Symbol.iterator] === "function";
72
+ }
73
+ function isAsyncIterator(value) {
74
+ return typeof value === "object" && value !== null && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
75
+ }
76
+ /**
77
+ * Resolves a result value by unwrapping Promises and collecting iterables into arrays.
78
+ * This is the runtime counterpart of the `Drained<T>` type.
79
+ */
80
+ async function drainValue(value) {
81
+ if (value instanceof Promise) return drainValue(await value);
82
+ if (isAsyncIterator(value)) {
83
+ const items = [];
84
+ const iter = value[Symbol.asyncIterator]();
85
+ while (true) {
86
+ const { done, value: item } = await iter.next();
87
+ if (done) break;
88
+ items.push(item);
89
+ }
90
+ return items;
91
+ }
92
+ if (typeof value !== "string" && !Array.isArray(value) && isIterator(value)) {
93
+ const items = [];
94
+ const iter = value[Symbol.iterator]();
95
+ while (true) {
96
+ const { done, value: item } = iter.next();
97
+ if (done) break;
98
+ items.push(item);
99
+ }
100
+ return items;
101
+ }
102
+ return value;
103
+ }
104
+ /**
105
+ * Attaches a `drain()` method to a command result object.
106
+ * If the result has an `error` field, `drain()` returns `{ error }`.
107
+ * Otherwise, resolves the result (unwrapping Promises, collecting iterables), catches errors,
108
+ * and returns a discriminated union `{ value } | { error }` that never throws.
109
+ */
110
+ function withDrain(obj) {
111
+ obj.drain = async () => {
112
+ if ("error" in obj && obj.error !== void 0) return { error: obj.error };
113
+ try {
114
+ return { value: await drainValue(obj.result) };
115
+ } catch (err) {
116
+ return { error: err };
117
+ }
118
+ };
119
+ return obj;
120
+ }
121
+ /**
122
+ * Creates an error command result with a `drain()` that returns the error.
123
+ */
124
+ function errorResult(error, partial) {
125
+ return withDrain({
126
+ error,
127
+ result: void 0,
128
+ command: partial?.command,
129
+ args: partial?.args,
130
+ argsResult: partial?.argsResult
131
+ });
132
+ }
133
+ function isAsyncBranded(schema) {
134
+ return !!schema && typeof schema === "object" && "~async" in schema && schema["~async"] === true;
135
+ }
136
+ function hasInteractiveConfig(meta) {
137
+ if (!meta || typeof meta !== "object") return false;
138
+ const m = meta;
139
+ return m.interactive === true || Array.isArray(m.interactive) || m.optionalInteractive === true || Array.isArray(m.optionalInteractive);
140
+ }
141
+ function warnIfUnexpectedAsync(value, command) {
142
+ const runtime = getCommandRuntime(command);
143
+ if (runtime.env().NODE_ENV === "production") return value;
144
+ if (value instanceof Promise && !command.isAsync) runtime.error(`[padrone] Command "${command.path || command.name}" returned a Promise from validation, but was not marked as async. Use \`.async()\` on the builder or \`asyncSchema()\` to brand your schema. Without this, TypeScript will infer a sync return type and the result will be a Promise at runtime.`);
145
+ return value;
146
+ }
147
+ //#endregion
148
+ export { asyncSchema, drainValue, errorResult, hasInteractiveConfig, isAsyncBranded, isAsyncIterator, isIterator, makeThenable, noop, thenMaybe, warnIfUnexpectedAsync, withDrain, withPromiseDrain };
149
+
150
+ //# sourceMappingURL=results.mjs.map