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,144 @@
1
+ //#region src/codegen/types.d.ts
2
+ /**
3
+ * Metadata for a single field/option/flag parsed from CLI help or completion data.
4
+ */
5
+ interface FieldMeta {
6
+ name: string;
7
+ type: 'string' | 'number' | 'boolean' | 'array' | 'enum' | 'unknown';
8
+ /** For arrays: the item type */
9
+ items?: string;
10
+ /** For enums: the allowed values */
11
+ enumValues?: string[];
12
+ description?: string;
13
+ default?: unknown;
14
+ required?: boolean;
15
+ aliases?: string[];
16
+ positional?: boolean;
17
+ /** Mark fields the parser wasn't confident about */
18
+ ambiguous?: boolean;
19
+ }
20
+ /**
21
+ * Intermediate representation for a CLI command.
22
+ * All parsers produce these, all generators consume them.
23
+ */
24
+ interface CommandMeta {
25
+ name: string;
26
+ description?: string;
27
+ aliases?: string[];
28
+ /** Named options/flags */
29
+ arguments?: FieldMeta[];
30
+ /** Positional arguments */
31
+ positionals?: FieldMeta[];
32
+ /** Recursive subcommands */
33
+ subcommands?: CommandMeta[];
34
+ examples?: string[];
35
+ deprecated?: boolean | string;
36
+ }
37
+ /**
38
+ * Logger interface for generators to report progress.
39
+ */
40
+ interface GeneratorLogger {
41
+ info(message: string): void;
42
+ warn(message: string): void;
43
+ error(message: string): void;
44
+ success(message: string): void;
45
+ }
46
+ /**
47
+ * Shared context passed to all generators.
48
+ */
49
+ interface GeneratorContext {
50
+ /** Target output directory */
51
+ outDir: string;
52
+ /** Code builder factory */
53
+ createCodeBuilder: () => CodeBuilder;
54
+ /** File emitter for writing output */
55
+ emitter: FileEmitter;
56
+ /** Template engine */
57
+ template: TemplateFunction;
58
+ /** User-facing logger */
59
+ log: GeneratorLogger;
60
+ }
61
+ /**
62
+ * Result from CodeBuilder.build()
63
+ */
64
+ interface CodeBuildResult {
65
+ /** The formatted source string */
66
+ text: string;
67
+ /** Resolved import map for deduplication across files */
68
+ imports: Map<string, {
69
+ specifiers: Set<string>;
70
+ typeOnly: boolean;
71
+ }>;
72
+ }
73
+ /**
74
+ * Fluent builder for constructing TypeScript source files.
75
+ */
76
+ interface CodeBuilder {
77
+ /** Add a named import: import { specifier } from source */
78
+ import(specifier: string | string[], source: string): CodeBuilder;
79
+ /** Add a default import: import name from source */
80
+ importDefault(name: string, source: string): CodeBuilder;
81
+ /** Add a type-only import: import type { specifier } from source */
82
+ importType(specifier: string | string[], source: string): CodeBuilder;
83
+ /** Add a line of code (empty string or no argument for blank line) */
84
+ line(code?: string): CodeBuilder;
85
+ /** Add a nested block with automatic indentation */
86
+ block(builder: (b: CodeBuilder) => CodeBuilder): CodeBuilder;
87
+ /** Add a nested block with open/close strings */
88
+ block(open: string, builder: (b: CodeBuilder) => CodeBuilder, close?: string): CodeBuilder;
89
+ /** Add a nested block with open string, close string override, and builder */
90
+ block(open: string, close: string, builder: (b: CodeBuilder) => CodeBuilder): CodeBuilder;
91
+ /** Add a single-line comment */
92
+ comment(text: string): CodeBuilder;
93
+ /** Add a JSDoc comment */
94
+ docComment(text: string): CodeBuilder;
95
+ /** Add a TODO comment */
96
+ todoComment(text: string): CodeBuilder;
97
+ /** Add raw pre-formatted code (no indentation adjustment) */
98
+ raw(code: string): CodeBuilder;
99
+ /** Build the final source string */
100
+ build(): CodeBuildResult;
101
+ }
102
+ /**
103
+ * Result from FileEmitter.emit()
104
+ */
105
+ interface EmitResult {
106
+ /** Files that were written */
107
+ written: string[];
108
+ /** Files that were skipped (already exist, no overwrite) */
109
+ skipped: string[];
110
+ /** Files that failed to write */
111
+ errors: {
112
+ file: string;
113
+ error: Error;
114
+ }[];
115
+ }
116
+ /**
117
+ * Options for creating a FileEmitter.
118
+ */
119
+ interface FileEmitterOptions {
120
+ /** Target output directory */
121
+ outDir: string;
122
+ /** Header comment prepended to every file */
123
+ header?: string;
124
+ /** How to handle existing files: true = overwrite, false = skip */
125
+ overwrite?: boolean;
126
+ /** Print what would be written without writing */
127
+ dryRun?: boolean;
128
+ }
129
+ /**
130
+ * Manages writing multiple generated files to disk.
131
+ */
132
+ interface FileEmitter {
133
+ /** Queue a file for writing */
134
+ addFile(path: string, content: string | CodeBuildResult): void;
135
+ /** Write all queued files to disk */
136
+ emit(): Promise<EmitResult>;
137
+ }
138
+ /**
139
+ * Template function returned by template().
140
+ */
141
+ type TemplateFunction = (text: string) => (data: Record<string, unknown>) => string;
142
+ //#endregion
143
+ export { CodeBuildResult, CodeBuilder, CommandMeta, EmitResult, FieldMeta, FileEmitter, FileEmitterOptions, GeneratorContext, GeneratorLogger, TemplateFunction };
144
+ //# sourceMappingURL=types.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.mts","names":[],"sources":["../../src/codegen/types.ts"],"mappings":";;AAGA;;UAAiB,SAAA;EACf,IAAA;EACA,IAAA;EAAA;EAEA,KAAA;EAEA;EAAA,UAAA;EACA,WAAA;EACA,OAAA;EACA,QAAA;EACA,OAAA;EACA,UAAA;EAES;EAAT,SAAA;AAAA;;;;;UAOe,WAAA;EACf,IAAA;EACA,WAAA;EACA,OAAA;EADA;EAGA,SAAA,GAAY,SAAA;EAAZ;EAEA,WAAA,GAAc,SAAA;EAAd;EAEA,WAAA,GAAc,WAAA;EACd,QAAA;EACA,UAAA;AAAA;;;AAAU;UAMK,eAAA;EACf,IAAA,CAAK,OAAA;EACL,IAAA,CAAK,OAAA;EACL,KAAA,CAAM,OAAA;EACN,OAAA,CAAQ,OAAA;AAAA;;;;UAMO,gBAAA;EANf;EAQA,MAAA;EARuB;EAUvB,iBAAA,QAAyB,WAAA;EAJV;EAMf,OAAA,EAAS,WAAA;;EAET,QAAA,EAAU,gBAAA;EAFD;EAIT,GAAA,EAAK,eAAA;AAAA;;;;UAMU,eAAA;EAZU;EAczB,IAAA;EAZS;EAcT,OAAA,EAAS,GAAG;IAAW,UAAA,EAAY,GAAA;IAAa,QAAA;EAAA;AAAA;AAV5B;AAMtB;;AANsB,UAgBL,WAAA;EANH;EAQZ,MAAA,CAAO,SAAA,qBAA8B,MAAA,WAAiB,WAAA;EARtD;EAUA,aAAA,CAAc,IAAA,UAAc,MAAA,WAAiB,WAAA;EAVtB;EAYvB,UAAA,CAAW,SAAA,qBAA8B,MAAA,WAAiB,WAAA;EAZV;EAchD,IAAA,CAAK,IAAA,YAAgB,WAAA;EAdmC;EAgBxD,KAAA,CAAM,OAAA,GAAU,CAAA,EAAG,WAAA,KAAgB,WAAA,GAAc,WAAA;EAVvB;EAY1B,KAAA,CAAM,IAAA,UAAc,OAAA,GAAU,CAAA,EAAG,WAAA,KAAgB,WAAA,EAAa,KAAA,YAAiB,WAAA;EAVzB;EAYtD,KAAA,CAAM,IAAA,UAAc,KAAA,UAAe,OAAA,GAAU,CAAA,EAAG,WAAA,KAAgB,WAAA,GAAc,WAAA;EARpB;EAU1D,OAAA,CAAQ,IAAA,WAAe,WAAA;EANJ;EAQnB,UAAA,CAAW,IAAA,WAAe,WAAA;EARuB;EAUjD,WAAA,CAAY,IAAA,WAAe,WAAA;EARsB;EAUjD,GAAA,CAAI,IAAA,WAAe,WAAA;EAR6B;EAUhD,KAAA,IAAS,eAAA;AAAA;;;;UAMM,UAAA;EANN;EAQT,OAAA;EARwB;EAUxB,OAAA;EAhCO;EAkCP,MAAA;IAAU,IAAA;IAAc,KAAA,EAAO,KAAK;EAAA;AAAA;;;;UAMrB,kBAAA;EApC2C;EAsC1D,MAAA;EApCK;EAsCL,MAAA;EApCA;EAsCA,SAAA;EAtCgB;EAwChB,MAAA;AAAA;;;;UAMe,WAAA;EA5Ce;EA8C9B,OAAA,CAAQ,IAAA,UAAc,OAAA,WAAkB,eAAA;EA9CpB;EAgDpB,IAAA,IAAQ,OAAA,CAAQ,UAAA;AAAA;;;;KAMN,gBAAA,IAAoB,IAAA,cAAkB,IAAA,EAAM,MAAM"}
@@ -0,0 +1,2 @@
1
+ import { WithCompletion, padroneCompletion } from "./extension/completion.mjs";
2
+ export { type WithCompletion, padroneCompletion };
@@ -0,0 +1,2 @@
1
+ import { padroneCompletion } from "./extension/completion.mjs";
2
+ export { padroneCompletion };
@@ -0,0 +1,3 @@
1
+ import { PadroneArgsSchemaMeta, PadroneFieldMeta, SingleChar, StdinConfig } from "../types/args-meta.mjs";
2
+ import { StandardJSONSchemaV1, StandardSchemaV1 } from "@standard-schema/spec";
3
+ export type { PadroneFieldMeta };
@@ -1,81 +1,5 @@
1
- import { n as asyncStreamRegistry } from "./stream-DC4H8YTx.mjs";
2
- //#region src/util/shell-utils.ts
3
- /**
4
- * Convert a camelCase string to kebab-case.
5
- * Returns null if the string has no uppercase letters (no conversion needed).
6
- */
7
- function camelToKebab(str) {
8
- if (!/[A-Z]/.test(str)) return null;
9
- return str.replace(/[A-Z]/g, (ch) => `-${ch.toLowerCase()}`);
10
- }
11
- /**
12
- * Detects the current shell from environment variables and process info.
13
- * @returns The detected shell type, or undefined if unknown
14
- */
15
- async function detectShell() {
16
- if (typeof process === "undefined") return void 0;
17
- const shellEnv = process.env.SHELL || "";
18
- if (shellEnv.includes("zsh")) return "zsh";
19
- if (shellEnv.includes("bash")) return "bash";
20
- if (shellEnv.includes("fish")) return "fish";
21
- if (process.env.PSModulePath || process.env.POWERSHELL_DISTRIBUTION_CHANNEL) return "powershell";
22
- try {
23
- const ppid = process.ppid;
24
- if (ppid) {
25
- const { execSync } = await import("node:child_process");
26
- const processName = execSync(`ps -p ${ppid} -o comm=`, {
27
- encoding: "utf-8",
28
- stdio: [
29
- "pipe",
30
- "pipe",
31
- "ignore"
32
- ]
33
- }).trim();
34
- if (processName.includes("zsh")) return "zsh";
35
- if (processName.includes("bash")) return "bash";
36
- if (processName.includes("fish")) return "fish";
37
- }
38
- } catch {}
39
- }
40
- async function getRcFile(shell, home) {
41
- const { homedir } = await import("node:os");
42
- const { join } = await import("node:path");
43
- const h = home ?? homedir();
44
- switch (shell) {
45
- case "bash": return join(h, ".bashrc");
46
- case "zsh": return join(h, ".zshrc");
47
- case "fish": return join(h, ".config", "fish", "config.fish");
48
- case "powershell": return (typeof process !== "undefined" ? process.env.PROFILE : void 0) || join(h, "Documents", "PowerShell", "Microsoft.PowerShell_profile.ps1");
49
- default: return null;
50
- }
51
- }
52
- function escapeRegExp(str) {
53
- return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
54
- }
55
- /**
56
- * Writes a snippet to a shell config file using begin/end markers for idempotency.
57
- * If a block with the same begin marker exists, it is replaced. Otherwise the snippet is appended.
58
- */
59
- async function writeToRcFile(rcFile, snippet, beginMarker, endMarker) {
60
- const { existsSync, mkdirSync, readFileSync, writeFileSync } = await import("node:fs");
61
- const { dirname } = await import("node:path");
62
- const existing = existsSync(rcFile) ? readFileSync(rcFile, "utf-8") : "";
63
- if (existing.includes(beginMarker)) {
64
- const pattern = new RegExp(`${escapeRegExp(beginMarker)}[\\s\\S]*?${escapeRegExp(endMarker)}`);
65
- writeFileSync(rcFile, existing.replace(pattern, snippet));
66
- return {
67
- file: rcFile,
68
- updated: true
69
- };
70
- }
71
- mkdirSync(dirname(rcFile), { recursive: true });
72
- writeFileSync(rcFile, `${existing}${existing.length > 0 && !existing.endsWith("\n") ? "\n" : ""}\n${snippet}\n`);
73
- return {
74
- file: rcFile,
75
- updated: false
76
- };
77
- }
78
- //#endregion
1
+ import { camelToKebab } from "../util/shell-utils.mjs";
2
+ import { asyncStreamRegistry } from "../util/stream.mjs";
79
3
  //#region src/core/args.ts
80
4
  /** Extract the JSON schema from a Standard Schema, returning it as a plain record. */
81
5
  function getJsonSchema(schema) {
@@ -281,7 +205,7 @@ function detectUnknownArgs(data, schema, flags, aliases, negatives) {
281
205
  return [];
282
206
  }
283
207
  if (isLoose) return [];
284
- const knownKeys = new Set([
208
+ const knownKeys = /* @__PURE__ */ new Set([
285
209
  ...Object.keys(properties),
286
210
  ...Object.keys(flags),
287
211
  ...Object.values(flags),
@@ -295,6 +219,6 @@ function detectUnknownArgs(data, schema, flags, aliases, negatives) {
295
219
  return unknowns;
296
220
  }
297
221
  //#endregion
298
- export { getJsonSchema as a, parsePositionalConfig as c, detectShell as d, escapeRegExp as f, extractSchemaMetadata as i, preprocessArgs as l, writeToRcFile as m, coerceArgs as n, isArrayField as o, getRcFile as p, detectUnknownArgs as r, isAsyncStreamField as s, applyValues as t, camelToKebab as u };
222
+ export { applyValues, coerceArgs, detectUnknownArgs, extractSchemaMetadata, getJsonSchema, isArrayField, isAsyncStreamField, parsePositionalConfig, preprocessArgs };
299
223
 
300
- //# sourceMappingURL=args-WmyGc59s.mjs.map
224
+ //# sourceMappingURL=args.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"args.mjs","names":[],"sources":["../../src/core/args.ts"],"sourcesContent":["import type { StandardJSONSchemaV1, StandardSchemaV1 } from '@standard-schema/spec';\nimport type { PadroneFieldMeta } from '../types/args-meta.ts';\nimport { camelToKebab } from '../util/shell-utils.ts';\nimport { asyncStreamRegistry } from '../util/stream.ts';\n\nexport type { PadroneArgsSchemaMeta, PadroneFieldMeta, SingleChar, StdinConfig } from '../types/args-meta.ts';\n\n/** Extract the JSON schema from a Standard Schema, returning it as a plain record. */\nexport function getJsonSchema(schema: StandardJSONSchemaV1): Record<string, any> {\n return schema['~standard'].jsonSchema.input({\n target: 'draft-2020-12',\n libraryOptions: { unrepresentable: 'any' },\n }) as Record<string, any>;\n}\n\nfunction getFieldJsonSchema(schema: StandardJSONSchemaV1 | undefined, field: string): Record<string, any> | undefined {\n if (!schema) return undefined;\n try {\n const jsonSchema = getJsonSchema(schema);\n if (jsonSchema.type === 'object' && jsonSchema.properties) return jsonSchema.properties[field];\n } catch {}\n return undefined;\n}\n\n/**\n * Checks if a field in the schema is an array type (e.g. `z.string().array()`).\n */\nexport function isArrayField(schema: StandardJSONSchemaV1 | undefined, field: string): boolean {\n return getFieldJsonSchema(schema, field)?.type === 'array';\n}\n\n/**\n * Checks if a field is an async stream (marked with `asyncStream()` metadata).\n * Returns the item schema if provided, or `true` if it's a plain string stream.\n */\nexport function isAsyncStreamField(schema: StandardJSONSchemaV1 | undefined, field: string): { itemSchema?: StandardSchemaV1 } | false {\n const prop = getFieldJsonSchema(schema, field);\n const asyncStreamId = prop?.asyncStream;\n if (asyncStreamId && asyncStreamRegistry.has(asyncStreamId)) {\n const meta = asyncStreamRegistry.get(asyncStreamId);\n return { itemSchema: meta?.itemSchema };\n }\n\n return false;\n}\n\n/**\n * Parse positional configuration to extract names and variadic info.\n */\nexport function parsePositionalConfig(positional: readonly string[]): { name: string; variadic: boolean }[] {\n return positional.map((p) => {\n const variadic = p.startsWith('...');\n const name = variadic ? p.slice(3) : p;\n return { name, variadic };\n });\n}\n\n/**\n * Result type for extractSchemaMetadata function.\n */\ninterface SchemaMetadataResult {\n /** Single-char flags: maps flag char → full arg name (e.g. `{ v: 'verbose' }`) */\n flags: Record<string, string>;\n /** Multi-char aliases: maps alias → full arg name (e.g. `{ 'dry-run': 'dryRun' }`) */\n aliases: Record<string, string>;\n /** Negative keywords: maps keyword → target arg name (e.g. `{ remote: 'local' }`) */\n negatives: Record<string, string>;\n /** Args that have custom negation set (even if empty), disabling the `--no-` prefix */\n customNegation: Set<string>;\n}\n\nfunction addEntries(target: Record<string, string>, key: string, items: string | readonly string[], filter?: (item: string) => boolean) {\n const list = typeof items === 'string' ? [items] : items;\n for (const item of list) {\n if (typeof item === 'string' && item && item !== key && !(item in target) && (!filter || filter(item))) {\n target[item] = key;\n }\n }\n}\n\n/**\n * Extract all arg metadata from schema and meta in a single pass.\n * Returns flags (single-char, stackable) and aliases (multi-char, long names) separately.\n * When `autoAlias` is true (default), camelCase property names automatically get kebab-case aliases.\n */\nexport function extractSchemaMetadata(\n schema: StandardJSONSchemaV1,\n meta?: Record<string, PadroneFieldMeta | undefined>,\n autoAlias?: boolean,\n): SchemaMetadataResult {\n const flags: Record<string, string> = {};\n const aliases: Record<string, string> = {};\n const negatives: Record<string, string> = {};\n const customNegation = new Set<string>();\n\n // Extract from meta object\n if (meta) {\n for (const [key, value] of Object.entries(meta)) {\n if (!value) continue;\n\n if (value.flags) {\n addEntries(flags, key, value.flags, (item) => item.length === 1);\n }\n if (value.alias) {\n addEntries(aliases, key, value.alias, (item) => item.length > 1);\n }\n if (value.negative !== undefined) {\n customNegation.add(key);\n addEntries(negatives, key, value.negative);\n }\n }\n }\n\n // Extract from JSON schema properties\n try {\n const jsonSchema = getJsonSchema(schema) as Record<string, any>;\n if (jsonSchema.type === 'object' && jsonSchema.properties) {\n for (const [propertyName, propertySchema] of Object.entries(jsonSchema.properties as Record<string, any>)) {\n if (!propertySchema) continue;\n\n // Extract flags from schema `.meta({ flags: ... })`\n const propFlags = propertySchema.flags;\n if (propFlags) {\n addEntries(flags, propertyName, propFlags, (item) => item.length === 1);\n }\n\n // Extract aliases from schema `.meta({ alias: ... })`\n const propAlias = propertySchema.alias;\n if (propAlias) {\n const list = typeof propAlias === 'string' ? [propAlias] : propAlias;\n if (Array.isArray(list)) {\n addEntries(aliases, propertyName, list, (item) => item.length > 1);\n }\n }\n\n // Extract negative keywords from schema `.meta({ negative: ... })`\n const propNegative = propertySchema.negative;\n if (propNegative !== undefined && !customNegation.has(propertyName)) {\n customNegation.add(propertyName);\n const list = typeof propNegative === 'string' ? [propNegative] : propNegative;\n if (Array.isArray(list)) {\n addEntries(negatives, propertyName, list);\n }\n }\n\n // Auto-generate kebab-case alias for camelCase property names\n if (autoAlias !== false) {\n const kebab = camelToKebab(propertyName);\n if (kebab && !(kebab in aliases)) {\n aliases[kebab] = propertyName;\n }\n }\n }\n }\n } catch {\n // Ignore errors from JSON schema generation\n }\n\n return { flags, aliases, negatives, customNegation };\n}\n\nfunction preprocessMappings(data: Record<string, unknown>, mappings: Record<string, string>): Record<string, unknown> {\n const result = { ...data };\n\n for (const [mappedKey, fullArgName] of Object.entries(mappings)) {\n if (mappedKey in data && mappedKey !== fullArgName) {\n const mappedValue = data[mappedKey];\n // Prefer full arg name if it exists\n if (!(fullArgName in result)) result[fullArgName] = mappedValue;\n delete result[mappedKey];\n }\n }\n\n return result;\n}\n\n/**\n * Apply values to arguments using \"set if not present\" semantics.\n * Existing values take precedence — only fills in undefined or missing keys.\n */\nexport function applyValues(data: Record<string, unknown>, values: Record<string, unknown>): Record<string, unknown> {\n const result = { ...data };\n\n for (const [key, value] of Object.entries(values)) {\n if (key in result && result[key] !== undefined) continue;\n if (value !== undefined) {\n result[key] = value;\n }\n }\n\n return result;\n}\n\n/** Applies flag and alias mappings to raw arguments. */\nexport function preprocessArgs(\n data: Record<string, unknown>,\n ctx: { flags?: Record<string, string>; aliases?: Record<string, string> },\n): Record<string, unknown> {\n let result = { ...data };\n\n if (ctx.flags && Object.keys(ctx.flags).length > 0) {\n result = preprocessMappings(result, ctx.flags);\n }\n if (ctx.aliases && Object.keys(ctx.aliases).length > 0) {\n result = preprocessMappings(result, ctx.aliases);\n }\n\n return result;\n}\n\n/**\n * Walk a JSON schema fragment and collect the set of allowed primitive types,\n * descending into `anyOf` / `oneOf` (used for unions). For variants whose type\n * is `array`, item types are collected separately into `itemTypes`.\n */\nfunction collectAllowedTypes(prop: Record<string, any> | undefined, types: Set<string>, itemTypes: Set<string>): void {\n if (!prop) return;\n\n if (prop.type !== undefined) {\n const list = Array.isArray(prop.type) ? prop.type : [prop.type];\n for (const t of list) {\n if (typeof t === 'string') types.add(t);\n }\n if (list.includes('array') && prop.items) {\n collectAllowedTypes(prop.items, itemTypes, new Set());\n }\n }\n\n const variants = prop.anyOf ?? prop.oneOf;\n if (Array.isArray(variants)) {\n for (const variant of variants) collectAllowedTypes(variant, types, itemTypes);\n }\n}\n\n/** Coerce a single CLI string to a primitive based on the set of allowed types. */\nfunction coerceScalar(value: unknown, allowedTypes: Set<string>): unknown {\n if (typeof value !== 'string') return value;\n\n if (allowedTypes.has('boolean')) {\n const lower = value.toLowerCase();\n if (lower === 'true' || lower === '1' || lower === 'yes' || lower === 'on') return true;\n if (lower === 'false' || lower === '0' || lower === 'no' || lower === 'off') return false;\n }\n\n if (allowedTypes.has('number') || allowedTypes.has('integer')) {\n const trimmed = value.trim();\n if (trimmed !== '') {\n const num = Number(trimmed);\n if (!Number.isNaN(num)) return num;\n }\n }\n\n return value;\n}\n\n/**\n * Auto-coerce CLI string values to match the expected schema types.\n * Handles: string → number, string → boolean for primitive schema fields.\n * Arrays of primitives are also coerced element-wise.\n * Union types (`anyOf` / `oneOf`) are coerced to the most specific matching\n * primitive — e.g. `--test true` for `z.union([z.boolean(), z.string()])`\n * becomes the boolean `true` rather than the string \"true\".\n */\nexport function coerceArgs(data: Record<string, unknown>, schema: StandardJSONSchemaV1): Record<string, unknown> {\n let properties: Record<string, any>;\n try {\n const jsonSchema = getJsonSchema(schema) as Record<string, any>;\n if (jsonSchema.type !== 'object' || !jsonSchema.properties) return data;\n properties = jsonSchema.properties;\n } catch {\n return data;\n }\n\n const result = { ...data };\n\n for (const [key, value] of Object.entries(result)) {\n const prop = properties[key];\n if (!prop) continue;\n\n const types = new Set<string>();\n const itemTypes = new Set<string>();\n collectAllowedTypes(prop, types, itemTypes);\n\n const isArrayValue = Array.isArray(value);\n const allowsArray = types.has('array');\n const allowsScalar = types.has('string') || types.has('boolean') || types.has('number') || types.has('integer');\n\n if (isArrayValue && allowsArray) {\n result[key] = value.map((v) => coerceScalar(v, itemTypes));\n } else if (!isArrayValue && allowsArray && !allowsScalar) {\n // Wrap single value into an array when only array shapes are allowed\n result[key] = [coerceScalar(value, itemTypes)];\n } else if (!isArrayValue) {\n result[key] = coerceScalar(value, types);\n }\n }\n\n return result;\n}\n\n/**\n * Detect unknown keys in the args that don't match any schema property.\n * Returns an array of { key } for each unknown key.\n * Framework-reserved keys (--config, -c) are always allowed.\n */\nexport function detectUnknownArgs(\n data: Record<string, unknown>,\n schema: StandardJSONSchemaV1,\n flags: Record<string, string>,\n aliases: Record<string, string>,\n negatives?: Record<string, string>,\n): { key: string }[] {\n let properties: Record<string, any>;\n let isLoose = false;\n try {\n const jsonSchema = getJsonSchema(schema) as Record<string, any>;\n if (jsonSchema.type !== 'object' || !jsonSchema.properties) return [];\n properties = jsonSchema.properties;\n // If additionalProperties is set (true, {}, or a schema), the schema allows extra keys\n if (jsonSchema.additionalProperties !== undefined && jsonSchema.additionalProperties !== false) isLoose = true;\n } catch {\n return [];\n }\n\n if (isLoose) return [];\n\n const knownKeys = new Set<string>([\n ...Object.keys(properties),\n ...Object.keys(flags),\n ...Object.values(flags),\n ...Object.keys(aliases),\n ...Object.values(aliases),\n ...(negatives ? Object.keys(negatives) : []),\n ...(negatives ? Object.values(negatives) : []),\n ]);\n const unknowns: { key: string }[] = [];\n\n for (const key of Object.keys(data)) {\n if (!knownKeys.has(key)) {\n unknowns.push({ key });\n }\n }\n\n return unknowns;\n}\n"],"mappings":";;;;AAQA,SAAgB,cAAc,QAAmD;CAC/E,OAAO,OAAO,YAAY,CAAC,WAAW,MAAM;EAC1C,QAAQ;EACR,gBAAgB,EAAE,iBAAiB,MAAM;CAC3C,CAAC;AACH;AAEA,SAAS,mBAAmB,QAA0C,OAAgD;CACpH,IAAI,CAAC,QAAQ,OAAO,KAAA;CACpB,IAAI;EACF,MAAM,aAAa,cAAc,MAAM;EACvC,IAAI,WAAW,SAAS,YAAY,WAAW,YAAY,OAAO,WAAW,WAAW;CAC1F,QAAQ,CAAC;AAEX;;;;AAKA,SAAgB,aAAa,QAA0C,OAAwB;CAC7F,OAAO,mBAAmB,QAAQ,KAAK,CAAC,EAAE,SAAS;AACrD;;;;;AAMA,SAAgB,mBAAmB,QAA0C,OAA0D;CAErI,MAAM,gBADO,mBAAmB,QAAQ,KACf,CAAC,EAAE;CAC5B,IAAI,iBAAiB,oBAAoB,IAAI,aAAa,GAExD,OAAO,EAAE,YADI,oBAAoB,IAAI,aACb,CAAC,EAAE,WAAW;CAGxC,OAAO;AACT;;;;AAKA,SAAgB,sBAAsB,YAAsE;CAC1G,OAAO,WAAW,KAAK,MAAM;EAC3B,MAAM,WAAW,EAAE,WAAW,KAAK;EAEnC,OAAO;GAAE,MADI,WAAW,EAAE,MAAM,CAAC,IAAI;GACtB;EAAS;CAC1B,CAAC;AACH;AAgBA,SAAS,WAAW,QAAgC,KAAa,OAAmC,QAAoC;CACtI,MAAM,OAAO,OAAO,UAAU,WAAW,CAAC,KAAK,IAAI;CACnD,KAAK,MAAM,QAAQ,MACjB,IAAI,OAAO,SAAS,YAAY,QAAQ,SAAS,OAAO,EAAE,QAAQ,YAAY,CAAC,UAAU,OAAO,IAAI,IAClG,OAAO,QAAQ;AAGrB;;;;;;AAOA,SAAgB,sBACd,QACA,MACA,WACsB;CACtB,MAAM,QAAgC,CAAC;CACvC,MAAM,UAAkC,CAAC;CACzC,MAAM,YAAoC,CAAC;CAC3C,MAAM,iCAAiB,IAAI,IAAY;CAGvC,IAAI,MACF,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,IAAI,GAAG;EAC/C,IAAI,CAAC,OAAO;EAEZ,IAAI,MAAM,OACR,WAAW,OAAO,KAAK,MAAM,QAAQ,SAAS,KAAK,WAAW,CAAC;EAEjE,IAAI,MAAM,OACR,WAAW,SAAS,KAAK,MAAM,QAAQ,SAAS,KAAK,SAAS,CAAC;EAEjE,IAAI,MAAM,aAAa,KAAA,GAAW;GAChC,eAAe,IAAI,GAAG;GACtB,WAAW,WAAW,KAAK,MAAM,QAAQ;EAC3C;CACF;CAIF,IAAI;EACF,MAAM,aAAa,cAAc,MAAM;EACvC,IAAI,WAAW,SAAS,YAAY,WAAW,YAC7C,KAAK,MAAM,CAAC,cAAc,mBAAmB,OAAO,QAAQ,WAAW,UAAiC,GAAG;GACzG,IAAI,CAAC,gBAAgB;GAGrB,MAAM,YAAY,eAAe;GACjC,IAAI,WACF,WAAW,OAAO,cAAc,YAAY,SAAS,KAAK,WAAW,CAAC;GAIxE,MAAM,YAAY,eAAe;GACjC,IAAI,WAAW;IACb,MAAM,OAAO,OAAO,cAAc,WAAW,CAAC,SAAS,IAAI;IAC3D,IAAI,MAAM,QAAQ,IAAI,GACpB,WAAW,SAAS,cAAc,OAAO,SAAS,KAAK,SAAS,CAAC;GAErE;GAGA,MAAM,eAAe,eAAe;GACpC,IAAI,iBAAiB,KAAA,KAAa,CAAC,eAAe,IAAI,YAAY,GAAG;IACnE,eAAe,IAAI,YAAY;IAC/B,MAAM,OAAO,OAAO,iBAAiB,WAAW,CAAC,YAAY,IAAI;IACjE,IAAI,MAAM,QAAQ,IAAI,GACpB,WAAW,WAAW,cAAc,IAAI;GAE5C;GAGA,IAAI,cAAc,OAAO;IACvB,MAAM,QAAQ,aAAa,YAAY;IACvC,IAAI,SAAS,EAAE,SAAS,UACtB,QAAQ,SAAS;GAErB;EACF;CAEJ,QAAQ,CAER;CAEA,OAAO;EAAE;EAAO;EAAS;EAAW;CAAe;AACrD;AAEA,SAAS,mBAAmB,MAA+B,UAA2D;CACpH,MAAM,SAAS,EAAE,GAAG,KAAK;CAEzB,KAAK,MAAM,CAAC,WAAW,gBAAgB,OAAO,QAAQ,QAAQ,GAC5D,IAAI,aAAa,QAAQ,cAAc,aAAa;EAClD,MAAM,cAAc,KAAK;EAEzB,IAAI,EAAE,eAAe,SAAS,OAAO,eAAe;EACpD,OAAO,OAAO;CAChB;CAGF,OAAO;AACT;;;;;AAMA,SAAgB,YAAY,MAA+B,QAA0D;CACnH,MAAM,SAAS,EAAE,GAAG,KAAK;CAEzB,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,MAAM,GAAG;EACjD,IAAI,OAAO,UAAU,OAAO,SAAS,KAAA,GAAW;EAChD,IAAI,UAAU,KAAA,GACZ,OAAO,OAAO;CAElB;CAEA,OAAO;AACT;;AAGA,SAAgB,eACd,MACA,KACyB;CACzB,IAAI,SAAS,EAAE,GAAG,KAAK;CAEvB,IAAI,IAAI,SAAS,OAAO,KAAK,IAAI,KAAK,CAAC,CAAC,SAAS,GAC/C,SAAS,mBAAmB,QAAQ,IAAI,KAAK;CAE/C,IAAI,IAAI,WAAW,OAAO,KAAK,IAAI,OAAO,CAAC,CAAC,SAAS,GACnD,SAAS,mBAAmB,QAAQ,IAAI,OAAO;CAGjD,OAAO;AACT;;;;;;AAOA,SAAS,oBAAoB,MAAuC,OAAoB,WAA8B;CACpH,IAAI,CAAC,MAAM;CAEX,IAAI,KAAK,SAAS,KAAA,GAAW;EAC3B,MAAM,OAAO,MAAM,QAAQ,KAAK,IAAI,IAAI,KAAK,OAAO,CAAC,KAAK,IAAI;EAC9D,KAAK,MAAM,KAAK,MACd,IAAI,OAAO,MAAM,UAAU,MAAM,IAAI,CAAC;EAExC,IAAI,KAAK,SAAS,OAAO,KAAK,KAAK,OACjC,oBAAoB,KAAK,OAAO,2BAAW,IAAI,IAAI,CAAC;CAExD;CAEA,MAAM,WAAW,KAAK,SAAS,KAAK;CACpC,IAAI,MAAM,QAAQ,QAAQ,GACxB,KAAK,MAAM,WAAW,UAAU,oBAAoB,SAAS,OAAO,SAAS;AAEjF;;AAGA,SAAS,aAAa,OAAgB,cAAoC;CACxE,IAAI,OAAO,UAAU,UAAU,OAAO;CAEtC,IAAI,aAAa,IAAI,SAAS,GAAG;EAC/B,MAAM,QAAQ,MAAM,YAAY;EAChC,IAAI,UAAU,UAAU,UAAU,OAAO,UAAU,SAAS,UAAU,MAAM,OAAO;EACnF,IAAI,UAAU,WAAW,UAAU,OAAO,UAAU,QAAQ,UAAU,OAAO,OAAO;CACtF;CAEA,IAAI,aAAa,IAAI,QAAQ,KAAK,aAAa,IAAI,SAAS,GAAG;EAC7D,MAAM,UAAU,MAAM,KAAK;EAC3B,IAAI,YAAY,IAAI;GAClB,MAAM,MAAM,OAAO,OAAO;GAC1B,IAAI,CAAC,OAAO,MAAM,GAAG,GAAG,OAAO;EACjC;CACF;CAEA,OAAO;AACT;;;;;;;;;AAUA,SAAgB,WAAW,MAA+B,QAAuD;CAC/G,IAAI;CACJ,IAAI;EACF,MAAM,aAAa,cAAc,MAAM;EACvC,IAAI,WAAW,SAAS,YAAY,CAAC,WAAW,YAAY,OAAO;EACnE,aAAa,WAAW;CAC1B,QAAQ;EACN,OAAO;CACT;CAEA,MAAM,SAAS,EAAE,GAAG,KAAK;CAEzB,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,MAAM,GAAG;EACjD,MAAM,OAAO,WAAW;EACxB,IAAI,CAAC,MAAM;EAEX,MAAM,wBAAQ,IAAI,IAAY;EAC9B,MAAM,4BAAY,IAAI,IAAY;EAClC,oBAAoB,MAAM,OAAO,SAAS;EAE1C,MAAM,eAAe,MAAM,QAAQ,KAAK;EACxC,MAAM,cAAc,MAAM,IAAI,OAAO;EACrC,MAAM,eAAe,MAAM,IAAI,QAAQ,KAAK,MAAM,IAAI,SAAS,KAAK,MAAM,IAAI,QAAQ,KAAK,MAAM,IAAI,SAAS;EAE9G,IAAI,gBAAgB,aAClB,OAAO,OAAO,MAAM,KAAK,MAAM,aAAa,GAAG,SAAS,CAAC;OACpD,IAAI,CAAC,gBAAgB,eAAe,CAAC,cAE1C,OAAO,OAAO,CAAC,aAAa,OAAO,SAAS,CAAC;OACxC,IAAI,CAAC,cACV,OAAO,OAAO,aAAa,OAAO,KAAK;CAE3C;CAEA,OAAO;AACT;;;;;;AAOA,SAAgB,kBACd,MACA,QACA,OACA,SACA,WACmB;CACnB,IAAI;CACJ,IAAI,UAAU;CACd,IAAI;EACF,MAAM,aAAa,cAAc,MAAM;EACvC,IAAI,WAAW,SAAS,YAAY,CAAC,WAAW,YAAY,OAAO,CAAC;EACpE,aAAa,WAAW;EAExB,IAAI,WAAW,yBAAyB,KAAA,KAAa,WAAW,yBAAyB,OAAO,UAAU;CAC5G,QAAQ;EACN,OAAO,CAAC;CACV;CAEA,IAAI,SAAS,OAAO,CAAC;CAErB,MAAM,4BAAY,IAAI,IAAY;EAChC,GAAG,OAAO,KAAK,UAAU;EACzB,GAAG,OAAO,KAAK,KAAK;EACpB,GAAG,OAAO,OAAO,KAAK;EACtB,GAAG,OAAO,KAAK,OAAO;EACtB,GAAG,OAAO,OAAO,OAAO;EACxB,GAAI,YAAY,OAAO,KAAK,SAAS,IAAI,CAAC;EAC1C,GAAI,YAAY,OAAO,OAAO,SAAS,IAAI,CAAC;CAC9C,CAAC;CACD,MAAM,WAA8B,CAAC;CAErC,KAAK,MAAM,OAAO,OAAO,KAAK,IAAI,GAChC,IAAI,CAAC,UAAU,IAAI,GAAG,GACpB,SAAS,KAAK,EAAE,IAAI,CAAC;CAIzB,OAAO;AACT"}
@@ -0,0 +1,13 @@
1
+ import { AnyPadroneCommand } from "../types/command.mjs";
2
+ //#region src/core/commands.d.ts
3
+ /**
4
+ * Builds a completer function for the REPL from the command tree.
5
+ * Completes command names, subcommand names, option names (--foo), and aliases (-f).
6
+ * Also includes dot-prefixed built-in REPL commands (.exit, .clear, .scope, .help, .history).
7
+ */
8
+ declare function buildReplCompleter(rootCommand: AnyPadroneCommand, builtins: {
9
+ inScope?: boolean;
10
+ }): (line: string) => [string[], string];
11
+ //#endregion
12
+ export { buildReplCompleter };
13
+ //# sourceMappingURL=commands.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.d.mts","names":[],"sources":["../../src/core/commands.ts"],"mappings":";;;;;;;iBAmIgB,kBAAA,CACd,WAAA,EAAa,iBAAiB,EAC9B,QAAA;EACE,OAAA;AAAA,KAEA,IAAA"}
@@ -1,234 +1,6 @@
1
- import { a as getJsonSchema, i as extractSchemaMetadata } from "./args-WmyGc59s.mjs";
2
- import { a as readStreamAsText } from "./stream-DC4H8YTx.mjs";
3
- //#region \0rolldown/runtime.js
4
- var __defProp = Object.defineProperty;
5
- var __exportAll = (all, no_symbols) => {
6
- let target = {};
7
- for (var name in all) __defProp(target, name, {
8
- get: all[name],
9
- enumerable: true
10
- });
11
- if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
12
- return target;
13
- };
14
- //#endregion
15
- //#region src/core/runtime.ts
16
- /**
17
- * Sentinel value returned by the terminal REPL session when Ctrl+C is pressed.
18
- * Distinguished from empty string (user pressed enter) and null (EOF/Ctrl+D).
19
- */
20
- const REPL_SIGINT = Symbol("REPL_SIGINT");
21
- //#endregion
22
- //#region src/core/default-runtime.ts
23
- /**
24
- * Default terminal prompt implementation powered by Enquirer.
25
- * Lazily imported to avoid loading Enquirer when not needed.
26
- */
27
- async function defaultTerminalPrompt(config) {
28
- const Enquirer = (await import("enquirer")).default;
29
- const question = {
30
- type: config.type,
31
- name: config.name,
32
- message: config.message
33
- };
34
- if (config.default !== void 0) question.initial = config.default;
35
- if (config.choices) question.choices = config.choices.map((c) => ({
36
- name: String(c.value),
37
- message: c.label
38
- }));
39
- return (await Enquirer.prompt(question))[config.name];
40
- }
41
- function createTerminalReplSession(config) {
42
- let history = config.history ? [...config.history] : [];
43
- let currentCompleter = config.completer;
44
- return {
45
- set completer(fn) {
46
- currentCompleter = fn;
47
- },
48
- async question(prompt) {
49
- const { createInterface } = await import("node:readline");
50
- const opts = {
51
- input: process.stdin,
52
- output: process.stdout,
53
- terminal: true,
54
- history: [...history],
55
- historySize: Math.max(history.length, 1e3)
56
- };
57
- if (currentCompleter) opts.completer = currentCompleter;
58
- const rl = createInterface(opts);
59
- return new Promise((resolve) => {
60
- let resolved = false;
61
- const settle = (value) => {
62
- if (resolved) return;
63
- resolved = true;
64
- rl.close();
65
- resolve(value);
66
- };
67
- rl.question(prompt, (answer) => {
68
- if (Array.isArray(rl.history)) history = [...rl.history];
69
- settle(answer);
70
- });
71
- rl.once("SIGINT", () => {
72
- process.stdout.write("\n");
73
- settle(REPL_SIGINT);
74
- });
75
- rl.once("close", () => {
76
- process.stdout.write("\n");
77
- settle(null);
78
- });
79
- });
80
- },
81
- close() {}
82
- };
83
- }
84
- /**
85
- * Auto-detect interactive mode when not explicitly set.
86
- * Returns 'disabled' in CI environments or non-TTY contexts, 'supported' otherwise.
87
- */
88
- function detectInteractiveMode() {
89
- if (typeof process === "undefined") return "disabled";
90
- if (process.env.CI || process.env.CONTINUOUS_INTEGRATION) return "disabled";
91
- if (!process.stdout?.isTTY) return "disabled";
92
- return "supported";
93
- }
94
- /**
95
- * Creates a default stdin reader from `process.stdin`.
96
- * Only created when a command actually declares a `stdin` meta field.
97
- */
98
- function createDefaultStdin() {
99
- return {
100
- get isTTY() {
101
- if (typeof process === "undefined") return true;
102
- return process.stdin?.isTTY === true;
103
- },
104
- async text() {
105
- if (typeof process === "undefined") return "";
106
- return readStreamAsText(process.stdin);
107
- },
108
- async *lines() {
109
- if (typeof process === "undefined") return;
110
- const { createInterface } = await import("node:readline");
111
- const rl = createInterface({ input: process.stdin });
112
- try {
113
- for await (const line of rl) yield line;
114
- } finally {
115
- rl.close();
116
- }
117
- }
118
- };
119
- }
120
- /**
121
- * Default signal listener that wires to `process.on(signal)`.
122
- * Returns an unsubscribe function that removes all listeners.
123
- */
124
- function defaultOnSignal(callback) {
125
- if (typeof process === "undefined") return () => {};
126
- const signals = [
127
- "SIGINT",
128
- "SIGTERM",
129
- "SIGHUP"
130
- ];
131
- const handlers = /* @__PURE__ */ new Map();
132
- for (const sig of signals) {
133
- const handler = () => callback(sig);
134
- handlers.set(sig, handler);
135
- process.on(sig, handler);
136
- }
137
- return () => {
138
- for (const [sig, handler] of handlers) process.removeListener(sig, handler);
139
- };
140
- }
141
- /**
142
- * Creates the default Node.js/Bun runtime.
143
- */
144
- function defaultExit(code) {
145
- if (typeof process !== "undefined") process.exit(code);
146
- throw new Error(`Exit with code ${code}`);
147
- }
148
- function getTerminalInfo() {
149
- if (typeof process === "undefined") return void 0;
150
- return {
151
- get columns() {
152
- return process.stdout?.columns;
153
- },
154
- get isTTY() {
155
- return process.stdout?.isTTY === true;
156
- }
157
- };
158
- }
159
- function createDefaultRuntime() {
160
- return {
161
- output: (...args) => console.log(...args),
162
- error: (text) => console.error(text),
163
- argv: () => typeof process !== "undefined" ? process.argv.slice(2) : [],
164
- env: () => typeof process !== "undefined" ? process.env : {},
165
- format: "auto",
166
- prompt: defaultTerminalPrompt,
167
- interactive: detectInteractiveMode(),
168
- onSignal: defaultOnSignal,
169
- terminal: getTerminalInfo(),
170
- exit: defaultExit
171
- };
172
- }
173
- /**
174
- * Returns the stdin abstraction: custom runtime stdin > default process.stdin.
175
- * Returns `undefined` when no custom stdin is provided and process.stdin is not piped.
176
- */
177
- function resolveStdin(partial) {
178
- if (partial?.stdin) return partial.stdin;
179
- const defaultStdin = createDefaultStdin();
180
- if (defaultStdin.isTTY) return void 0;
181
- return defaultStdin;
182
- }
183
- /**
184
- * Like `resolveStdin`, but always returns a stdin source even when it's a TTY.
185
- * Used for async streams which support interactive (non-piped) input.
186
- */
187
- function resolveStdinAlways(partial) {
188
- if (partial?.stdin) return partial.stdin;
189
- return createDefaultStdin();
190
- }
191
- /**
192
- * Merges a partial runtime with the default runtime.
193
- */
194
- function resolveRuntime(partial) {
195
- const defaults = createDefaultRuntime();
196
- if (!partial) return defaults;
197
- return {
198
- output: partial.output ?? defaults.output,
199
- error: partial.error ?? defaults.error,
200
- argv: partial.argv ?? defaults.argv,
201
- env: partial.env ?? defaults.env,
202
- format: partial.format ?? defaults.format,
203
- interactive: partial.interactive ?? defaults.interactive,
204
- prompt: partial.prompt ?? defaults.prompt,
205
- readLine: partial.readLine ?? defaults.readLine,
206
- stdin: partial.stdin,
207
- theme: partial.theme,
208
- onSignal: partial.onSignal ?? defaults.onSignal,
209
- terminal: partial.terminal ?? defaults.terminal,
210
- exit: partial.exit ?? defaults.exit
211
- };
212
- }
213
- //#endregion
1
+ import { extractSchemaMetadata, getJsonSchema } from "./args.mjs";
2
+ import { resolveRuntime } from "./default-runtime.mjs";
214
3
  //#region src/core/commands.ts
215
- var commands_exports = /* @__PURE__ */ __exportAll({
216
- buildInputSchema: () => buildInputSchema,
217
- buildReplCompleter: () => buildReplCompleter,
218
- collectEndpoints: () => collectEndpoints,
219
- commandSymbol: () => commandSymbol,
220
- configKeys: () => configKeys,
221
- findCommandByName: () => findCommandByName,
222
- getCommand: () => getCommand,
223
- getCommandRuntime: () => getCommandRuntime,
224
- lazyResolver: () => lazyResolver,
225
- mergeCommands: () => mergeCommands,
226
- repathCommandTree: () => repathCommandTree,
227
- resolveAllCommands: () => resolveAllCommands,
228
- resolveCommand: () => resolveCommand,
229
- serializeArgsToFlags: () => serializeArgsToFlags,
230
- suggestSimilar: () => suggestSimilar
231
- });
232
4
  const lazyResolver = Symbol("lazyResolver");
233
5
  /** Resolves a lazy command in place by calling its stored resolver. No-op if already resolved. */
234
6
  function resolveCommand(cmd) {
@@ -509,6 +281,6 @@ function serializeArgsToFlags(args) {
509
281
  return parts;
510
282
  }
511
283
  //#endregion
512
- export { resolveStdin as _, commands_exports as a, getCommandRuntime as c, repathCommandTree as d, resolveAllCommands as f, createTerminalReplSession as g, suggestSimilar as h, commandSymbol as i, lazyResolver as l, serializeArgsToFlags as m, buildReplCompleter as n, findCommandByName as o, resolveCommand as p, collectEndpoints as r, getCommand as s, buildInputSchema as t, mergeCommands as u, resolveStdinAlways as v, REPL_SIGINT as y };
284
+ export { buildInputSchema, buildReplCompleter, collectEndpoints, commandSymbol, configKeys, findCommandByName, getCommand, getCommandRuntime, lazyResolver, mergeCommands, repathCommandTree, resolveAllCommands, resolveCommand, serializeArgsToFlags, suggestSimilar };
513
285
 
514
- //# sourceMappingURL=commands-ohEApqIw.mjs.map
286
+ //# sourceMappingURL=commands.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.mjs","names":[],"sources":["../../src/core/commands.ts"],"sourcesContent":["import type { AnyPadroneCommand } from '../types/index.ts';\nimport { extractSchemaMetadata, getJsonSchema } from './args.ts';\nimport { resolveRuntime } from './default-runtime.ts';\nimport type { ResolvedPadroneRuntime } from './runtime.ts';\n\n// ---------------------------------------------------------------------------\n// Lazy command resolution\n// ---------------------------------------------------------------------------\n\nexport const lazyResolver = Symbol('lazyResolver');\n\n/** Resolves a lazy command in place by calling its stored resolver. No-op if already resolved. */\nexport function resolveCommand(cmd: AnyPadroneCommand): AnyPadroneCommand {\n const resolver = (cmd as any)[lazyResolver];\n if (resolver) {\n delete (cmd as any)[lazyResolver];\n resolver(cmd);\n }\n return cmd;\n}\n\n/** Recursively resolves a command and all its descendants. */\nexport function resolveAllCommands(cmd: AnyPadroneCommand): void {\n resolveCommand(cmd);\n if (cmd.commands) {\n for (const sub of cmd.commands) resolveAllCommands(sub);\n }\n}\n\n/** Checks whether a value is a Padrone program/builder. */\nexport function isPadroneProgram(value: unknown): value is object {\n return !!value && typeof value === 'object' && commandSymbol in value;\n}\n\n/** Extracts the underlying command from a program/builder and resolves the full command tree. */\nexport function getCommand(program: object): AnyPadroneCommand {\n const cmd = commandSymbol in program ? ((program as any)[commandSymbol] as AnyPadroneCommand) : (program as AnyPadroneCommand);\n resolveAllCommands(cmd);\n return cmd;\n}\n\nexport const commandSymbol = Symbol('padrone_command');\n\n/** Config keys that are merged when overriding a command. */\nexport const configKeys = ['title', 'description', 'version', 'deprecated', 'hidden', 'mutation', 'needsApproval'] as const;\n\n/**\n * Merges an existing command with an override.\n * - Config fields are shallow-merged (new overrides old).\n * - Action, arguments, meta, config schema, env schema are taken from the override if set.\n * - Subcommands are recursively merged by name.\n */\nexport function mergeCommands(existing: AnyPadroneCommand, override: AnyPadroneCommand): AnyPadroneCommand {\n resolveCommand(existing);\n resolveCommand(override);\n const merged: AnyPadroneCommand = { ...existing };\n\n // Merge config fields\n for (const key of configKeys) {\n if (override[key] !== undefined) (merged as any)[key] = override[key];\n }\n\n // Override fields: take from override if explicitly set (not inherited from existing via spread)\n if (override.action !== existing.action) merged.action = override.action;\n if (override.argsSchema !== existing.argsSchema) merged.argsSchema = override.argsSchema;\n if (override.meta !== existing.meta) merged.meta = override.meta;\n if (override.isAsync !== existing.isAsync) merged.isAsync = override.isAsync || existing.isAsync;\n if (override.runtime !== existing.runtime) merged.runtime = override.runtime;\n if (override.interceptors !== existing.interceptors) merged.interceptors = override.interceptors;\n if (override.aliases !== existing.aliases) merged.aliases = override.aliases;\n // Recursively merge subcommands by name\n if (override.commands) {\n const baseCommands = [...(existing.commands || [])];\n for (const overrideChild of override.commands) {\n const existingIndex = baseCommands.findIndex((c) => c.name === overrideChild.name);\n if (existingIndex >= 0) {\n baseCommands[existingIndex] = mergeCommands(baseCommands[existingIndex]!, overrideChild);\n } else {\n baseCommands.push(overrideChild);\n }\n }\n merged.commands = baseCommands;\n }\n\n return merged;\n}\n\n/**\n * Resolves the runtime for a command by walking up the parent chain.\n * Returns a fully resolved runtime with all defaults filled in.\n */\nexport function getCommandRuntime(cmd: AnyPadroneCommand): ResolvedPadroneRuntime {\n let current: AnyPadroneCommand | undefined = cmd;\n while (current) {\n if (current.runtime) return resolveRuntime(current.runtime);\n current = current.parent;\n }\n return resolveRuntime();\n}\n\n/**\n * Recursively re-paths a command tree under a new parent path, updating parent references.\n */\nexport function repathCommandTree(\n cmd: AnyPadroneCommand,\n newName: string,\n parentPath: string,\n parent: AnyPadroneCommand,\n): AnyPadroneCommand {\n resolveCommand(cmd);\n const newPath = parentPath ? `${parentPath} ${newName}` : newName;\n const remounted: AnyPadroneCommand = {\n ...cmd,\n name: newName,\n path: newPath,\n parent,\n version: undefined,\n };\n\n if (cmd.commands?.length) {\n remounted.commands = cmd.commands.map((child) => repathCommandTree(child, child.name, newPath, remounted));\n }\n\n return remounted;\n}\n\n/**\n * Builds a completer function for the REPL from the command tree.\n * Completes command names, subcommand names, option names (--foo), and aliases (-f).\n * Also includes dot-prefixed built-in REPL commands (.exit, .clear, .scope, .help, .history).\n */\nexport function buildReplCompleter(\n rootCommand: AnyPadroneCommand,\n builtins: {\n inScope?: boolean;\n },\n): (line: string) => [string[], string] {\n resolveAllCommands(rootCommand);\n return (line: string): [string[], string] => {\n const trimmed = line.trimStart();\n const parts = trimmed.split(/\\s+/);\n const lastPart = parts[parts.length - 1] ?? '';\n\n // If we're completing a dot-command\n if (lastPart.startsWith('.')) {\n const dotCmds = ['.exit', '.clear', '.help', '.history'];\n if (rootCommand.commands?.some((c) => c.commands?.length) || builtins.inScope) dotCmds.push('.scope');\n const hits = dotCmds.filter((c) => c.startsWith(lastPart));\n return [hits.length ? hits : dotCmds, lastPart];\n }\n\n // If we're completing an option (starts with -)\n if (lastPart.startsWith('-')) {\n // Find which command we're in\n const commandParts = parts.slice(0, -1).filter((p) => !p.startsWith('-'));\n let targetCommand = rootCommand;\n for (const part of commandParts) {\n resolveCommand(targetCommand);\n const sub = targetCommand.commands?.find((c) => c.name === part || c.aliases?.includes(part));\n if (sub) {\n resolveCommand(sub);\n targetCommand = sub;\n } else break;\n }\n\n // Get options for this command\n const options: string[] = [];\n if (targetCommand.argsSchema) {\n try {\n const argsMeta = targetCommand.meta?.fields;\n const { flags, aliases } = extractSchemaMetadata(targetCommand.argsSchema, argsMeta, targetCommand.meta?.autoAlias);\n const jsonSchema = getJsonSchema(targetCommand.argsSchema) as Record<string, any>;\n if (jsonSchema.type === 'object' && jsonSchema.properties) {\n for (const key of Object.keys(jsonSchema.properties)) {\n options.push(`--${key}`);\n }\n for (const flag of Object.keys(flags)) {\n options.push(`-${flag}`);\n }\n for (const alias of Object.keys(aliases)) {\n options.push(`--${alias}`);\n }\n }\n } catch {\n // Ignore schema parsing errors\n }\n }\n // Add global flags\n options.push('--help', '-h');\n\n const hits = options.filter((o) => o.startsWith(lastPart));\n return [hits.length ? hits : options, lastPart];\n }\n\n // Completing command names\n const commandParts = parts.filter((p) => !p.startsWith('-'));\n // Walk into subcommands for all but the last token\n let targetCommand = rootCommand;\n for (let i = 0; i < commandParts.length - 1; i++) {\n resolveCommand(targetCommand);\n const sub = targetCommand.commands?.find((c) => c.name === commandParts[i] || c.aliases?.includes(commandParts[i]!));\n if (sub) {\n resolveCommand(sub);\n targetCommand = sub;\n } else break;\n }\n\n const candidates: string[] = [];\n\n // Add subcommand names and aliases\n if (targetCommand.commands) {\n for (const cmd of targetCommand.commands) {\n if (!cmd.hidden) {\n candidates.push(cmd.name);\n if (cmd.aliases) candidates.push(...cmd.aliases);\n }\n }\n }\n\n // Add dot-commands and `..` shorthand at the root level (relative to current scope)\n if (targetCommand === rootCommand) {\n candidates.push('.help', '.exit', '.clear', '.history');\n if (rootCommand.commands?.some((c) => c.commands?.length) || builtins.inScope) candidates.push('.scope');\n if (builtins.inScope) candidates.push('..');\n }\n\n const hits = candidates.filter((c) => c.startsWith(lastPart));\n return [hits.length ? hits : candidates, lastPart];\n };\n}\n\n/**\n * Computes the Levenshtein edit distance between two strings.\n */\nfunction levenshtein(a: string, b: string): number {\n const m = a.length;\n const n = b.length;\n const dp: number[] = Array.from({ length: n + 1 }, (_, i) => i);\n\n for (let i = 1; i <= m; i++) {\n let prev = dp[0]!;\n dp[0] = i;\n for (let j = 1; j <= n; j++) {\n const temp = dp[j]!;\n dp[j] = a[i - 1] === b[j - 1] ? prev : 1 + Math.min(prev, dp[j]!, dp[j - 1]!);\n prev = temp;\n }\n }\n\n return dp[n]!;\n}\n\n/**\n * Finds close matches from a list of candidates using Levenshtein distance\n * and prefix/substring matching (for inputs longer than 3 characters).\n * Returns up to 3 matching candidate names (raw, unformatted).\n */\nexport function suggestSimilar(input: string, candidates: string[]): string[] {\n if (candidates.length === 0) return [];\n\n const lower = input.toLowerCase();\n const matches: { candidate: string; score: number }[] = [];\n\n for (const candidate of candidates) {\n const candidateLower = candidate.toLowerCase();\n if (candidateLower === lower) continue;\n\n const dist = levenshtein(lower, candidateLower);\n const maxLen = Math.max(input.length, candidate.length);\n const threshold = Math.min(3, Math.max(1, Math.ceil(maxLen * 0.4)));\n\n if (dist > 0 && dist <= threshold) {\n matches.push({ candidate, score: dist });\n } else if (lower.length >= 3) {\n // Prefix or substring match for longer inputs\n if (candidateLower.startsWith(lower) || candidateLower.includes(lower)) {\n matches.push({ candidate, score: threshold + 1 });\n }\n }\n }\n\n matches.sort((a, b) => a.score - b.score);\n return matches.slice(0, 3).map((m) => m.candidate);\n}\n\nexport function findCommandByName(name: string, commands?: AnyPadroneCommand[]): AnyPadroneCommand | undefined {\n if (!commands) return undefined;\n\n const foundByName = commands.find((cmd) => cmd.name === name);\n if (foundByName) return resolveCommand(foundByName);\n\n // Check for aliases\n const foundByAlias = commands.find((cmd) => cmd.aliases?.includes(name));\n if (foundByAlias) return resolveCommand(foundByAlias);\n\n for (const cmd of commands) {\n if (name.startsWith(`${cmd.name} `)) {\n resolveCommand(cmd);\n if (cmd.commands) {\n const subCommandName = name.slice(cmd.name.length + 1);\n const subCommand = findCommandByName(subCommandName, cmd.commands);\n if (subCommand) return subCommand;\n }\n }\n // Check aliases for nested commands\n if (cmd.aliases) {\n for (const alias of cmd.aliases) {\n if (name.startsWith(`${alias} `)) {\n resolveCommand(cmd);\n if (cmd.commands) {\n const subCommandName = name.slice(alias.length + 1);\n const subCommand = findCommandByName(subCommandName, cmd.commands);\n if (subCommand) return subCommand;\n }\n }\n }\n }\n }\n return undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Shared utilities for MCP and serve\n// ---------------------------------------------------------------------------\n\nexport type CollectedEndpoint = { name: string; command: AnyPadroneCommand };\n\n/** Collect all actionable commands recursively. Hidden commands are excluded. */\nexport function collectEndpoints(commands: AnyPadroneCommand[] | undefined, prefix: string): CollectedEndpoint[] {\n if (!commands) return [];\n const endpoints: CollectedEndpoint[] = [];\n for (const cmd of commands) {\n resolveCommand(cmd);\n if (cmd.hidden) continue;\n const path = cmd.name ? (prefix ? `${prefix}.${cmd.name}` : cmd.name) : prefix;\n if (cmd.action || cmd.argsSchema) {\n endpoints.push({ name: path, command: cmd });\n }\n if (cmd.commands?.length) {\n endpoints.push(...collectEndpoints(cmd.commands, path));\n }\n }\n return endpoints;\n}\n\n/** Build the JSON Schema for a command's arguments. */\nexport function buildInputSchema(cmd: AnyPadroneCommand): Record<string, unknown> {\n if (!cmd.argsSchema) {\n return { type: 'object', additionalProperties: false };\n }\n try {\n return getJsonSchema(cmd.argsSchema) as Record<string, unknown>;\n } catch {\n return { type: 'object', additionalProperties: false };\n }\n}\n\n/** Serialize a record of args into CLI flag strings. */\nexport function serializeArgsToFlags(args: Record<string, unknown>): string[] {\n const parts: string[] = [];\n for (const [key, value] of Object.entries(args)) {\n if (value === undefined) continue;\n if (typeof value === 'boolean') {\n parts.push(value ? `--${key}` : `--no-${key}`);\n } else if (Array.isArray(value)) {\n for (const v of value) parts.push(`--${key}=${String(v)}`);\n } else {\n const strVal = String(value);\n parts.push(strVal.includes(' ') ? `--${key}=\"${strVal}\"` : `--${key}=${strVal}`);\n }\n }\n return parts;\n}\n"],"mappings":"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"}