padrone 1.6.0 → 1.7.1

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 (33) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/docs/index.mjs +1 -1
  3. package/dist/{errors-CL63UOzt.mjs → errors-DA4KzK1M.mjs} +1 -1
  4. package/dist/{errors-CL63UOzt.mjs.map → errors-DA4KzK1M.mjs.map} +1 -1
  5. package/dist/formatter-DrvhDMrq.d.mts.map +1 -1
  6. package/dist/{help-B5Kk83of.mjs → help-BtxLgrF_.mjs} +88 -55
  7. package/dist/help-BtxLgrF_.mjs.map +1 -0
  8. package/dist/{index-BaU3X6dY.d.mts → index-C0Tab27T.d.mts} +25 -4
  9. package/dist/{index-BaU3X6dY.d.mts.map → index-C0Tab27T.d.mts.map} +1 -1
  10. package/dist/index.d.mts +143 -8
  11. package/dist/index.d.mts.map +1 -1
  12. package/dist/index.mjs +363 -24
  13. package/dist/index.mjs.map +1 -1
  14. package/dist/{mcp-BM-d0nZi.mjs → mcp-6-Jw4Bpq.mjs} +2 -2
  15. package/dist/{mcp-BM-d0nZi.mjs.map → mcp-6-Jw4Bpq.mjs.map} +1 -1
  16. package/dist/{serve-Bk0JUlCj.mjs → serve-YVTPzBCl.mjs} +3 -3
  17. package/dist/{serve-Bk0JUlCj.mjs.map → serve-YVTPzBCl.mjs.map} +1 -1
  18. package/dist/test.d.mts +1 -1
  19. package/dist/zod.d.mts +1 -1
  20. package/package.json +1 -1
  21. package/src/core/create.ts +33 -0
  22. package/src/extension/auto-output.ts +72 -21
  23. package/src/extension/config.ts +1 -1
  24. package/src/extension/index.ts +1 -0
  25. package/src/extension/logger.ts +49 -1
  26. package/src/index.ts +5 -1
  27. package/src/output/formatter.ts +16 -168
  28. package/src/output/output-indicator.ts +87 -0
  29. package/src/output/primitives.ts +335 -0
  30. package/src/output/styling.ts +221 -0
  31. package/src/types/builder.ts +87 -37
  32. package/src/types/index.ts +1 -0
  33. package/dist/help-B5Kk83of.mjs.map +0 -1
package/dist/index.mjs CHANGED
@@ -1,8 +1,8 @@
1
1
  import { _ as resolveStdin, c as getCommandRuntime, d as repathCommandTree, f as resolveAllCommands, g as createTerminalReplSession, h as suggestSimilar, i as commandSymbol, l as lazyResolver, n as buildReplCompleter, o as findCommandByName, p as resolveCommand, u as mergeCommands, v as resolveStdinAlways, y as REPL_SIGINT } from "./commands-B_gufyR9.mjs";
2
2
  import { a as getJsonSchema, c as parsePositionalConfig, i as extractSchemaMetadata, l as preprocessArgs, n as coerceArgs, o as isArrayField, r as detectUnknownArgs, s as isAsyncStreamField, t as applyValues } from "./args-Cnq0nwSM.mjs";
3
3
  import { i as createStdinStream, r as concatBytes, t as asyncStream } from "./stream-DC4H8YTx.mjs";
4
- import { a as SignalError, i as RoutingError, n as ConfigError, o as ValidationError, r as PadroneError, s as signalExitCode, t as ActionError } from "./errors-CL63UOzt.mjs";
5
- import { a as getVersion, i as getRootCommand, r as colorThemes, t as generateHelp } from "./help-B5Kk83of.mjs";
4
+ import { a as escapeHtml, i as getVersion, o as resolveOutputFormat, r as getRootCommand, s as colorThemes, t as generateHelp } from "./help-BtxLgrF_.mjs";
5
+ import { a as SignalError, i as RoutingError, n as ConfigError, o as ValidationError, r as PadroneError, s as signalExitCode, t as ActionError } from "./errors-DA4KzK1M.mjs";
6
6
  //#region src/core/results.ts
7
7
  /**
8
8
  * Brands a schema as async, signaling that its `validate()` may return a Promise.
@@ -326,6 +326,258 @@ function wrapWithLifecycle(interceptors, command, input, pipeline, wrapErrorResu
326
326
  return handleSuccess(result);
327
327
  }
328
328
  //#endregion
329
+ //#region src/output/primitives.ts
330
+ function stringifyCell(value) {
331
+ if (value === void 0 || value === null) return "";
332
+ if (typeof value === "string") return value;
333
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
334
+ return JSON.stringify(value);
335
+ }
336
+ function truncate(text, max) {
337
+ if (max <= 0 || text.length <= max) return text;
338
+ return max <= 1 ? "…" : `${text.slice(0, max - 1)}…`;
339
+ }
340
+ function padCell(text, width, alignment = "left") {
341
+ const pad = width - text.length;
342
+ if (pad <= 0) return text;
343
+ if (alignment === "right") return " ".repeat(pad) + text;
344
+ if (alignment === "center") {
345
+ const left = Math.floor(pad / 2);
346
+ return " ".repeat(left) + text + " ".repeat(pad - left);
347
+ }
348
+ return text + " ".repeat(pad);
349
+ }
350
+ function renderTable(data, options, ctx) {
351
+ if (data.length === 0) return "";
352
+ if (ctx.format === "json") return JSON.stringify(data, null, 2);
353
+ const columns = options?.columns ?? Object.keys(data[0]);
354
+ if (columns.length === 0) return "";
355
+ const headers = columns.map((col) => options?.headers?.[col] ?? col);
356
+ const maxCol = options?.maxColumnWidth;
357
+ const rows = data.map((row) => columns.map((col) => {
358
+ const text = stringifyCell(row[col]);
359
+ return maxCol ? truncate(text, maxCol) : text;
360
+ }));
361
+ const colWidths = columns.map((_, i) => {
362
+ const headerWidth = headers[i].length;
363
+ const maxCellWidth = rows.reduce((max, row) => Math.max(max, row[i].length), 0);
364
+ return Math.max(headerWidth, maxCellWidth);
365
+ });
366
+ const getAlign = (i) => options?.align?.[columns[i]] ?? "left";
367
+ if (ctx.format === "markdown") return renderTableMarkdown(headers, rows, colWidths, getAlign);
368
+ if (ctx.format === "html") return renderTableHtml(columns, headers, rows, data, getAlign);
369
+ return renderTableText(headers, rows, colWidths, getAlign, options?.border !== false, ctx);
370
+ }
371
+ function renderTableText(headers, rows, colWidths, getAlign, border, ctx) {
372
+ const { styler } = ctx;
373
+ const formatRow = (cells, style) => cells.map((cell, i) => {
374
+ const padded = padCell(cell, colWidths[i], getAlign(i));
375
+ return style ? style(padded) : padded;
376
+ });
377
+ if (border) {
378
+ const sep = ctx.styler.meta("─");
379
+ const divider = colWidths.map((w) => sep.repeat(w + 2)).join(styler.meta("┼"));
380
+ const row = (cells) => cells.map((c, i) => ` ${padCell(c, colWidths[i], getAlign(i))} `).join(styler.meta("│"));
381
+ const headerRow = row(headers.map((h) => styler.label(h)));
382
+ const dataRows = rows.map((r) => row(r.map((c) => styler.description(c))));
383
+ return [
384
+ headerRow,
385
+ styler.meta("─") + divider + styler.meta("─"),
386
+ ...dataRows
387
+ ].join("\n");
388
+ }
389
+ const headerCells = formatRow(headers, styler.label);
390
+ const dataCells = rows.map((r) => formatRow(r, styler.description));
391
+ const gap = " ";
392
+ return [headerCells.join(gap), ...dataCells.map((r) => r.join(gap))].join("\n");
393
+ }
394
+ function renderTableMarkdown(headers, rows, colWidths, getAlign) {
395
+ return [
396
+ `| ${headers.map((h, i) => padCell(h, colWidths[i], "left")).join(" | ")} |`,
397
+ "| " + colWidths.map((w, i) => {
398
+ const a = getAlign(i);
399
+ const dashes = "─".repeat(Math.max(w, 3));
400
+ if (a === "center") return `:${dashes}:`;
401
+ if (a === "right") return `${dashes}:`;
402
+ return dashes;
403
+ }).join(" | ") + " |",
404
+ ...rows.map((r) => `| ${r.map((c, i) => padCell(c, colWidths[i], "left")).join(" | ")} |`)
405
+ ].join("\n");
406
+ }
407
+ function renderTableHtml(columns, headers, _rows, data, getAlign) {
408
+ const ths = headers.map((h, i) => {
409
+ const a = getAlign(i);
410
+ return `<th${a !== "left" ? ` style="text-align: ${a};"` : ""}>${escapeHtml(h)}</th>`;
411
+ });
412
+ const trs = data.map((row) => "<tr>" + columns.map((col, i) => {
413
+ const a = getAlign(i);
414
+ return `<td${a !== "left" ? ` style="text-align: ${a};"` : ""}>${escapeHtml(stringifyCell(row[col]))}</td>`;
415
+ }).join("") + "</tr>");
416
+ return `<table><thead><tr>${ths.join("")}</tr></thead><tbody>${trs.join("")}</tbody></table>`;
417
+ }
418
+ function renderTree(data, options, ctx) {
419
+ const nodes = Array.isArray(data) ? data : [data];
420
+ if (nodes.length === 0) return "";
421
+ if (ctx.format === "json") return JSON.stringify(nodes, null, 2);
422
+ if (ctx.format === "markdown") return renderTreeMarkdown(nodes, 0);
423
+ if (ctx.format === "html") return renderTreeHtml(nodes);
424
+ return renderTreeText(nodes, "", options?.guides !== false, ctx).join("\n");
425
+ }
426
+ function renderTreeText(nodes, prefix, guides, ctx) {
427
+ const lines = [];
428
+ for (let i = 0; i < nodes.length; i++) {
429
+ const node = nodes[i];
430
+ const isLast = i === nodes.length - 1;
431
+ if (guides) {
432
+ const connector = isLast ? "└── " : "├── ";
433
+ const childPrefix = isLast ? " " : "│ ";
434
+ lines.push(prefix + ctx.styler.meta(connector) + ctx.styler.label(node.label));
435
+ if (node.children?.length) lines.push(...renderTreeText(node.children, prefix + ctx.styler.meta(childPrefix), guides, ctx));
436
+ } else {
437
+ const indent = prefix ? `${prefix} ` : "";
438
+ lines.push(indent + ctx.styler.label(node.label));
439
+ if (node.children?.length) lines.push(...renderTreeText(node.children, indent, guides, ctx));
440
+ }
441
+ }
442
+ return lines;
443
+ }
444
+ function renderTreeMarkdown(nodes, depth) {
445
+ return nodes.map((node) => {
446
+ const line = `${" ".repeat(depth)}- ${node.label}`;
447
+ if (!node.children?.length) return line;
448
+ return `${line}\n${renderTreeMarkdown(node.children, depth + 1)}`;
449
+ }).join("\n");
450
+ }
451
+ function renderTreeHtml(nodes) {
452
+ return `<ul>${nodes.map((node) => {
453
+ const label = escapeHtml(node.label);
454
+ if (!node.children?.length) return `<li>${label}</li>`;
455
+ return `<li>${label}${renderTreeHtml(node.children)}</li>`;
456
+ }).join("")}</ul>`;
457
+ }
458
+ function renderList(data, options, ctx) {
459
+ if (data.length === 0) return "";
460
+ if (ctx.format === "json") {
461
+ const normalized = data.map((item) => typeof item === "string" ? { label: item } : item);
462
+ return JSON.stringify(normalized, null, 2);
463
+ }
464
+ if (ctx.format === "markdown") return renderListMarkdown(data, options);
465
+ if (ctx.format === "html") return renderListHtml(data, options);
466
+ return renderListText(data, options, ctx);
467
+ }
468
+ function renderListText(data, options, ctx) {
469
+ const { styler } = ctx;
470
+ const numbered = options?.numbered ?? false;
471
+ const bullet = options?.bullet ?? (ctx.format === "ansi" ? "•" : "-");
472
+ const baseIndent = " ".repeat(options?.indent ?? 0);
473
+ return data.map((item, i) => {
474
+ const prefix = numbered ? `${i + 1}.` : bullet;
475
+ const label = typeof item === "string" ? item : item.label;
476
+ const desc = typeof item === "object" && item.description ? item.description : void 0;
477
+ const line = `${baseIndent}${styler.meta(prefix)} ${styler.label(label)}`;
478
+ if (!desc) return line;
479
+ return `${line} ${styler.description(desc)}`;
480
+ }).join("\n");
481
+ }
482
+ function renderListMarkdown(data, options) {
483
+ const numbered = options?.numbered ?? false;
484
+ return data.map((item, i) => {
485
+ const prefix = numbered ? `${i + 1}.` : "-";
486
+ const label = typeof item === "string" ? item : item.label;
487
+ const desc = typeof item === "object" && item.description ? item.description : void 0;
488
+ if (!desc) return `${prefix} ${label}`;
489
+ return `${prefix} **${label}** — ${desc}`;
490
+ }).join("\n");
491
+ }
492
+ function renderListHtml(data, options) {
493
+ const tag = options?.numbered ? "ol" : "ul";
494
+ return `<${tag}>${data.map((item) => {
495
+ const label = typeof item === "string" ? item : item.label;
496
+ const desc = typeof item === "object" && item.description ? item.description : void 0;
497
+ if (!desc) return `<li>${escapeHtml(label)}</li>`;
498
+ return `<li><strong>${escapeHtml(label)}</strong> — ${escapeHtml(desc)}</li>`;
499
+ }).join("")}</${tag}>`;
500
+ }
501
+ function renderKeyValue(data, options, ctx) {
502
+ const entries = Object.entries(data);
503
+ if (entries.length === 0) return "";
504
+ if (ctx.format === "json") return JSON.stringify(data, null, 2);
505
+ if (ctx.format === "markdown") return renderKeyValueMarkdown(entries, options);
506
+ if (ctx.format === "html") return renderKeyValueHtml(entries, options);
507
+ return renderKeyValueText(entries, options, ctx);
508
+ }
509
+ function getLabel(key, labels) {
510
+ return labels?.[key] ?? key;
511
+ }
512
+ function renderKeyValueText(entries, options, ctx) {
513
+ const { styler } = ctx;
514
+ const sep = options?.separator ?? ": ";
515
+ const shouldAlign = options?.align !== false;
516
+ const displayLabels = entries.map(([k]) => getLabel(k, options?.labels));
517
+ const maxWidth = shouldAlign ? Math.max(...displayLabels.map((l) => l.length)) : 0;
518
+ return entries.map(([_key, value], i) => {
519
+ const label = displayLabels[i];
520
+ const paddedLabel = shouldAlign ? label + " ".repeat(maxWidth - label.length) : label;
521
+ return `${styler.label(paddedLabel)}${styler.meta(sep)}${styler.description(stringifyCell(value))}`;
522
+ }).join("\n");
523
+ }
524
+ function renderKeyValueMarkdown(entries, options) {
525
+ return entries.map(([key, value]) => `- **${getLabel(key, options?.labels)}**: ${stringifyCell(value)}`).join("\n");
526
+ }
527
+ function renderKeyValueHtml(entries, options) {
528
+ return `<dl>${entries.map(([key, value]) => `<dt>${escapeHtml(getLabel(key, options?.labels))}</dt><dd>${escapeHtml(stringifyCell(value))}</dd>`).join("")}</dl>`;
529
+ }
530
+ //#endregion
531
+ //#region src/output/output-indicator.ts
532
+ /** Create an output indicator that renders through the given output function and format context. */
533
+ function createOutputIndicator(outputFn, ctx) {
534
+ let _called = false;
535
+ const emit = (rendered) => {
536
+ _called = true;
537
+ outputFn(rendered);
538
+ };
539
+ return {
540
+ table(data, options) {
541
+ emit(renderTable(data, options, ctx));
542
+ },
543
+ tree(data, options) {
544
+ emit(renderTree(data, options, ctx));
545
+ },
546
+ list(data, options) {
547
+ emit(renderList(data, options, ctx));
548
+ },
549
+ kv(data, options) {
550
+ emit(renderKeyValue(data, options, ctx));
551
+ },
552
+ raw(...args) {
553
+ _called = true;
554
+ outputFn(...args);
555
+ },
556
+ get called() {
557
+ return _called;
558
+ }
559
+ };
560
+ }
561
+ /** Format a return value using a declarative output config. */
562
+ function formatDeclarativeOutput(value, config, ctx) {
563
+ const type = typeof config === "string" ? config : config.type;
564
+ const options = typeof config === "object" ? config.options : void 0;
565
+ switch (type) {
566
+ case "table":
567
+ if (!Array.isArray(value)) return void 0;
568
+ return renderTable(value, options, ctx);
569
+ case "tree": return renderTree(value, options, ctx);
570
+ case "list":
571
+ if (!Array.isArray(value)) return void 0;
572
+ return renderList(value, options, ctx);
573
+ case "kv":
574
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
575
+ return renderKeyValue(value, options, ctx);
576
+ case "json": return JSON.stringify(value, null, 2);
577
+ default: return;
578
+ }
579
+ }
580
+ //#endregion
329
581
  //#region src/extension/auto-output.ts
330
582
  /**
331
583
  * Outputs each value and collects into a result.
@@ -366,17 +618,36 @@ const autoOutputMeta = {
366
618
  name: "padrone:auto-output",
367
619
  order: -1100
368
620
  };
369
- const autoOutputInterceptor = defineInterceptor(autoOutputMeta, () => ({ execute(ctx, next) {
370
- const handleResult = (e) => {
371
- if (e.result instanceof Promise) return { result: e.result.then((value) => outputAndCollect(value, ctx.runtime.output)) };
372
- const collected = outputAndCollect(e.result, ctx.runtime.output);
373
- if (collected instanceof Promise) return collected.then((v) => ({ result: v }));
374
- return { result: collected };
375
- };
376
- const executedOrPromise = next();
377
- if (executedOrPromise instanceof Promise) return executedOrPromise.then(handleResult);
378
- return handleResult(executedOrPromise);
379
- } }));
621
+ function createAutoOutputInterceptor(outputConfig) {
622
+ return defineInterceptor(autoOutputMeta, () => ({ execute(ctx, next) {
623
+ const outputCtx = resolveOutputFormat(ctx.runtime, ctx.caller);
624
+ const indicator = createOutputIndicator(ctx.runtime.output, outputCtx);
625
+ const handleResult = (e) => {
626
+ if (indicator.called) return e;
627
+ const autoOutput = (value) => {
628
+ if (value == null) return value;
629
+ if (outputConfig) {
630
+ const rendered = formatDeclarativeOutput(value, outputConfig, outputCtx);
631
+ if (rendered !== void 0) {
632
+ ctx.runtime.output(rendered);
633
+ return value;
634
+ }
635
+ }
636
+ return outputAndCollect(value, ctx.runtime.output);
637
+ };
638
+ if (e.result instanceof Promise) return { result: e.result.then(autoOutput) };
639
+ const collected = autoOutput(e.result);
640
+ if (collected instanceof Promise) return collected.then((v) => ({ result: v }));
641
+ return { result: collected };
642
+ };
643
+ const executedOrPromise = next({ context: {
644
+ ...ctx.context,
645
+ output: indicator
646
+ } });
647
+ if (executedOrPromise instanceof Promise) return executedOrPromise.then(handleResult);
648
+ return handleResult(executedOrPromise);
649
+ } }));
650
+ }
380
651
  /**
381
652
  * Extension that automatically writes a command's return value to output after execution.
382
653
  *
@@ -386,12 +657,15 @@ const autoOutputInterceptor = defineInterceptor(autoOutputMeta, () => ({ execute
386
657
  * The result is replaced with the collected array so `drain()` still works.
387
658
  * - `undefined` and `null` results produce no output.
388
659
  *
660
+ * Also injects `ctx.context.output` with format-aware output primitives (table, tree, list, kv).
661
+ * When action handlers use these methods, auto-output skips to avoid double output.
662
+ *
389
663
  * Included in the default extensions. Can also be applied per-command:
390
664
  * ```ts
391
665
  * createPadrone('my-cli')
392
- * .command('greet', (c) =>
393
- * c.extend(padroneAutoOutput())
394
- * .action(() => 'hello')
666
+ * .command('users', (c) =>
667
+ * c.extend(padroneAutoOutput({ output: 'table' }))
668
+ * .action(() => fetchUsers())
395
669
  * )
396
670
  * ```
397
671
  */
@@ -399,7 +673,7 @@ function padroneAutoOutput(options) {
399
673
  const interceptor = options?.disabled ? defineInterceptor({
400
674
  ...autoOutputMeta,
401
675
  disabled: true
402
- }, () => ({})) : autoOutputInterceptor;
676
+ }, () => ({})) : createAutoOutputInterceptor(options?.output);
403
677
  return ((builder) => builder.intercept(interceptor));
404
678
  }
405
679
  //#endregion
@@ -2188,12 +2462,12 @@ function createProgramMethods(ctx, evalCommand) {
2188
2462
  };
2189
2463
  const mcp = async (prefs) => {
2190
2464
  resolveAllCommands(rootCommand);
2191
- const { startMcpServer } = await import("./mcp-BM-d0nZi.mjs");
2465
+ const { startMcpServer } = await import("./mcp-6-Jw4Bpq.mjs");
2192
2466
  return startMcpServer(ctx.builder, rootCommand, evalCommand, prefs);
2193
2467
  };
2194
2468
  const serve = async (prefs) => {
2195
2469
  resolveAllCommands(rootCommand);
2196
- const { startServeServer } = await import("./serve-Bk0JUlCj.mjs");
2470
+ const { startServeServer } = await import("./serve-YVTPzBCl.mjs");
2197
2471
  return startServeServer(ctx.builder, rootCommand, evalCommand, prefs);
2198
2472
  };
2199
2473
  return {
@@ -2414,6 +2688,34 @@ function createPadroneBuilder(inputCommand) {
2414
2688
  execCtx.builder = builder;
2415
2689
  return builder;
2416
2690
  }
2691
+ /**
2692
+ * Identity helper that contextually types a command builder callback while preserving its full return type.
2693
+ * Use this when defining commands in separate files — the parent program retains exact type information
2694
+ * about the subcommand's args, result, and nested commands.
2695
+ *
2696
+ * @example
2697
+ * ```ts
2698
+ * // my-command.ts
2699
+ * export const myCommand = defineCommand((c) =>
2700
+ * c.arguments(z.object({ name: z.string() }))
2701
+ * .action((args) => console.log(args.name))
2702
+ * );
2703
+ *
2704
+ * // cli.ts
2705
+ * createPadrone('test').command('my-command', myCommand)
2706
+ * ```
2707
+ *
2708
+ * @example With context
2709
+ * ```ts
2710
+ * export const myCommand = defineCommand<{ db: Database }>((c) =>
2711
+ * c.arguments(z.object({ id: z.string() }))
2712
+ * .action((args, ctx) => ctx.context.db.find(args.id))
2713
+ * );
2714
+ * ```
2715
+ */
2716
+ function defineCommand(fn) {
2717
+ return fn;
2718
+ }
2417
2719
  //#endregion
2418
2720
  //#region src/extension/completion.ts
2419
2721
  /**
@@ -2507,7 +2809,10 @@ function loadConfigSync(fs, path, files, xdgAppName) {
2507
2809
  return Bun.JSONC.parse(getContent());
2508
2810
  }
2509
2811
  }
2510
- if (ext === ".js" || ext === ".cjs" || ext === ".mjs" || ext === ".ts" || ext === ".cts" || ext === ".mts") return import(absolutePath).then((mod) => mod.default ?? mod);
2812
+ if (ext === ".js" || ext === ".cjs" || ext === ".mjs" || ext === ".ts" || ext === ".cts" || ext === ".mts") return import(
2813
+ /* @vite-ignore */
2814
+ absolutePath
2815
+ ).then((mod) => mod.default ?? mod);
2511
2816
  try {
2512
2817
  return JSON.parse(getContent());
2513
2818
  } catch {
@@ -2886,6 +3191,40 @@ const LEVEL_LABELS = {
2886
3191
  error: "ERROR"
2887
3192
  };
2888
3193
  const VALID_LEVELS = new Set(Object.keys(LEVEL_ORDER));
3194
+ /** Format specifier pattern: matches %s, %d, %i, %f, %o, %O, %j, %% */
3195
+ const FORMAT_PATTERN = /%%|%[sdifjoO]/g;
3196
+ /**
3197
+ * Applies printf-style format specifiers to args, following the WHATWG Console Standard
3198
+ * and Node.js `util.format` conventions. Remaining args are appended space-separated.
3199
+ */
3200
+ function formatArgs(args) {
3201
+ if (args.length === 0) return "";
3202
+ if (typeof args[0] !== "string" || !FORMAT_PATTERN.test(args[0])) return args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
3203
+ const template = args[0];
3204
+ let argIndex = 1;
3205
+ const result = template.replace(FORMAT_PATTERN, (token) => {
3206
+ if (token === "%%") return "%";
3207
+ if (argIndex >= args.length) return token;
3208
+ const val = args[argIndex++];
3209
+ switch (token) {
3210
+ case "%s": return String(val);
3211
+ case "%d":
3212
+ case "%i": return String(Math.trunc(Number(val)));
3213
+ case "%f": return String(Number(val));
3214
+ case "%j": try {
3215
+ return JSON.stringify(val);
3216
+ } catch {
3217
+ return "[Circular]";
3218
+ }
3219
+ case "%o":
3220
+ case "%O": return typeof val === "string" ? val : JSON.stringify(val);
3221
+ default: return token;
3222
+ }
3223
+ });
3224
+ const remaining = args.slice(argIndex);
3225
+ if (remaining.length === 0) return result;
3226
+ return `${result} ${remaining.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ")}`;
3227
+ }
2889
3228
  function resolveCliLevel(rawArgs) {
2890
3229
  if ("trace" in rawArgs) {
2891
3230
  const t = rawArgs.trace;
@@ -2925,7 +3264,7 @@ function createLogger(runtime, level, config, tracing) {
2925
3264
  if (config.timestamps) parts.push((/* @__PURE__ */ new Date()).toISOString());
2926
3265
  parts.push(`[${LEVEL_LABELS[lvl]}]`);
2927
3266
  if (prefix) parts.push(prefix);
2928
- parts.push(args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" "));
3267
+ parts.push(formatArgs(args));
2929
3268
  return parts.join(" ");
2930
3269
  }
2931
3270
  function makeLogger(prefix) {
@@ -3075,7 +3414,7 @@ function padroneMcp(defaults) {
3075
3414
  }), { positional: ["transport"] }).async().action(async (args, ctx) => {
3076
3415
  const rootCommand = getRootCommand(ctx.command);
3077
3416
  resolveAllCommands(rootCommand);
3078
- const { startMcpServer } = await import("./mcp-BM-d0nZi.mjs");
3417
+ const { startMcpServer } = await import("./mcp-6-Jw4Bpq.mjs");
3079
3418
  const transport = args.transport === "stdio" || args.transport === "http" ? args.transport : void 0;
3080
3419
  const port = args.port ? parseInt(args.port, 10) : void 0;
3081
3420
  const prefs = {
@@ -3612,7 +3951,7 @@ function padroneServe(defaults) {
3612
3951
  })).async().action(async (args, ctx) => {
3613
3952
  const rootCommand = getRootCommand(ctx.command);
3614
3953
  resolveAllCommands(rootCommand);
3615
- const { startServeServer } = await import("./serve-Bk0JUlCj.mjs");
3954
+ const { startServeServer } = await import("./serve-YVTPzBCl.mjs");
3616
3955
  const port = args.port ? parseInt(args.port, 10) : void 0;
3617
3956
  const prefs = {
3618
3957
  ...defaults,
@@ -3850,6 +4189,6 @@ function padroneUpdateCheck(config = {}) {
3850
4189
  return ((builder) => builder.intercept(createUpdateCheckInterceptor(config)));
3851
4190
  }
3852
4191
  //#endregion
3853
- export { ActionError, ConfigError, PadroneError, REPL_SIGINT, RoutingError, SignalError, ValidationError, asyncSchema, asyncStream, buildReplCompleter, colorThemes, createPadrone, createTerminalProgress, defineInterceptor, isReactElement, padroneAutoOutput, padroneColor, padroneCompletion, padroneConfig, padroneEnv, padroneHelp, padroneInk, padroneInteractive, padroneLogger, padroneMan, padroneMcp, padroneProgress, padroneRepl, padroneServe, padroneSignalHandling, padroneStdin, padroneSuggestions, padroneTiming, padroneTracing, padroneUpdateCheck, padroneVersion };
4192
+ export { ActionError, ConfigError, PadroneError, REPL_SIGINT, RoutingError, SignalError, ValidationError, asyncSchema, asyncStream, buildReplCompleter, colorThemes, createPadrone, createTerminalProgress, defineCommand, defineInterceptor, isReactElement, padroneAutoOutput, padroneColor, padroneCompletion, padroneConfig, padroneEnv, padroneHelp, padroneInk, padroneInteractive, padroneLogger, padroneMan, padroneMcp, padroneProgress, padroneRepl, padroneServe, padroneSignalHandling, padroneStdin, padroneSuggestions, padroneTiming, padroneTracing, padroneUpdateCheck, padroneVersion };
3854
4193
 
3855
4194
  //# sourceMappingURL=index.mjs.map