padrone 1.0.0-beta.2

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.
package/index.mjs ADDED
@@ -0,0 +1,1246 @@
1
+ import { createRequire } from "node:module";
2
+
3
+ //#region rolldown:runtime
4
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
5
+
6
+ //#endregion
7
+ //#region src/colorizer.ts
8
+ const colors = {
9
+ reset: "\x1B[0m",
10
+ bold: "\x1B[1m",
11
+ dim: "\x1B[2m",
12
+ italic: "\x1B[3m",
13
+ underline: "\x1B[4m",
14
+ strikethrough: "\x1B[9m",
15
+ cyan: "\x1B[36m",
16
+ green: "\x1B[32m",
17
+ yellow: "\x1B[33m",
18
+ blue: "\x1B[34m",
19
+ magenta: "\x1B[35m",
20
+ gray: "\x1B[90m"
21
+ };
22
+ function createColorizer() {
23
+ return {
24
+ command: (text) => `${colors.cyan}${colors.bold}${text}${colors.reset}`,
25
+ option: (text) => `${colors.green}${text}${colors.reset}`,
26
+ type: (text) => `${colors.yellow}${text}${colors.reset}`,
27
+ description: (text) => `${colors.dim}${text}${colors.reset}`,
28
+ label: (text) => `${colors.bold}${text}${colors.reset}`,
29
+ meta: (text) => `${colors.gray}${text}${colors.reset}`,
30
+ example: (text) => `${colors.underline}${text}${colors.reset}`,
31
+ exampleValue: (text) => `${colors.italic}${text}${colors.reset}`,
32
+ deprecated: (text) => `${colors.strikethrough}${colors.gray}${text}${colors.reset}`
33
+ };
34
+ }
35
+
36
+ //#endregion
37
+ //#region src/formatter.ts
38
+ function createTextStyler() {
39
+ return {
40
+ command: (text) => text,
41
+ option: (text) => text,
42
+ type: (text) => text,
43
+ description: (text) => text,
44
+ label: (text) => text,
45
+ meta: (text) => text,
46
+ example: (text) => text,
47
+ exampleValue: (text) => text,
48
+ deprecated: (text) => text
49
+ };
50
+ }
51
+ function createAnsiStyler() {
52
+ const colorizer = createColorizer();
53
+ return {
54
+ command: colorizer.command,
55
+ option: colorizer.option,
56
+ type: colorizer.type,
57
+ description: colorizer.description,
58
+ label: colorizer.label,
59
+ meta: colorizer.meta,
60
+ example: colorizer.example,
61
+ exampleValue: colorizer.exampleValue,
62
+ deprecated: colorizer.deprecated
63
+ };
64
+ }
65
+ function createConsoleStyler() {
66
+ const colors$1 = {
67
+ reset: "\x1B[0m",
68
+ bold: "\x1B[1m",
69
+ dim: "\x1B[2m",
70
+ italic: "\x1B[3m",
71
+ underline: "\x1B[4m",
72
+ strikethrough: "\x1B[9m",
73
+ cyan: "\x1B[36m",
74
+ green: "\x1B[32m",
75
+ yellow: "\x1B[33m",
76
+ gray: "\x1B[90m"
77
+ };
78
+ return {
79
+ command: (text) => `${colors$1.cyan}${colors$1.bold}${text}${colors$1.reset}`,
80
+ option: (text) => `${colors$1.green}${text}${colors$1.reset}`,
81
+ type: (text) => `${colors$1.yellow}${text}${colors$1.reset}`,
82
+ description: (text) => `${colors$1.dim}${text}${colors$1.reset}`,
83
+ label: (text) => `${colors$1.bold}${text}${colors$1.reset}`,
84
+ meta: (text) => `${colors$1.gray}${text}${colors$1.reset}`,
85
+ example: (text) => `${colors$1.underline}${text}${colors$1.reset}`,
86
+ exampleValue: (text) => `${colors$1.italic}${text}${colors$1.reset}`,
87
+ deprecated: (text) => `${colors$1.strikethrough}${colors$1.gray}${text}${colors$1.reset}`
88
+ };
89
+ }
90
+ function createMarkdownStyler() {
91
+ return {
92
+ command: (text) => `**${text}**`,
93
+ option: (text) => `\`${text}\``,
94
+ type: (text) => `\`${text}\``,
95
+ description: (text) => text,
96
+ label: (text) => `### ${text}`,
97
+ meta: (text) => `*${text}*`,
98
+ example: (text) => `**${text}**`,
99
+ exampleValue: (text) => `\`${text}\``,
100
+ deprecated: (text) => `~~${text}~~`
101
+ };
102
+ }
103
+ function escapeHtml(text) {
104
+ return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
105
+ }
106
+ function createHtmlStyler() {
107
+ return {
108
+ command: (text) => `<strong style="color: #00bcd4;">${escapeHtml(text)}</strong>`,
109
+ option: (text) => `<code style="color: #4caf50;">${escapeHtml(text)}</code>`,
110
+ type: (text) => `<code style="color: #ff9800;">${escapeHtml(text)}</code>`,
111
+ description: (text) => `<span style="color: #666;">${escapeHtml(text)}</span>`,
112
+ label: (text) => `<h3>${escapeHtml(text)}</h3>`,
113
+ meta: (text) => `<span style="color: #999;">${escapeHtml(text)}</span>`,
114
+ example: (text) => `<strong style="text-decoration: underline;">${escapeHtml(text)}</strong>`,
115
+ exampleValue: (text) => `<em>${escapeHtml(text)}</em>`,
116
+ deprecated: (text) => `<del style="color: #999;">${escapeHtml(text)}</del>`
117
+ };
118
+ }
119
+ function createTextLayout() {
120
+ return {
121
+ newline: "\n",
122
+ indent: (level) => " ".repeat(level),
123
+ join: (parts) => parts.filter(Boolean).join(" "),
124
+ usageLabel: "Usage:"
125
+ };
126
+ }
127
+ function createMarkdownLayout() {
128
+ return {
129
+ newline: "\n\n",
130
+ indent: (level) => {
131
+ if (level === 0) return "";
132
+ if (level === 1) return " ";
133
+ return " ";
134
+ },
135
+ join: (parts) => parts.filter(Boolean).join(" "),
136
+ usageLabel: "Usage:"
137
+ };
138
+ }
139
+ function createHtmlLayout() {
140
+ return {
141
+ newline: "<br>",
142
+ indent: (level) => "&nbsp;&nbsp;".repeat(level),
143
+ join: (parts) => parts.filter(Boolean).join(" "),
144
+ wrapDocument: (content) => `<div style="font-family: monospace; line-height: 1.6;">${content}</div>`,
145
+ usageLabel: "<strong>Usage:</strong>"
146
+ };
147
+ }
148
+ /**
149
+ * Creates a formatter that uses the given styler and layout configuration.
150
+ */
151
+ function createGenericFormatter(styler, layout) {
152
+ const { newline, indent, join, wrapDocument, usageLabel } = layout;
153
+ function formatUsageSection(info) {
154
+ return [`${usageLabel} ${join([
155
+ styler.command(info.usage.command),
156
+ info.usage.hasSubcommands ? styler.meta("[command]") : "",
157
+ info.usage.hasArguments ? styler.meta("[args...]") : "",
158
+ info.usage.hasOptions ? styler.meta("[options]") : ""
159
+ ])}`];
160
+ }
161
+ function formatSubcommandsSection(info) {
162
+ const lines = [];
163
+ const subcommands = info.subcommands;
164
+ lines.push(styler.label("Commands:"));
165
+ const maxNameLength = Math.max(...subcommands.map((c) => c.name.length));
166
+ for (const subCmd of subcommands) {
167
+ const padding = " ".repeat(Math.max(0, maxNameLength - subCmd.name.length + 2));
168
+ const isDeprecated = !!subCmd.deprecated;
169
+ const lineParts = [isDeprecated ? styler.deprecated(subCmd.name) : styler.command(subCmd.name), padding];
170
+ const displayText = subCmd.title ?? subCmd.description;
171
+ if (displayText) lineParts.push(isDeprecated ? styler.deprecated(displayText) : styler.description(displayText));
172
+ if (isDeprecated) {
173
+ const deprecatedMeta = typeof subCmd.deprecated === "string" ? styler.meta(` (deprecated: ${subCmd.deprecated})`) : styler.meta(" (deprecated)");
174
+ lineParts.push(deprecatedMeta);
175
+ }
176
+ lines.push(indent(1) + lineParts.join(""));
177
+ }
178
+ lines.push("");
179
+ lines.push(styler.meta(`Run "${info.name} [command] --help" for more information on a command.`));
180
+ return lines;
181
+ }
182
+ function formatArgumentsSection(info) {
183
+ const lines = [];
184
+ const args = info.arguments;
185
+ lines.push(styler.label("Arguments:"));
186
+ for (const arg of args) {
187
+ const parts = [styler.option(arg.name)];
188
+ if (arg.optional) parts.push(styler.meta("(optional)"));
189
+ if (arg.default !== void 0) parts.push(styler.meta(`(default: ${String(arg.default)})`));
190
+ lines.push(indent(1) + join(parts));
191
+ if (arg.description) lines.push(indent(2) + styler.description(arg.description));
192
+ }
193
+ return lines;
194
+ }
195
+ function formatOptionsSection(info) {
196
+ const lines = [];
197
+ const options = info.options;
198
+ lines.push(styler.label("Options:"));
199
+ const maxNameLength = Math.max(...options.map((opt) => opt.name.length));
200
+ for (const opt of options) {
201
+ const optionName = opt.negatable ? `--[no-]${opt.name}` : `--${opt.name}`;
202
+ const aliasNames = opt.aliases && opt.aliases.length > 0 ? opt.aliases.map((a) => `-${a}`).join(", ") : "";
203
+ const fullOptionName = aliasNames ? `${optionName}, ${aliasNames}` : optionName;
204
+ const padding = " ".repeat(Math.max(0, maxNameLength - opt.name.length + 2));
205
+ const isDeprecated = !!opt.deprecated;
206
+ const parts = [isDeprecated ? styler.deprecated(fullOptionName) : styler.option(fullOptionName)];
207
+ if (opt.type) parts.push(styler.type(`<${opt.type}>`));
208
+ if (opt.optional && !opt.deprecated) parts.push(styler.meta("(optional)"));
209
+ if (opt.default !== void 0) parts.push(styler.meta(`(default: ${String(opt.default)})`));
210
+ if (opt.enum) parts.push(styler.meta(`(choices: ${opt.enum.join(", ")})`));
211
+ if (opt.variadic) parts.push(styler.meta("(repeatable)"));
212
+ if (isDeprecated) {
213
+ const deprecatedMeta = typeof opt.deprecated === "string" ? styler.meta(`(deprecated: ${opt.deprecated})`) : styler.meta("(deprecated)");
214
+ parts.push(deprecatedMeta);
215
+ }
216
+ const description = opt.description ? styler.description(opt.description) : "";
217
+ lines.push(indent(1) + join(parts) + padding + description);
218
+ if (opt.env) {
219
+ const envVars = typeof opt.env === "string" ? [opt.env] : opt.env;
220
+ const envParts = [styler.example("Env:"), styler.exampleValue(envVars.join(", "))];
221
+ lines.push(indent(3) + join(envParts));
222
+ }
223
+ if (opt.configKey) {
224
+ const configParts = [styler.example("Config:"), styler.exampleValue(opt.configKey)];
225
+ lines.push(indent(3) + join(configParts));
226
+ }
227
+ if (opt.examples && opt.examples.length > 0) {
228
+ const exampleValues = opt.examples.map((example) => typeof example === "string" ? example : JSON.stringify(example)).join(", ");
229
+ const exampleParts = [styler.example("Example:"), styler.exampleValue(exampleValues)];
230
+ lines.push(indent(3) + join(exampleParts));
231
+ }
232
+ }
233
+ return lines;
234
+ }
235
+ return { format(info) {
236
+ const lines = [];
237
+ if (info.deprecated) {
238
+ const deprecationMessage = typeof info.deprecated === "string" ? `⚠️ This command is deprecated: ${info.deprecated}` : "⚠️ This command is deprecated";
239
+ lines.push(styler.deprecated(deprecationMessage));
240
+ lines.push("");
241
+ }
242
+ lines.push(...formatUsageSection(info));
243
+ lines.push("");
244
+ if (info.title) {
245
+ lines.push(styler.label(info.title));
246
+ lines.push("");
247
+ }
248
+ if (info.description) {
249
+ lines.push(styler.description(info.description));
250
+ lines.push("");
251
+ }
252
+ if (info.subcommands && info.subcommands.length > 0) {
253
+ lines.push(...formatSubcommandsSection(info));
254
+ lines.push("");
255
+ }
256
+ if (info.arguments && info.arguments.length > 0) {
257
+ lines.push(...formatArgumentsSection(info));
258
+ lines.push("");
259
+ }
260
+ if (info.options && info.options.length > 0) {
261
+ lines.push(...formatOptionsSection(info));
262
+ lines.push("");
263
+ }
264
+ if (info.nestedCommands?.length) {
265
+ lines.push(styler.label("Subcommand Details:"));
266
+ lines.push("");
267
+ for (const nestedCmd of info.nestedCommands) {
268
+ lines.push(styler.meta("─".repeat(60)));
269
+ lines.push(this.format(nestedCmd));
270
+ }
271
+ }
272
+ const result = lines.join(newline);
273
+ return wrapDocument ? wrapDocument(result) : result;
274
+ } };
275
+ }
276
+ function createJsonFormatter() {
277
+ return { format(info) {
278
+ return JSON.stringify(info, null, 2);
279
+ } };
280
+ }
281
+ function shouldUseAnsi() {
282
+ if (typeof process === "undefined") return false;
283
+ if (process.env.NO_COLOR) return false;
284
+ if (process.env.CI) return false;
285
+ if (process.stdout && typeof process.stdout.isTTY === "boolean") return process.stdout.isTTY;
286
+ return false;
287
+ }
288
+ /**
289
+ * Creates a minimal formatter that outputs just a single-line usage string.
290
+ */
291
+ function createMinimalFormatter() {
292
+ return { format(info) {
293
+ const parts = [info.usage.command];
294
+ if (info.usage.hasSubcommands) parts.push("[command]");
295
+ if (info.usage.hasArguments) parts.push("[args...]");
296
+ if (info.usage.hasOptions) parts.push("[options]");
297
+ return parts.join(" ");
298
+ } };
299
+ }
300
+ function createFormatter(format, detail = "standard") {
301
+ if (detail === "minimal") return createMinimalFormatter();
302
+ if (format === "json") return createJsonFormatter();
303
+ if (format === "ansi" || format === "auto" && shouldUseAnsi()) return createGenericFormatter(createAnsiStyler(), createTextLayout());
304
+ if (format === "console") return createGenericFormatter(createConsoleStyler(), createTextLayout());
305
+ if (format === "markdown") return createGenericFormatter(createMarkdownStyler(), createMarkdownLayout());
306
+ if (format === "html") return createGenericFormatter(createHtmlStyler(), createHtmlLayout());
307
+ return createGenericFormatter(createTextStyler(), createTextLayout());
308
+ }
309
+
310
+ //#endregion
311
+ //#region src/options.ts
312
+ /**
313
+ * Parse positional configuration to extract names and variadic info.
314
+ */
315
+ function parsePositionalConfig(positional) {
316
+ return positional.map((p) => {
317
+ const isVariadic = p.startsWith("...");
318
+ return {
319
+ name: isVariadic ? p.slice(3) : p,
320
+ variadic: isVariadic
321
+ };
322
+ });
323
+ }
324
+ /**
325
+ * Extract all option metadata from schema and meta in a single pass.
326
+ * This consolidates aliases, env bindings, and config keys extraction.
327
+ */
328
+ function extractSchemaMetadata(schema, meta) {
329
+ const aliases = {};
330
+ const envBindings = {};
331
+ const configKeys = {};
332
+ if (meta) for (const [key, value] of Object.entries(meta)) {
333
+ if (!value) continue;
334
+ if (value.alias) {
335
+ const list = typeof value.alias === "string" ? [value.alias] : value.alias;
336
+ for (const aliasKey of list) if (typeof aliasKey === "string" && aliasKey && aliasKey !== key) aliases[aliasKey] = key;
337
+ }
338
+ if (value.env) envBindings[key] = typeof value.env === "string" ? [value.env] : value.env;
339
+ if (value.configKey) configKeys[key] = value.configKey;
340
+ }
341
+ try {
342
+ const jsonSchema = schema["~standard"].jsonSchema.input({ target: "draft-2020-12" });
343
+ if (jsonSchema.type === "object" && jsonSchema.properties) for (const [propertyName, propertySchema] of Object.entries(jsonSchema.properties)) {
344
+ if (!propertySchema) continue;
345
+ const propAlias = propertySchema.alias;
346
+ if (propAlias) {
347
+ const list = typeof propAlias === "string" ? [propAlias] : propAlias;
348
+ if (Array.isArray(list)) {
349
+ for (const aliasKey of list) if (typeof aliasKey === "string" && aliasKey && aliasKey !== propertyName && !(aliasKey in aliases)) aliases[aliasKey] = propertyName;
350
+ }
351
+ }
352
+ if (propertySchema.env && !(propertyName in envBindings)) {
353
+ const envVars = typeof propertySchema.env === "string" ? [propertySchema.env] : propertySchema.env;
354
+ if (Array.isArray(envVars)) envBindings[propertyName] = envVars;
355
+ }
356
+ if (propertySchema.configKey && !(propertyName in configKeys)) configKeys[propertyName] = propertySchema.configKey;
357
+ }
358
+ } catch {}
359
+ return {
360
+ aliases,
361
+ envBindings,
362
+ configKeys
363
+ };
364
+ }
365
+ function preprocessAliases(data, aliases) {
366
+ const result = { ...data };
367
+ for (const [aliasKey, fullOptionName] of Object.entries(aliases)) if (aliasKey in data && aliasKey !== fullOptionName) {
368
+ const aliasValue = data[aliasKey];
369
+ if (!(fullOptionName in result)) result[fullOptionName] = aliasValue;
370
+ delete result[aliasKey];
371
+ }
372
+ return result;
373
+ }
374
+ /**
375
+ * Apply environment variable values to options.
376
+ * CLI values take precedence over environment variables.
377
+ */
378
+ function applyEnvBindings(data, envBindings, env = typeof process !== "undefined" ? process.env : {}) {
379
+ const result = { ...data };
380
+ for (const [optionName, envVars] of Object.entries(envBindings)) {
381
+ if (optionName in result && result[optionName] !== void 0) continue;
382
+ for (const envVar of envVars) {
383
+ const envValue = env[envVar];
384
+ if (envValue !== void 0) {
385
+ result[optionName] = parseEnvValue(envValue);
386
+ break;
387
+ }
388
+ }
389
+ }
390
+ return result;
391
+ }
392
+ /**
393
+ * Parse an environment variable value, attempting to convert to appropriate types.
394
+ */
395
+ function parseEnvValue(value) {
396
+ const lowerValue = value.toLowerCase();
397
+ if (lowerValue === "true" || lowerValue === "1" || lowerValue === "yes") return true;
398
+ if (lowerValue === "false" || lowerValue === "0" || lowerValue === "no") return false;
399
+ if (/^-?\d+$/.test(value)) return Number.parseInt(value, 10);
400
+ if (/^-?\d+\.\d+$/.test(value)) return Number.parseFloat(value);
401
+ if (value.includes(",")) return value.split(",").map((v) => parseEnvValue(v.trim()));
402
+ return value;
403
+ }
404
+ /**
405
+ * Get a nested value from an object using dot notation.
406
+ */
407
+ function getNestedValue(obj, path) {
408
+ const parts = path.split(".");
409
+ let current = obj;
410
+ for (const part of parts) {
411
+ if (current === null || current === void 0) return void 0;
412
+ if (typeof current !== "object") return void 0;
413
+ current = current[part];
414
+ }
415
+ return current;
416
+ }
417
+ /**
418
+ * Apply config file values to options.
419
+ * CLI values and env values take precedence over config file values.
420
+ */
421
+ function applyConfigValues(data, configKeys, configData) {
422
+ const result = { ...data };
423
+ for (const [optionName, configKey] of Object.entries(configKeys)) {
424
+ if (optionName in result && result[optionName] !== void 0) continue;
425
+ const configValue = getNestedValue(configData, configKey);
426
+ if (configValue !== void 0) result[optionName] = configValue;
427
+ }
428
+ return result;
429
+ }
430
+ /**
431
+ * Combined preprocessing of options with all features.
432
+ * Precedence order (highest to lowest): CLI args > env vars > config file
433
+ */
434
+ function preprocessOptions(data, ctx) {
435
+ let result = { ...data };
436
+ if (ctx.aliases && Object.keys(ctx.aliases).length > 0) result = preprocessAliases(result, ctx.aliases);
437
+ if (ctx.envBindings && Object.keys(ctx.envBindings).length > 0) result = applyEnvBindings(result, ctx.envBindings, ctx.env);
438
+ if (ctx.configKeys && ctx.configData) result = applyConfigValues(result, ctx.configKeys, ctx.configData);
439
+ return result;
440
+ }
441
+
442
+ //#endregion
443
+ //#region src/utils.ts
444
+ function getRootCommand(cmd) {
445
+ let current = cmd;
446
+ while (current.parent) current = current.parent;
447
+ return current;
448
+ }
449
+ /**
450
+ * Attempts to get the version from various sources:
451
+ * 1. Explicit version set on the command
452
+ * 2. npm_package_version environment variable (set by npm/yarn/pnpm when running scripts)
453
+ * 3. package.json in current or parent directories
454
+ * @param explicitVersion - Version explicitly set via .version()
455
+ * @returns The version string or '0.0.0' if not found
456
+ */
457
+ function getVersion(explicitVersion) {
458
+ if (explicitVersion) return explicitVersion;
459
+ if (typeof process !== "undefined" && process.env?.npm_package_version) return process.env.npm_package_version;
460
+ if (typeof process !== "undefined") try {
461
+ const fs = __require("node:fs");
462
+ const path = __require("node:path");
463
+ let dir = process.cwd();
464
+ for (let i = 0; i < 10; i++) {
465
+ const pkgPath = path.join(dir, "package.json");
466
+ if (fs.existsSync(pkgPath)) {
467
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
468
+ if (pkg.version) return pkg.version;
469
+ }
470
+ const parentDir = path.dirname(dir);
471
+ if (parentDir === dir) break;
472
+ dir = parentDir;
473
+ }
474
+ } catch {}
475
+ return "0.0.0";
476
+ }
477
+ /**
478
+ * Loads and parses a config file from the given path.
479
+ * Supports JSON, JSONC (JSON with comments), and attempts to parse other formats.
480
+ * @param configPath - Path to the config file
481
+ * @returns Parsed config data or undefined if loading fails
482
+ */
483
+ function loadConfigFile(configPath) {
484
+ if (typeof process === "undefined") return void 0;
485
+ try {
486
+ const fs = __require("node:fs");
487
+ const path = __require("node:path");
488
+ const absolutePath = path.isAbsolute(configPath) ? configPath : path.resolve(process.cwd(), configPath);
489
+ if (!fs.existsSync(absolutePath)) {
490
+ console.error(`Config file not found: ${absolutePath}`);
491
+ return;
492
+ }
493
+ const getContent = () => fs.readFileSync(absolutePath, "utf-8");
494
+ const ext = path.extname(absolutePath).toLowerCase();
495
+ if (ext === ".yaml" || ext === ".yml") return Bun.YAML.parse(getContent());
496
+ if (ext === ".toml") return Bun.TOML.parse(getContent());
497
+ if (ext === ".json") return JSON.parse(getContent());
498
+ if (ext === ".js" || ext === ".cjs" || ext === ".mjs" || ext === ".ts" || ext === ".cts" || ext === ".mts") return __require(absolutePath);
499
+ try {
500
+ return JSON.parse(getContent());
501
+ } catch {
502
+ console.error(`Unable to parse config file: ${absolutePath}`);
503
+ return;
504
+ }
505
+ } catch (error) {
506
+ console.error(`Error loading config file: ${error}`);
507
+ return;
508
+ }
509
+ }
510
+ /**
511
+ * Searches for a config file from a list of possible file names.
512
+ * Searches in the current working directory.
513
+ * @param configFiles - Array of possible config file names to search for
514
+ * @returns The path to the first found config file, or undefined if none found
515
+ */
516
+ function findConfigFile(configFiles) {
517
+ if (typeof process === "undefined" || !configFiles?.length) return void 0;
518
+ try {
519
+ const fs = __require("node:fs");
520
+ const path = __require("node:path");
521
+ const cwd = process.cwd();
522
+ for (const configFile of configFiles) {
523
+ const configPath = path.isAbsolute(configFile) ? configFile : path.resolve(cwd, configFile);
524
+ if (fs.existsSync(configPath)) return configPath;
525
+ }
526
+ } catch {}
527
+ }
528
+
529
+ //#endregion
530
+ //#region src/help.ts
531
+ /**
532
+ * Extract positional arguments info from schema based on meta.positional config.
533
+ */
534
+ function extractPositionalArgsInfo(schema, meta) {
535
+ const args = [];
536
+ const positionalNames = /* @__PURE__ */ new Set();
537
+ if (!schema || !meta?.positional || meta.positional.length === 0) return {
538
+ args,
539
+ positionalNames
540
+ };
541
+ const positionalConfig = parsePositionalConfig(meta.positional);
542
+ try {
543
+ const jsonSchema = schema["~standard"].jsonSchema.input({ target: "draft-2020-12" });
544
+ if (jsonSchema.type === "object" && jsonSchema.properties) {
545
+ const properties = jsonSchema.properties;
546
+ const required = jsonSchema.required || [];
547
+ for (const { name, variadic } of positionalConfig) {
548
+ const prop = properties[name];
549
+ if (!prop) continue;
550
+ positionalNames.add(name);
551
+ const optMeta = meta.options?.[name];
552
+ args.push({
553
+ name: variadic ? `...${name}` : name,
554
+ description: optMeta?.description ?? prop.description,
555
+ optional: !required.includes(name),
556
+ default: prop.default,
557
+ type: variadic ? `array<${prop.items?.type || "string"}>` : prop.type
558
+ });
559
+ }
560
+ }
561
+ } catch {}
562
+ return {
563
+ args,
564
+ positionalNames
565
+ };
566
+ }
567
+ function extractOptionsInfo(schema, meta, positionalNames) {
568
+ const result = [];
569
+ if (!schema) return result;
570
+ if (!schema["~standard"].vendor.includes("zod")) return result;
571
+ const optionsMeta = meta?.options;
572
+ try {
573
+ const jsonSchema = schema["~standard"].jsonSchema.input({ target: "draft-2020-12" });
574
+ if (jsonSchema.type === "object" && jsonSchema.properties) {
575
+ const properties = jsonSchema.properties;
576
+ const required = jsonSchema.required || [];
577
+ const propertyNames = new Set(Object.keys(properties));
578
+ const hasExplicitNegation = (key) => {
579
+ const camelNegated = `no${key.charAt(0).toUpperCase()}${key.slice(1)}`;
580
+ if (propertyNames.has(camelNegated)) return true;
581
+ const kebabNegated = `no-${key}`;
582
+ if (propertyNames.has(kebabNegated)) return true;
583
+ return false;
584
+ };
585
+ const isNegationOf = (key) => {
586
+ if (key.startsWith("no") && key.length > 2 && key[2] === key[2]?.toUpperCase()) {
587
+ const positiveKey = key.charAt(2).toLowerCase() + key.slice(3);
588
+ if (propertyNames.has(positiveKey)) return true;
589
+ }
590
+ if (key.startsWith("no-")) {
591
+ const positiveKey = key.slice(3);
592
+ if (propertyNames.has(positiveKey)) return true;
593
+ }
594
+ return false;
595
+ };
596
+ for (const [key, prop] of Object.entries(properties)) {
597
+ if (positionalNames?.has(key)) continue;
598
+ const isOptional = !required.includes(key);
599
+ const enumValues = prop.enum;
600
+ const optMeta = optionsMeta?.[key];
601
+ const propType = prop.type;
602
+ const isNegatable = propType === "boolean" && !hasExplicitNegation(key) && !isNegationOf(key);
603
+ result.push({
604
+ name: key,
605
+ description: optMeta?.description ?? prop.description,
606
+ optional: isOptional,
607
+ default: prop.default,
608
+ type: propType,
609
+ enum: enumValues,
610
+ deprecated: optMeta?.deprecated ?? prop?.deprecated,
611
+ hidden: optMeta?.hidden ?? prop?.hidden,
612
+ examples: optMeta?.examples ?? prop?.examples,
613
+ env: optMeta?.env ?? prop?.env,
614
+ variadic: propType === "array",
615
+ negatable: isNegatable,
616
+ configKey: optMeta?.configKey ?? prop?.configKey
617
+ });
618
+ }
619
+ }
620
+ } catch {}
621
+ return result;
622
+ }
623
+ /**
624
+ * Builds a comprehensive HelpInfo structure from a command.
625
+ * This is the single source of truth that all formatters use.
626
+ * @param cmd - The command to build help info for
627
+ * @param detail - The level of detail ('minimal', 'standard', or 'full')
628
+ */
629
+ function getHelpInfo(cmd, detail = "standard") {
630
+ const rootCmd = getRootCommand(cmd);
631
+ const commandName = cmd.path || cmd.name || "program";
632
+ const { args: positionalArgs, positionalNames } = cmd.options ? extractPositionalArgsInfo(cmd.options, cmd.meta) : {
633
+ args: [],
634
+ positionalNames: /* @__PURE__ */ new Set()
635
+ };
636
+ const hasArguments = positionalArgs.length > 0;
637
+ const helpInfo = {
638
+ name: commandName,
639
+ title: cmd.title,
640
+ description: cmd.description,
641
+ deprecated: cmd.deprecated,
642
+ hidden: cmd.hidden,
643
+ usage: {
644
+ command: rootCmd === cmd ? commandName : `${rootCmd.name} ${commandName}`,
645
+ hasSubcommands: !!(cmd.commands && cmd.commands.length > 0),
646
+ hasArguments,
647
+ hasOptions: !!cmd.options
648
+ }
649
+ };
650
+ if (cmd.commands && cmd.commands.length > 0) {
651
+ const visibleCommands = detail === "full" ? cmd.commands : cmd.commands.filter((c) => !c.hidden);
652
+ helpInfo.subcommands = visibleCommands.map((c) => ({
653
+ name: c.name,
654
+ title: c.title,
655
+ description: c.description,
656
+ deprecated: c.deprecated,
657
+ hidden: c.hidden
658
+ }));
659
+ if (detail === "full") helpInfo.nestedCommands = visibleCommands.map((c) => getHelpInfo(c, "full"));
660
+ }
661
+ if (hasArguments) helpInfo.arguments = positionalArgs;
662
+ if (cmd.options) {
663
+ const optionsInfo = extractOptionsInfo(cmd.options, cmd.meta, positionalNames);
664
+ const optMap = Object.fromEntries(optionsInfo.map((opt) => [opt.name, opt]));
665
+ const { aliases } = extractSchemaMetadata(cmd.options, cmd.meta?.options);
666
+ for (const [alias, name] of Object.entries(aliases)) {
667
+ const opt = optMap[name];
668
+ if (!opt) continue;
669
+ opt.aliases = [...opt.aliases || [], alias];
670
+ }
671
+ const visibleOptions = optionsInfo.filter((opt) => !opt.hidden);
672
+ if (visibleOptions.length > 0) helpInfo.options = visibleOptions;
673
+ }
674
+ return helpInfo;
675
+ }
676
+ function generateHelp(rootCommand, commandObj = rootCommand, options) {
677
+ const helpInfo = getHelpInfo(commandObj, options?.detail);
678
+ return createFormatter(options?.format ?? "auto", options?.detail).format(helpInfo);
679
+ }
680
+
681
+ //#endregion
682
+ //#region src/parse.ts
683
+ /**
684
+ * Tokenizes input string respecting quoted strings and bracket arrays.
685
+ * Supports single quotes, double quotes, backticks, and square brackets.
686
+ */
687
+ function tokenizeInput(input) {
688
+ const tokens = [];
689
+ let current = "";
690
+ let inQuote = null;
691
+ let bracketDepth = 0;
692
+ let i = 0;
693
+ while (i < input.length) {
694
+ const char = input[i];
695
+ if (inQuote) {
696
+ if (char === "\\" && i + 1 < input.length) {
697
+ const nextChar = input[i + 1];
698
+ if (nextChar === inQuote || nextChar === "\\") {
699
+ current += nextChar;
700
+ i += 2;
701
+ continue;
702
+ }
703
+ }
704
+ if (char === inQuote) inQuote = null;
705
+ else current += char;
706
+ } else if (char === "[") {
707
+ bracketDepth++;
708
+ current += char;
709
+ } else if (char === "]") {
710
+ bracketDepth = Math.max(0, bracketDepth - 1);
711
+ current += char;
712
+ } else if (bracketDepth > 0) current += char;
713
+ else if (char === "\"" || char === "'" || char === "`") inQuote = char;
714
+ else if (char === " " || char === " ") {
715
+ if (current) {
716
+ tokens.push(current);
717
+ current = "";
718
+ }
719
+ } else current += char;
720
+ i++;
721
+ }
722
+ if (current) tokens.push(current);
723
+ return tokens;
724
+ }
725
+ function parseCliInputToParts(input) {
726
+ const parts = tokenizeInput(input.trim());
727
+ const result = [];
728
+ let pendingValue;
729
+ let allowTerm = true;
730
+ for (const part of parts) {
731
+ if (!part) continue;
732
+ const wasPending = pendingValue;
733
+ pendingValue = void 0;
734
+ if (part.startsWith("--no-") && part.length > 5) {
735
+ const p = {
736
+ type: "option",
737
+ key: part.slice(5),
738
+ value: void 0,
739
+ negated: true
740
+ };
741
+ result.push(p);
742
+ } else if (part.startsWith("--")) {
743
+ const [key = "", value] = splitOptionValue(part.slice(2));
744
+ const p = {
745
+ type: "option",
746
+ key,
747
+ value
748
+ };
749
+ if (typeof value === "undefined") pendingValue = p;
750
+ result.push(p);
751
+ } else if (part.startsWith("-") && part.length > 1 && !/^-\d/.test(part)) {
752
+ const [key = "", value] = splitOptionValue(part.slice(1));
753
+ const p = {
754
+ type: "alias",
755
+ key,
756
+ value
757
+ };
758
+ if (typeof value === "undefined") pendingValue = p;
759
+ result.push(p);
760
+ } else if (wasPending) wasPending.value = part;
761
+ else if (/^[a-zA-Z0-9_-]+$/.test(part) && allowTerm) result.push({
762
+ type: "term",
763
+ value: part
764
+ });
765
+ else {
766
+ result.push({
767
+ type: "arg",
768
+ value: part
769
+ });
770
+ allowTerm = false;
771
+ }
772
+ }
773
+ return result;
774
+ }
775
+ /**
776
+ * Split option key and value, handling quoted values after =.
777
+ */
778
+ function splitOptionValue(str) {
779
+ const eqIndex = str.indexOf("=");
780
+ if (eqIndex === -1) return [str, void 0];
781
+ const key = str.slice(0, eqIndex);
782
+ let value = str.slice(eqIndex + 1);
783
+ if (value.startsWith("\"") && value.endsWith("\"") || value.startsWith("'") && value.endsWith("'") || value.startsWith("`") && value.endsWith("`")) {
784
+ value = value.slice(1, -1);
785
+ return [key, value];
786
+ }
787
+ if (value.startsWith("[") && value.endsWith("]")) {
788
+ const inner = value.slice(1, -1);
789
+ if (inner === "") return [key, []];
790
+ return [key, parseArrayItems(inner)];
791
+ }
792
+ return [key, value];
793
+ }
794
+ /**
795
+ * Parse comma-separated items, respecting quotes within items.
796
+ */
797
+ function parseArrayItems(input) {
798
+ const items = [];
799
+ let current = "";
800
+ let inQuote = null;
801
+ let i = 0;
802
+ while (i < input.length) {
803
+ const char = input[i];
804
+ if (inQuote) {
805
+ if (char === "\\" && i + 1 < input.length && input[i + 1] === inQuote) {
806
+ current += input[i + 1];
807
+ i += 2;
808
+ continue;
809
+ }
810
+ if (char === inQuote) inQuote = null;
811
+ else current += char;
812
+ } else if (char === "\"" || char === "'" || char === "`") inQuote = char;
813
+ else if (char === ",") {
814
+ items.push(current.trim());
815
+ current = "";
816
+ } else current += char;
817
+ i++;
818
+ }
819
+ if (current || items.length > 0) items.push(current.trim());
820
+ return items;
821
+ }
822
+
823
+ //#endregion
824
+ //#region src/create.ts
825
+ const commandSymbol = Symbol("padrone_command");
826
+ const noop = () => void 0;
827
+ function createPadroneCommandBuilder(existingCommand) {
828
+ function findCommandByName(name, commands) {
829
+ if (!commands) return void 0;
830
+ const foundByName = commands.find((cmd) => cmd.name === name);
831
+ if (foundByName) return foundByName;
832
+ for (const cmd of commands) if (cmd.commands && name.startsWith(`${cmd.name} `)) {
833
+ const subCommand = findCommandByName(name.slice(cmd.name.length + 1), cmd.commands);
834
+ if (subCommand) return subCommand;
835
+ }
836
+ }
837
+ const find = (command) => {
838
+ return findCommandByName(command, existingCommand.commands);
839
+ };
840
+ /**
841
+ * Parses CLI input to find the command and extract raw options without validation.
842
+ */
843
+ const parseCommand = (input) => {
844
+ input ??= typeof process !== "undefined" ? process.argv.slice(2).join(" ") : void 0;
845
+ if (!input) return {
846
+ command: existingCommand,
847
+ rawOptions: {},
848
+ args: []
849
+ };
850
+ const parts = parseCliInputToParts(input);
851
+ const terms = parts.filter((p) => p.type === "term").map((p) => p.value);
852
+ const args = parts.filter((p) => p.type === "arg").map((p) => p.value);
853
+ let curCommand = existingCommand;
854
+ if (terms[0] === existingCommand.name) terms.shift();
855
+ for (let i = 0; i < terms.length; i++) {
856
+ const found = findCommandByName(terms[i] || "", curCommand.commands);
857
+ if (found) curCommand = found;
858
+ else {
859
+ args.unshift(...terms.slice(i));
860
+ break;
861
+ }
862
+ }
863
+ if (!curCommand) return {
864
+ command: existingCommand,
865
+ rawOptions: {},
866
+ args
867
+ };
868
+ const optionsMeta = curCommand.meta?.options;
869
+ const { aliases } = curCommand.options ? extractSchemaMetadata(curCommand.options, optionsMeta) : {
870
+ aliases: {},
871
+ envBindings: {},
872
+ configKeys: {}
873
+ };
874
+ const arrayOptions = /* @__PURE__ */ new Set();
875
+ if (curCommand.options) try {
876
+ const jsonSchema = curCommand.options["~standard"].jsonSchema.input({ target: "draft-2020-12" });
877
+ if (jsonSchema.type === "object" && jsonSchema.properties) {
878
+ for (const [key, prop] of Object.entries(jsonSchema.properties)) if (prop?.type === "array") arrayOptions.add(key);
879
+ }
880
+ } catch {}
881
+ const opts = parts.filter((p) => p.type === "option" || p.type === "alias");
882
+ const rawOptions = {};
883
+ for (const opt of opts) {
884
+ const key = opt.type === "alias" ? aliases[opt.key] || opt.key : opt.key;
885
+ if (opt.type === "option" && opt.negated) {
886
+ rawOptions[key] = false;
887
+ continue;
888
+ }
889
+ const value = opt.value ?? true;
890
+ if (arrayOptions.has(key)) if (key in rawOptions) {
891
+ const existing = rawOptions[key];
892
+ if (Array.isArray(existing)) if (Array.isArray(value)) existing.push(...value);
893
+ else existing.push(value);
894
+ else if (Array.isArray(value)) rawOptions[key] = [existing, ...value];
895
+ else rawOptions[key] = [existing, value];
896
+ } else rawOptions[key] = Array.isArray(value) ? value : [value];
897
+ else rawOptions[key] = value;
898
+ }
899
+ return {
900
+ command: curCommand,
901
+ rawOptions,
902
+ args
903
+ };
904
+ };
905
+ /**
906
+ * Validates raw options against the command's schema and applies preprocessing.
907
+ */
908
+ const validateOptions = (command, rawOptions, args, parseOptions) => {
909
+ const optionsMeta = command.meta?.options;
910
+ const { envBindings, configKeys } = command.options ? extractSchemaMetadata(command.options, optionsMeta) : {
911
+ aliases: {},
912
+ envBindings: {},
913
+ configKeys: {}
914
+ };
915
+ const preprocessedOptions = preprocessOptions(rawOptions, {
916
+ aliases: {},
917
+ envBindings,
918
+ configKeys,
919
+ configData: parseOptions?.configData,
920
+ env: parseOptions?.env
921
+ });
922
+ const positionalConfig = command.meta?.positional ? parsePositionalConfig(command.meta.positional) : [];
923
+ if (positionalConfig.length > 0) {
924
+ let argIndex = 0;
925
+ for (const { name, variadic } of positionalConfig) {
926
+ if (argIndex >= args.length) break;
927
+ if (variadic) {
928
+ const nonVariadicAfter = positionalConfig.slice(positionalConfig.indexOf({
929
+ name,
930
+ variadic
931
+ }) + 1).filter((p) => !p.variadic).length;
932
+ const variadicEnd = args.length - nonVariadicAfter;
933
+ preprocessedOptions[name] = args.slice(argIndex, variadicEnd);
934
+ argIndex = variadicEnd;
935
+ } else {
936
+ preprocessedOptions[name] = args[argIndex];
937
+ argIndex++;
938
+ }
939
+ }
940
+ }
941
+ const optionsParsed = command.options ? command.options["~standard"].validate(preprocessedOptions) : { value: preprocessedOptions };
942
+ if (optionsParsed instanceof Promise) throw new Error("Async validation is not supported. Schema validate() must return a synchronous result.");
943
+ const hasOptions = command.options || Object.keys(preprocessedOptions).length > 0;
944
+ return {
945
+ options: optionsParsed.issues ? void 0 : hasOptions ? optionsParsed.value : void 0,
946
+ optionsResult: optionsParsed
947
+ };
948
+ };
949
+ const parse = (input, parseOptions) => {
950
+ const { command, rawOptions, args } = parseCommand(input);
951
+ const { options, optionsResult } = validateOptions(command, rawOptions, args, parseOptions);
952
+ return {
953
+ command,
954
+ options,
955
+ optionsResult
956
+ };
957
+ };
958
+ const stringify = (command = "", options) => {
959
+ const commandObj = typeof command === "string" ? findCommandByName(command, existingCommand.commands) : command;
960
+ if (!commandObj) throw new Error(`Command "${command ?? ""}" not found`);
961
+ const parts = [];
962
+ if (commandObj.path) parts.push(commandObj.path);
963
+ const positionalConfig = commandObj.meta?.positional ? parsePositionalConfig(commandObj.meta.positional) : [];
964
+ const positionalNames = new Set(positionalConfig.map((p) => p.name));
965
+ if (options && typeof options === "object") {
966
+ for (const { name, variadic } of positionalConfig) {
967
+ const value = options[name];
968
+ if (value === void 0) continue;
969
+ if (variadic && Array.isArray(value)) for (const v of value) {
970
+ const vStr = String(v);
971
+ if (vStr.includes(" ")) parts.push(`"${vStr}"`);
972
+ else parts.push(vStr);
973
+ }
974
+ else {
975
+ const argStr = String(value);
976
+ if (argStr.includes(" ")) parts.push(`"${argStr}"`);
977
+ else parts.push(argStr);
978
+ }
979
+ }
980
+ for (const [key, value] of Object.entries(options)) {
981
+ if (value === void 0 || positionalNames.has(key)) continue;
982
+ if (typeof value === "boolean") if (value) parts.push(`--${key}`);
983
+ else parts.push(`--no-${key}`);
984
+ else if (Array.isArray(value)) for (const v of value) {
985
+ const vStr = String(v);
986
+ if (vStr.includes(" ")) parts.push(`--${key}="${vStr}"`);
987
+ else parts.push(`--${key}=${vStr}`);
988
+ }
989
+ else if (typeof value === "string") if (value.includes(" ")) parts.push(`--${key}="${value}"`);
990
+ else parts.push(`--${key}=${value}`);
991
+ else parts.push(`--${key}=${value}`);
992
+ }
993
+ }
994
+ return parts.join(" ");
995
+ };
996
+ /**
997
+ * Check if help or version flags/commands are present in the input.
998
+ * Returns the appropriate action to take, or null if normal execution should proceed.
999
+ */
1000
+ const checkBuiltinCommands = (input) => {
1001
+ if (!input) return null;
1002
+ const parts = parseCliInputToParts(input);
1003
+ const terms = parts.filter((p) => p.type === "term").map((p) => p.value);
1004
+ const opts = parts.filter((p) => p.type === "option" || p.type === "alias");
1005
+ const hasHelpFlag = opts.some((p) => p.type === "option" && p.key === "help" || p.type === "alias" && p.key === "h");
1006
+ const getDetailLevel = () => {
1007
+ for (const opt of opts) {
1008
+ if (opt.type === "option" && opt.key === "detail" && typeof opt.value === "string") {
1009
+ if (opt.value === "minimal" || opt.value === "standard" || opt.value === "full") return opt.value;
1010
+ }
1011
+ if (opt.type === "alias" && opt.key === "d" && typeof opt.value === "string") {
1012
+ if (opt.value === "minimal" || opt.value === "standard" || opt.value === "full") return opt.value;
1013
+ }
1014
+ }
1015
+ };
1016
+ const detail = getDetailLevel();
1017
+ const getFormat = () => {
1018
+ const validFormats = [
1019
+ "text",
1020
+ "ansi",
1021
+ "console",
1022
+ "markdown",
1023
+ "html",
1024
+ "json",
1025
+ "auto"
1026
+ ];
1027
+ for (const opt of opts) {
1028
+ if (opt.type === "option" && opt.key === "format" && typeof opt.value === "string") {
1029
+ if (validFormats.includes(opt.value)) return opt.value;
1030
+ }
1031
+ if (opt.type === "alias" && opt.key === "f" && typeof opt.value === "string") {
1032
+ if (validFormats.includes(opt.value)) return opt.value;
1033
+ }
1034
+ }
1035
+ };
1036
+ const format = getFormat();
1037
+ const hasVersionFlag = opts.some((p) => p.type === "option" && p.key === "version" || p.type === "alias" && (p.key === "v" || p.key === "V"));
1038
+ const normalizedTerms = [...terms];
1039
+ if (normalizedTerms[0] === existingCommand.name) normalizedTerms.shift();
1040
+ const userHelpCommand = findCommandByName("help", existingCommand.commands);
1041
+ const userVersionCommand = findCommandByName("version", existingCommand.commands);
1042
+ if (!userHelpCommand && normalizedTerms[0] === "help") {
1043
+ const commandName = normalizedTerms.slice(1).join(" ");
1044
+ return {
1045
+ type: "help",
1046
+ command: commandName ? findCommandByName(commandName, existingCommand.commands) : void 0,
1047
+ detail,
1048
+ format
1049
+ };
1050
+ }
1051
+ if (!userVersionCommand && normalizedTerms[0] === "version") return { type: "version" };
1052
+ if (hasHelpFlag) {
1053
+ const commandName = normalizedTerms.filter((t) => t !== "help").join(" ");
1054
+ return {
1055
+ type: "help",
1056
+ command: commandName ? findCommandByName(commandName, existingCommand.commands) : void 0,
1057
+ detail,
1058
+ format
1059
+ };
1060
+ }
1061
+ if (hasVersionFlag && normalizedTerms.length === 0) return { type: "version" };
1062
+ return null;
1063
+ };
1064
+ /**
1065
+ * Extract the config file path from --config=<path> or -c <path> flags.
1066
+ */
1067
+ const extractConfigPath = (input) => {
1068
+ if (!input) return void 0;
1069
+ const opts = parseCliInputToParts(input).filter((p) => p.type === "option" || p.type === "alias");
1070
+ for (const opt of opts) {
1071
+ if (opt.type === "option" && opt.key === "config" && typeof opt.value === "string") return opt.value;
1072
+ if (opt.type === "alias" && opt.key === "c" && typeof opt.value === "string") return opt.value;
1073
+ }
1074
+ };
1075
+ const cli = (input, cliOptions) => {
1076
+ const resolvedInput = input ?? (typeof process !== "undefined" ? process.argv.slice(2).join(" ") : void 0);
1077
+ const builtin = checkBuiltinCommands(resolvedInput);
1078
+ if (builtin) {
1079
+ if (builtin.type === "help") {
1080
+ const helpText = generateHelp(existingCommand, builtin.command ?? existingCommand, {
1081
+ detail: builtin.detail,
1082
+ format: builtin.format
1083
+ });
1084
+ console.log(helpText);
1085
+ return {
1086
+ command: existingCommand,
1087
+ args: void 0,
1088
+ options: void 0,
1089
+ result: helpText
1090
+ };
1091
+ }
1092
+ if (builtin.type === "version") {
1093
+ const version = getVersion(existingCommand.version);
1094
+ console.log(version);
1095
+ return {
1096
+ command: existingCommand,
1097
+ options: void 0,
1098
+ result: version
1099
+ };
1100
+ }
1101
+ }
1102
+ const { command, rawOptions, args } = parseCommand(resolvedInput);
1103
+ const configPath = extractConfigPath(resolvedInput);
1104
+ const resolveConfigFiles = (cmd) => {
1105
+ if (cmd.configFiles !== void 0) return cmd.configFiles;
1106
+ if (cmd.parent) return resolveConfigFiles(cmd.parent);
1107
+ };
1108
+ const effectiveConfigFiles = resolveConfigFiles(command);
1109
+ let configData = cliOptions?.configData;
1110
+ if (configPath) configData = loadConfigFile(configPath);
1111
+ else if (effectiveConfigFiles?.length) {
1112
+ const foundConfigPath = findConfigFile(effectiveConfigFiles);
1113
+ if (foundConfigPath) configData = loadConfigFile(foundConfigPath) ?? configData;
1114
+ }
1115
+ const { options, optionsResult } = validateOptions(command, rawOptions, args, {
1116
+ ...cliOptions,
1117
+ configData
1118
+ });
1119
+ return {
1120
+ ...run(command, options),
1121
+ optionsResult
1122
+ };
1123
+ };
1124
+ const run = (command, options) => {
1125
+ const commandObj = typeof command === "string" ? findCommandByName(command, existingCommand.commands) : command;
1126
+ if (!commandObj) throw new Error(`Command "${command ?? ""}" not found`);
1127
+ if (!commandObj.handler) throw new Error(`Command "${commandObj.path}" has no handler`);
1128
+ return {
1129
+ command: commandObj,
1130
+ options,
1131
+ result: commandObj.handler(options)
1132
+ };
1133
+ };
1134
+ const tool = () => {
1135
+ return {
1136
+ type: "function",
1137
+ name: existingCommand.name,
1138
+ description: generateHelp(existingCommand, void 0, {
1139
+ format: "text",
1140
+ detail: "full"
1141
+ }),
1142
+ strict: true,
1143
+ inputExamples: [{ input: { command: "<command> [args...] [options...]" } }],
1144
+ inputSchema: {
1145
+ [Symbol.for("vercel.ai.schema")]: true,
1146
+ jsonSchema: {
1147
+ type: "object",
1148
+ properties: { command: { type: "string" } },
1149
+ additionalProperties: false
1150
+ },
1151
+ _type: void 0,
1152
+ validate: (value) => {
1153
+ const command = value?.command;
1154
+ if (typeof command === "string") return {
1155
+ success: true,
1156
+ value: { command }
1157
+ };
1158
+ return {
1159
+ success: false,
1160
+ error: /* @__PURE__ */ new Error("Expected an object with command property as string.")
1161
+ };
1162
+ }
1163
+ },
1164
+ title: existingCommand.description,
1165
+ needsApproval: (input) => {
1166
+ const { command, options } = parse(input.command);
1167
+ if (typeof command.needsApproval === "function") return command.needsApproval(options);
1168
+ return !!command.needsApproval;
1169
+ },
1170
+ execute: (input) => {
1171
+ return cli(input.command).result;
1172
+ }
1173
+ };
1174
+ };
1175
+ return {
1176
+ configure(config) {
1177
+ return createPadroneCommandBuilder({
1178
+ ...existingCommand,
1179
+ ...config
1180
+ });
1181
+ },
1182
+ options(options, meta) {
1183
+ return createPadroneCommandBuilder({
1184
+ ...existingCommand,
1185
+ options,
1186
+ meta
1187
+ });
1188
+ },
1189
+ action(handler = noop) {
1190
+ return createPadroneCommandBuilder({
1191
+ ...existingCommand,
1192
+ handler
1193
+ });
1194
+ },
1195
+ command: (name, builderFn) => {
1196
+ const initialCommand = {
1197
+ name,
1198
+ path: existingCommand.path ? `${existingCommand.path} ${name}` : name,
1199
+ parent: existingCommand,
1200
+ "~types": {}
1201
+ };
1202
+ const builder = createPadroneCommandBuilder(initialCommand);
1203
+ const commandObj = (builderFn?.(builder))?.[commandSymbol] ?? initialCommand;
1204
+ return createPadroneCommandBuilder({
1205
+ ...existingCommand,
1206
+ commands: [...existingCommand.commands || [], commandObj]
1207
+ });
1208
+ },
1209
+ run,
1210
+ find,
1211
+ parse,
1212
+ stringify,
1213
+ cli,
1214
+ tool,
1215
+ api() {
1216
+ function buildApi(command) {
1217
+ const runCommand = ((options) => run(command, options).result);
1218
+ if (!command.commands) return runCommand;
1219
+ for (const cmd of command.commands) runCommand[cmd.name] = buildApi(cmd);
1220
+ return runCommand;
1221
+ }
1222
+ return buildApi(existingCommand);
1223
+ },
1224
+ help(command, options) {
1225
+ const commandObj = !command ? existingCommand : typeof command === "string" ? findCommandByName(command, existingCommand.commands) : command;
1226
+ if (!commandObj) throw new Error(`Command "${command ?? ""}" not found`);
1227
+ return generateHelp(existingCommand, commandObj, options);
1228
+ },
1229
+ "~types": {},
1230
+ [commandSymbol]: existingCommand
1231
+ };
1232
+ }
1233
+
1234
+ //#endregion
1235
+ //#region src/index.ts
1236
+ function createPadrone(name) {
1237
+ return createPadroneCommandBuilder({
1238
+ name,
1239
+ path: "",
1240
+ commands: []
1241
+ });
1242
+ }
1243
+
1244
+ //#endregion
1245
+ export { createPadrone };
1246
+ //# sourceMappingURL=index.mjs.map