padrone 1.8.2 → 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.
- package/CHANGELOG.md +20 -1
- package/README.md +2 -2
- package/dist/codegen/code-builder.d.mts +10 -0
- package/dist/codegen/code-builder.d.mts.map +1 -0
- package/dist/codegen/code-builder.mjs +185 -0
- package/dist/codegen/code-builder.mjs.map +1 -0
- package/dist/codegen/discovery.d.mts +44 -0
- package/dist/codegen/discovery.d.mts.map +1 -0
- package/dist/codegen/discovery.mjs +179 -0
- package/dist/codegen/discovery.mjs.map +1 -0
- package/dist/codegen/file-emitter.d.mts +10 -0
- package/dist/codegen/file-emitter.d.mts.map +1 -0
- package/dist/codegen/file-emitter.mjs +58 -0
- package/dist/codegen/file-emitter.mjs.map +1 -0
- package/dist/codegen/generators/barrel-file.d.mts +10 -0
- package/dist/codegen/generators/barrel-file.d.mts.map +1 -0
- package/dist/codegen/generators/barrel-file.mjs +16 -0
- package/dist/codegen/generators/barrel-file.mjs.map +1 -0
- package/dist/codegen/generators/command-file.d.mts +25 -0
- package/dist/codegen/generators/command-file.d.mts.map +1 -0
- package/dist/codegen/generators/command-file.mjs +130 -0
- package/dist/codegen/generators/command-file.mjs.map +1 -0
- package/dist/codegen/generators/command-tree.d.mts +17 -0
- package/dist/codegen/generators/command-tree.d.mts.map +1 -0
- package/dist/codegen/generators/command-tree.mjs +72 -0
- package/dist/codegen/generators/command-tree.mjs.map +1 -0
- package/dist/codegen/index.d.mts +15 -330
- package/dist/codegen/index.mjs +13 -1507
- package/dist/codegen/parsers/bash.d.mts +19 -0
- package/dist/codegen/parsers/bash.d.mts.map +1 -0
- package/dist/codegen/parsers/bash.mjs +112 -0
- package/dist/codegen/parsers/bash.mjs.map +1 -0
- package/dist/codegen/parsers/fish.d.mts +13 -0
- package/dist/codegen/parsers/fish.d.mts.map +1 -0
- package/dist/codegen/parsers/fish.mjs +108 -0
- package/dist/codegen/parsers/fish.mjs.map +1 -0
- package/dist/codegen/parsers/help.d.mts +15 -0
- package/dist/codegen/parsers/help.d.mts.map +1 -0
- package/dist/codegen/parsers/help.mjs +271 -0
- package/dist/codegen/parsers/help.mjs.map +1 -0
- package/dist/codegen/parsers/merge.d.mts +14 -0
- package/dist/codegen/parsers/merge.d.mts.map +1 -0
- package/dist/codegen/parsers/merge.mjs +76 -0
- package/dist/codegen/parsers/merge.mjs.map +1 -0
- package/dist/codegen/parsers/zsh.d.mts +16 -0
- package/dist/codegen/parsers/zsh.d.mts.map +1 -0
- package/dist/codegen/parsers/zsh.mjs +161 -0
- package/dist/codegen/parsers/zsh.mjs.map +1 -0
- package/dist/codegen/schema-to-code.d.mts +24 -0
- package/dist/codegen/schema-to-code.d.mts.map +1 -0
- package/dist/codegen/schema-to-code.mjs +147 -0
- package/dist/codegen/schema-to-code.mjs.map +1 -0
- package/dist/codegen/template.d.mts +18 -0
- package/dist/codegen/template.d.mts.map +1 -0
- package/dist/codegen/template.mjs +37 -0
- package/dist/codegen/template.mjs.map +1 -0
- package/dist/codegen/types.d.mts +144 -0
- package/dist/codegen/types.d.mts.map +1 -0
- package/dist/completion.d.mts +2 -0
- package/dist/completion.mjs +2 -0
- package/dist/core/args.d.mts +3 -0
- package/dist/{args-DrCXxXeP.mjs → core/args.mjs} +49 -113
- package/dist/core/args.mjs.map +1 -0
- package/dist/core/commands.d.mts +13 -0
- package/dist/core/commands.d.mts.map +1 -0
- package/dist/{commands-DLR0rFgq.mjs → core/commands.mjs} +4 -232
- package/dist/core/commands.mjs.map +1 -0
- package/dist/core/create.d.mts +63 -0
- package/dist/core/create.d.mts.map +1 -0
- package/dist/core/create.mjs +230 -0
- package/dist/core/create.mjs.map +1 -0
- package/dist/core/default-runtime.mjs +198 -0
- package/dist/core/default-runtime.mjs.map +1 -0
- package/dist/core/errors.d.mts +107 -0
- package/dist/core/errors.d.mts.map +1 -0
- package/dist/{errors-DA4KzK1M.mjs → core/errors.mjs} +2 -2
- package/dist/core/errors.mjs.map +1 -0
- package/dist/core/exec.mjs +191 -0
- package/dist/core/exec.mjs.map +1 -0
- package/dist/core/interceptors.d.mts +33 -0
- package/dist/core/interceptors.d.mts.map +1 -0
- package/dist/core/interceptors.mjs +253 -0
- package/dist/core/interceptors.mjs.map +1 -0
- package/dist/core/parse.mjs +181 -0
- package/dist/core/parse.mjs.map +1 -0
- package/dist/core/program-methods.mjs +256 -0
- package/dist/core/program-methods.mjs.map +1 -0
- package/dist/core/results.d.mts +13 -0
- package/dist/core/results.d.mts.map +1 -0
- package/dist/core/results.mjs +150 -0
- package/dist/core/results.mjs.map +1 -0
- package/dist/core/runtime.d.mts +213 -0
- package/dist/core/runtime.d.mts.map +1 -0
- package/dist/core/runtime.mjs +10 -0
- package/dist/core/runtime.mjs.map +1 -0
- package/dist/core/validate.mjs +220 -0
- package/dist/core/validate.mjs.map +1 -0
- package/dist/docs/index.d.mts +1 -1
- package/dist/docs/index.d.mts.map +1 -1
- package/dist/docs/index.mjs +2 -2
- package/dist/docs/index.mjs.map +1 -1
- package/dist/extension/auto-output.d.mts +53 -0
- package/dist/extension/auto-output.d.mts.map +1 -0
- package/dist/extension/auto-output.mjs +116 -0
- package/dist/extension/auto-output.mjs.map +1 -0
- package/dist/extension/color.d.mts +19 -0
- package/dist/extension/color.d.mts.map +1 -0
- package/dist/extension/color.mjs +37 -0
- package/dist/extension/color.mjs.map +1 -0
- package/dist/extension/completion.d.mts +25 -0
- package/dist/extension/completion.d.mts.map +1 -0
- package/dist/extension/completion.mjs +40 -0
- package/dist/extension/completion.mjs.map +1 -0
- package/dist/extension/config.d.mts +55 -0
- package/dist/extension/config.d.mts.map +1 -0
- package/dist/extension/config.mjs +162 -0
- package/dist/extension/config.mjs.map +1 -0
- package/dist/extension/env.d.mts +42 -0
- package/dist/extension/env.d.mts.map +1 -0
- package/dist/extension/env.mjs +44 -0
- package/dist/extension/env.mjs.map +1 -0
- package/dist/extension/help.d.mts +29 -0
- package/dist/extension/help.d.mts.map +1 -0
- package/dist/extension/help.mjs +161 -0
- package/dist/extension/help.mjs.map +1 -0
- package/dist/extension/index.d.mts +18 -0
- package/dist/extension/ink.d.mts +31 -0
- package/dist/extension/ink.d.mts.map +1 -0
- package/dist/extension/ink.mjs +69 -0
- package/dist/extension/ink.mjs.map +1 -0
- package/dist/extension/interactive.d.mts +16 -0
- package/dist/extension/interactive.d.mts.map +1 -0
- package/dist/extension/interactive.mjs +89 -0
- package/dist/extension/interactive.mjs.map +1 -0
- package/dist/extension/logger.d.mts +67 -0
- package/dist/extension/logger.d.mts.map +1 -0
- package/dist/extension/logger.mjs +188 -0
- package/dist/extension/logger.mjs.map +1 -0
- package/dist/extension/man.d.mts +25 -0
- package/dist/extension/man.d.mts.map +1 -0
- package/dist/extension/man.mjs +41 -0
- package/dist/extension/man.mjs.map +1 -0
- package/dist/extension/mcp.d.mts +28 -0
- package/dist/extension/mcp.d.mts.map +1 -0
- package/dist/extension/mcp.mjs +44 -0
- package/dist/extension/mcp.mjs.map +1 -0
- package/dist/extension/progress-renderer.d.mts +13 -0
- package/dist/extension/progress-renderer.d.mts.map +1 -0
- package/dist/extension/progress-renderer.mjs +351 -0
- package/dist/extension/progress-renderer.mjs.map +1 -0
- package/dist/extension/progress.d.mts +76 -0
- package/dist/extension/progress.d.mts.map +1 -0
- package/dist/extension/progress.mjs +225 -0
- package/dist/extension/progress.mjs.map +1 -0
- package/dist/extension/repl.d.mts +26 -0
- package/dist/extension/repl.d.mts.map +1 -0
- package/dist/extension/repl.mjs +67 -0
- package/dist/extension/repl.mjs.map +1 -0
- package/dist/extension/serve.d.mts +27 -0
- package/dist/extension/serve.d.mts.map +1 -0
- package/dist/extension/serve.mjs +41 -0
- package/dist/extension/serve.mjs.map +1 -0
- package/dist/extension/signal.d.mts +19 -0
- package/dist/extension/signal.d.mts.map +1 -0
- package/dist/extension/signal.mjs +81 -0
- package/dist/extension/signal.mjs.map +1 -0
- package/dist/extension/stdin.d.mts +19 -0
- package/dist/extension/stdin.d.mts.map +1 -0
- package/dist/extension/stdin.mjs +52 -0
- package/dist/extension/stdin.mjs.map +1 -0
- package/dist/extension/suggestions.d.mts +6 -0
- package/dist/extension/suggestions.d.mts.map +1 -0
- package/dist/extension/suggestions.mjs +113 -0
- package/dist/extension/suggestions.mjs.map +1 -0
- package/dist/extension/timing.d.mts +27 -0
- package/dist/extension/timing.d.mts.map +1 -0
- package/dist/extension/timing.mjs +71 -0
- package/dist/extension/timing.mjs.map +1 -0
- package/dist/extension/tracing.d.mts +85 -0
- package/dist/extension/tracing.d.mts.map +1 -0
- package/dist/extension/tracing.mjs +107 -0
- package/dist/extension/tracing.mjs.map +1 -0
- package/dist/extension/update-check.d.mts +20 -0
- package/dist/extension/update-check.d.mts.map +1 -0
- package/dist/extension/update-check.mjs +62 -0
- package/dist/extension/update-check.mjs.map +1 -0
- package/dist/extension/utils.mjs +43 -0
- package/dist/extension/utils.mjs.map +1 -0
- package/dist/extension/version.d.mts +20 -0
- package/dist/extension/version.d.mts.map +1 -0
- package/dist/extension/version.mjs +51 -0
- package/dist/extension/version.mjs.map +1 -0
- package/dist/{completion-UnBKfGuk.mjs → feature/completion.mjs} +4 -3
- package/dist/feature/completion.mjs.map +1 -0
- package/dist/feature/interactive.mjs +145 -0
- package/dist/feature/interactive.mjs.map +1 -0
- package/dist/feature/mcp.d.mts +18 -0
- package/dist/feature/mcp.d.mts.map +1 -0
- package/dist/{mcp-D6PdtjIs.mjs → feature/mcp.mjs} +6 -6
- package/dist/feature/mcp.mjs.map +1 -0
- package/dist/feature/repl-loop.mjs +217 -0
- package/dist/feature/repl-loop.mjs.map +1 -0
- package/dist/feature/serve.d.mts +18 -0
- package/dist/feature/serve.d.mts.map +1 -0
- package/dist/{serve-PaCLsNoD.mjs → feature/serve.mjs} +7 -7
- package/dist/feature/serve.mjs.map +1 -0
- package/dist/feature/test.d.mts +109 -0
- package/dist/feature/test.d.mts.map +1 -0
- package/dist/feature/test.mjs +116 -0
- package/dist/feature/test.mjs.map +1 -0
- package/dist/feature/update-check.d.mts +35 -0
- package/dist/feature/update-check.d.mts.map +1 -0
- package/dist/{update-check-CZ2VqjnV.mjs → feature/update-check.mjs} +2 -2
- package/dist/feature/update-check.mjs.map +1 -0
- package/dist/feature/wrap.d.mts +58 -0
- package/dist/feature/wrap.d.mts.map +1 -0
- package/dist/feature/wrap.mjs +77 -0
- package/dist/feature/wrap.mjs.map +1 -0
- package/dist/index.d.mts +38 -901
- package/dist/index.mjs +25 -4337
- package/dist/ink.d.mts +2 -0
- package/dist/ink.mjs +2 -0
- package/dist/man.d.mts +2 -0
- package/dist/man.mjs +2 -0
- package/dist/mcp.d.mts +3 -0
- package/dist/mcp.mjs +2 -0
- package/dist/output/colorizer.d.mts +28 -0
- package/dist/output/colorizer.d.mts.map +1 -0
- package/dist/output/colorizer.mjs +94 -0
- package/dist/output/colorizer.mjs.map +1 -0
- package/dist/{formatter-CY3KrOEd.d.mts → output/formatter.d.mts} +2 -28
- package/dist/output/formatter.d.mts.map +1 -0
- package/dist/output/formatter.mjs +360 -0
- package/dist/output/formatter.mjs.map +1 -0
- package/dist/output/help.d.mts +18 -0
- package/dist/output/help.d.mts.map +1 -0
- package/dist/output/help.mjs +267 -0
- package/dist/output/help.mjs.map +1 -0
- package/dist/output/output-indicator.d.mts +27 -0
- package/dist/output/output-indicator.d.mts.map +1 -0
- package/dist/output/output-indicator.mjs +54 -0
- package/dist/output/output-indicator.mjs.map +1 -0
- package/dist/output/primitives.d.mts +33 -0
- package/dist/output/primitives.d.mts.map +1 -0
- package/dist/output/primitives.mjs +206 -0
- package/dist/output/primitives.mjs.map +1 -0
- package/dist/output/styling.d.mts +38 -0
- package/dist/output/styling.d.mts.map +1 -0
- package/dist/output/styling.mjs +146 -0
- package/dist/output/styling.mjs.map +1 -0
- package/dist/schema/zod.d.mts +6 -0
- package/dist/schema/zod.d.mts.map +1 -0
- package/dist/schema/zod.mjs +50 -0
- package/dist/schema/zod.mjs.map +1 -0
- package/dist/serve.d.mts +2 -0
- package/dist/serve.mjs +2 -0
- package/dist/test.d.mts +2 -109
- package/dist/test.mjs +1 -115
- package/dist/tracing.d.mts +2 -0
- package/dist/tracing.mjs +2 -0
- package/dist/types/args-meta.d.mts +129 -0
- package/dist/types/args-meta.d.mts.map +1 -0
- package/dist/types/builder.d.mts +212 -0
- package/dist/types/builder.d.mts.map +1 -0
- package/dist/types/command.d.mts +112 -0
- package/dist/types/command.d.mts.map +1 -0
- package/dist/types/index.d.mts +8 -0
- package/dist/types/interceptor.d.mts +232 -0
- package/dist/types/interceptor.d.mts.map +1 -0
- package/dist/types/preferences.d.mts +79 -0
- package/dist/types/preferences.d.mts.map +1 -0
- package/dist/types/result.d.mts +61 -0
- package/dist/types/result.d.mts.map +1 -0
- package/dist/types/schema.d.mts +24 -0
- package/dist/types/schema.d.mts.map +1 -0
- package/dist/util/dotenv.mjs +174 -0
- package/dist/util/dotenv.mjs.map +1 -0
- package/dist/util/shell-utils.mjs +80 -0
- package/dist/util/shell-utils.mjs.map +1 -0
- package/dist/util/stream.d.mts +33 -0
- package/dist/util/stream.d.mts.map +1 -0
- package/dist/{stream-DC4H8YTx.mjs → util/stream.mjs} +2 -2
- package/dist/util/stream.mjs.map +1 -0
- package/dist/util/type-helpers.d.mts +74 -0
- package/dist/util/type-helpers.d.mts.map +1 -0
- package/dist/util/type-utils.d.mts +186 -0
- package/dist/util/type-utils.d.mts.map +1 -0
- package/dist/util/utils.mjs +43 -0
- package/dist/util/utils.mjs.map +1 -0
- package/dist/zod.d.mts +1 -32
- package/dist/zod.mjs +1 -49
- package/package.json +65 -17
- package/src/completion.ts +2 -0
- package/src/core/args.ts +63 -37
- package/src/core/runtime.ts +11 -2
- package/src/extension/completion.ts +3 -0
- package/src/extension/index.ts +0 -12
- package/src/extension/ink.ts +2 -1
- package/src/extension/man.ts +3 -0
- package/src/extension/mcp.ts +3 -0
- package/src/extension/progress-renderer.ts +32 -8
- package/src/extension/progress.ts +19 -9
- package/src/extension/serve.ts +3 -0
- package/src/extension/tracing.ts +2 -0
- package/src/index.ts +1 -20
- package/src/ink.ts +2 -0
- package/src/man.ts +2 -0
- package/src/mcp.ts +3 -0
- package/src/serve.ts +2 -0
- package/src/tracing.ts +9 -0
- package/src/types/builder.ts +2 -2
- package/src/zod.ts +1 -1
- package/dist/args-DrCXxXeP.mjs.map +0 -1
- package/dist/codegen/index.d.mts.map +0 -1
- package/dist/codegen/index.mjs.map +0 -1
- package/dist/commands-DLR0rFgq.mjs.map +0 -1
- package/dist/completion-UnBKfGuk.mjs.map +0 -1
- package/dist/errors-DA4KzK1M.mjs.map +0 -1
- package/dist/formatter-CY3KrOEd.d.mts.map +0 -1
- package/dist/help-B-ZMYyn-.mjs +0 -892
- package/dist/help-B-ZMYyn-.mjs.map +0 -1
- package/dist/index-D-Dpz7l_.d.mts +0 -1427
- package/dist/index-D-Dpz7l_.d.mts.map +0 -1
- package/dist/index.d.mts.map +0 -1
- package/dist/index.mjs.map +0 -1
- package/dist/mcp-D6PdtjIs.mjs.map +0 -1
- package/dist/serve-PaCLsNoD.mjs.map +0 -1
- package/dist/stream-DC4H8YTx.mjs.map +0 -1
- package/dist/test.d.mts.map +0 -1
- package/dist/test.mjs.map +0 -1
- package/dist/update-check-CZ2VqjnV.mjs.map +0 -1
- package/dist/zod.d.mts.map +0 -1
- package/dist/zod.mjs.map +0 -1
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { escapeHtml } from "./styling.mjs";
|
|
2
|
+
//#region src/output/primitives.ts
|
|
3
|
+
function stringifyCell(value) {
|
|
4
|
+
if (value === void 0 || value === null) return "";
|
|
5
|
+
if (typeof value === "string") return value;
|
|
6
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
7
|
+
return JSON.stringify(value);
|
|
8
|
+
}
|
|
9
|
+
function truncate(text, max) {
|
|
10
|
+
if (max <= 0 || text.length <= max) return text;
|
|
11
|
+
return max <= 1 ? "…" : `${text.slice(0, max - 1)}…`;
|
|
12
|
+
}
|
|
13
|
+
function padCell(text, width, alignment = "left") {
|
|
14
|
+
const pad = width - text.length;
|
|
15
|
+
if (pad <= 0) return text;
|
|
16
|
+
if (alignment === "right") return " ".repeat(pad) + text;
|
|
17
|
+
if (alignment === "center") {
|
|
18
|
+
const left = Math.floor(pad / 2);
|
|
19
|
+
return " ".repeat(left) + text + " ".repeat(pad - left);
|
|
20
|
+
}
|
|
21
|
+
return text + " ".repeat(pad);
|
|
22
|
+
}
|
|
23
|
+
function renderTable(data, options, ctx) {
|
|
24
|
+
if (data.length === 0) return "";
|
|
25
|
+
if (ctx.format === "json") return JSON.stringify(data, null, 2);
|
|
26
|
+
const columns = options?.columns ?? Object.keys(data[0]);
|
|
27
|
+
if (columns.length === 0) return "";
|
|
28
|
+
const headers = columns.map((col) => options?.headers?.[col] ?? col);
|
|
29
|
+
const maxCol = options?.maxColumnWidth;
|
|
30
|
+
const rows = data.map((row) => columns.map((col) => {
|
|
31
|
+
const text = stringifyCell(row[col]);
|
|
32
|
+
return maxCol ? truncate(text, maxCol) : text;
|
|
33
|
+
}));
|
|
34
|
+
const colWidths = columns.map((_, i) => {
|
|
35
|
+
const headerWidth = headers[i].length;
|
|
36
|
+
const maxCellWidth = rows.reduce((max, row) => Math.max(max, row[i].length), 0);
|
|
37
|
+
return Math.max(headerWidth, maxCellWidth);
|
|
38
|
+
});
|
|
39
|
+
const getAlign = (i) => options?.align?.[columns[i]] ?? "left";
|
|
40
|
+
if (ctx.format === "markdown") return renderTableMarkdown(headers, rows, colWidths, getAlign);
|
|
41
|
+
if (ctx.format === "html") return renderTableHtml(columns, headers, rows, data, getAlign);
|
|
42
|
+
return renderTableText(headers, rows, colWidths, getAlign, options?.border !== false, ctx);
|
|
43
|
+
}
|
|
44
|
+
function renderTableText(headers, rows, colWidths, getAlign, border, ctx) {
|
|
45
|
+
const { styler } = ctx;
|
|
46
|
+
const formatRow = (cells, style) => cells.map((cell, i) => {
|
|
47
|
+
const padded = padCell(cell, colWidths[i], getAlign(i));
|
|
48
|
+
return style ? style(padded) : padded;
|
|
49
|
+
});
|
|
50
|
+
if (border) {
|
|
51
|
+
const sep = ctx.styler.meta("─");
|
|
52
|
+
const divider = colWidths.map((w) => sep.repeat(w + 2)).join(styler.meta("┼"));
|
|
53
|
+
const row = (cells) => cells.map((c, i) => ` ${padCell(c, colWidths[i], getAlign(i))} `).join(styler.meta("│"));
|
|
54
|
+
const headerRow = row(headers.map((h) => styler.label(h)));
|
|
55
|
+
const dataRows = rows.map((r) => row(r.map((c) => styler.description(c))));
|
|
56
|
+
return [
|
|
57
|
+
headerRow,
|
|
58
|
+
styler.meta("─") + divider + styler.meta("─"),
|
|
59
|
+
...dataRows
|
|
60
|
+
].join("\n");
|
|
61
|
+
}
|
|
62
|
+
const headerCells = formatRow(headers, styler.label);
|
|
63
|
+
const dataCells = rows.map((r) => formatRow(r, styler.description));
|
|
64
|
+
const gap = " ";
|
|
65
|
+
return [headerCells.join(gap), ...dataCells.map((r) => r.join(gap))].join("\n");
|
|
66
|
+
}
|
|
67
|
+
function renderTableMarkdown(headers, rows, colWidths, getAlign) {
|
|
68
|
+
return [
|
|
69
|
+
`| ${headers.map((h, i) => padCell(h, colWidths[i], "left")).join(" | ")} |`,
|
|
70
|
+
"| " + colWidths.map((w, i) => {
|
|
71
|
+
const a = getAlign(i);
|
|
72
|
+
const dashes = "─".repeat(Math.max(w, 3));
|
|
73
|
+
if (a === "center") return `:${dashes}:`;
|
|
74
|
+
if (a === "right") return `${dashes}:`;
|
|
75
|
+
return dashes;
|
|
76
|
+
}).join(" | ") + " |",
|
|
77
|
+
...rows.map((r) => `| ${r.map((c, i) => padCell(c, colWidths[i], "left")).join(" | ")} |`)
|
|
78
|
+
].join("\n");
|
|
79
|
+
}
|
|
80
|
+
function renderTableHtml(columns, headers, _rows, data, getAlign) {
|
|
81
|
+
const ths = headers.map((h, i) => {
|
|
82
|
+
const a = getAlign(i);
|
|
83
|
+
return `<th${a !== "left" ? ` style="text-align: ${a};"` : ""}>${escapeHtml(h)}</th>`;
|
|
84
|
+
});
|
|
85
|
+
const trs = data.map((row) => "<tr>" + columns.map((col, i) => {
|
|
86
|
+
const a = getAlign(i);
|
|
87
|
+
return `<td${a !== "left" ? ` style="text-align: ${a};"` : ""}>${escapeHtml(stringifyCell(row[col]))}</td>`;
|
|
88
|
+
}).join("") + "</tr>");
|
|
89
|
+
return `<table><thead><tr>${ths.join("")}</tr></thead><tbody>${trs.join("")}</tbody></table>`;
|
|
90
|
+
}
|
|
91
|
+
function renderTree(data, options, ctx) {
|
|
92
|
+
const nodes = Array.isArray(data) ? data : [data];
|
|
93
|
+
if (nodes.length === 0) return "";
|
|
94
|
+
if (ctx.format === "json") return JSON.stringify(nodes, null, 2);
|
|
95
|
+
if (ctx.format === "markdown") return renderTreeMarkdown(nodes, 0);
|
|
96
|
+
if (ctx.format === "html") return renderTreeHtml(nodes);
|
|
97
|
+
return renderTreeText(nodes, "", options?.guides !== false, ctx).join("\n");
|
|
98
|
+
}
|
|
99
|
+
function renderTreeText(nodes, prefix, guides, ctx) {
|
|
100
|
+
const lines = [];
|
|
101
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
102
|
+
const node = nodes[i];
|
|
103
|
+
const isLast = i === nodes.length - 1;
|
|
104
|
+
if (guides) {
|
|
105
|
+
const connector = isLast ? "└── " : "├── ";
|
|
106
|
+
const childPrefix = isLast ? " " : "│ ";
|
|
107
|
+
lines.push(prefix + ctx.styler.meta(connector) + ctx.styler.label(node.label));
|
|
108
|
+
if (node.children?.length) lines.push(...renderTreeText(node.children, prefix + ctx.styler.meta(childPrefix), guides, ctx));
|
|
109
|
+
} else {
|
|
110
|
+
const indent = prefix ? `${prefix} ` : "";
|
|
111
|
+
lines.push(indent + ctx.styler.label(node.label));
|
|
112
|
+
if (node.children?.length) lines.push(...renderTreeText(node.children, indent, guides, ctx));
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return lines;
|
|
116
|
+
}
|
|
117
|
+
function renderTreeMarkdown(nodes, depth) {
|
|
118
|
+
return nodes.map((node) => {
|
|
119
|
+
const line = `${" ".repeat(depth)}- ${node.label}`;
|
|
120
|
+
if (!node.children?.length) return line;
|
|
121
|
+
return `${line}\n${renderTreeMarkdown(node.children, depth + 1)}`;
|
|
122
|
+
}).join("\n");
|
|
123
|
+
}
|
|
124
|
+
function renderTreeHtml(nodes) {
|
|
125
|
+
return `<ul>${nodes.map((node) => {
|
|
126
|
+
const label = escapeHtml(node.label);
|
|
127
|
+
if (!node.children?.length) return `<li>${label}</li>`;
|
|
128
|
+
return `<li>${label}${renderTreeHtml(node.children)}</li>`;
|
|
129
|
+
}).join("")}</ul>`;
|
|
130
|
+
}
|
|
131
|
+
function renderList(data, options, ctx) {
|
|
132
|
+
if (data.length === 0) return "";
|
|
133
|
+
if (ctx.format === "json") {
|
|
134
|
+
const normalized = data.map((item) => typeof item === "string" ? { label: item } : item);
|
|
135
|
+
return JSON.stringify(normalized, null, 2);
|
|
136
|
+
}
|
|
137
|
+
if (ctx.format === "markdown") return renderListMarkdown(data, options);
|
|
138
|
+
if (ctx.format === "html") return renderListHtml(data, options);
|
|
139
|
+
return renderListText(data, options, ctx);
|
|
140
|
+
}
|
|
141
|
+
function renderListText(data, options, ctx) {
|
|
142
|
+
const { styler } = ctx;
|
|
143
|
+
const numbered = options?.numbered ?? false;
|
|
144
|
+
const bullet = options?.bullet ?? (ctx.format === "ansi" ? "•" : "-");
|
|
145
|
+
const baseIndent = " ".repeat(options?.indent ?? 0);
|
|
146
|
+
return data.map((item, i) => {
|
|
147
|
+
const prefix = numbered ? `${i + 1}.` : bullet;
|
|
148
|
+
const label = typeof item === "string" ? item : item.label;
|
|
149
|
+
const desc = typeof item === "object" && item.description ? item.description : void 0;
|
|
150
|
+
const line = `${baseIndent}${styler.meta(prefix)} ${styler.label(label)}`;
|
|
151
|
+
if (!desc) return line;
|
|
152
|
+
return `${line} ${styler.description(desc)}`;
|
|
153
|
+
}).join("\n");
|
|
154
|
+
}
|
|
155
|
+
function renderListMarkdown(data, options) {
|
|
156
|
+
const numbered = options?.numbered ?? false;
|
|
157
|
+
return data.map((item, i) => {
|
|
158
|
+
const prefix = numbered ? `${i + 1}.` : "-";
|
|
159
|
+
const label = typeof item === "string" ? item : item.label;
|
|
160
|
+
const desc = typeof item === "object" && item.description ? item.description : void 0;
|
|
161
|
+
if (!desc) return `${prefix} ${label}`;
|
|
162
|
+
return `${prefix} **${label}** — ${desc}`;
|
|
163
|
+
}).join("\n");
|
|
164
|
+
}
|
|
165
|
+
function renderListHtml(data, options) {
|
|
166
|
+
const tag = options?.numbered ? "ol" : "ul";
|
|
167
|
+
return `<${tag}>${data.map((item) => {
|
|
168
|
+
const label = typeof item === "string" ? item : item.label;
|
|
169
|
+
const desc = typeof item === "object" && item.description ? item.description : void 0;
|
|
170
|
+
if (!desc) return `<li>${escapeHtml(label)}</li>`;
|
|
171
|
+
return `<li><strong>${escapeHtml(label)}</strong> — ${escapeHtml(desc)}</li>`;
|
|
172
|
+
}).join("")}</${tag}>`;
|
|
173
|
+
}
|
|
174
|
+
function renderKeyValue(data, options, ctx) {
|
|
175
|
+
const entries = Object.entries(data);
|
|
176
|
+
if (entries.length === 0) return "";
|
|
177
|
+
if (ctx.format === "json") return JSON.stringify(data, null, 2);
|
|
178
|
+
if (ctx.format === "markdown") return renderKeyValueMarkdown(entries, options);
|
|
179
|
+
if (ctx.format === "html") return renderKeyValueHtml(entries, options);
|
|
180
|
+
return renderKeyValueText(entries, options, ctx);
|
|
181
|
+
}
|
|
182
|
+
function getLabel(key, labels) {
|
|
183
|
+
return labels?.[key] ?? key;
|
|
184
|
+
}
|
|
185
|
+
function renderKeyValueText(entries, options, ctx) {
|
|
186
|
+
const { styler } = ctx;
|
|
187
|
+
const sep = options?.separator ?? ": ";
|
|
188
|
+
const shouldAlign = options?.align !== false;
|
|
189
|
+
const displayLabels = entries.map(([k]) => getLabel(k, options?.labels));
|
|
190
|
+
const maxWidth = shouldAlign ? Math.max(...displayLabels.map((l) => l.length)) : 0;
|
|
191
|
+
return entries.map(([_key, value], i) => {
|
|
192
|
+
const label = displayLabels[i];
|
|
193
|
+
const paddedLabel = shouldAlign ? label + " ".repeat(maxWidth - label.length) : label;
|
|
194
|
+
return `${styler.label(paddedLabel)}${styler.meta(sep)}${styler.description(stringifyCell(value))}`;
|
|
195
|
+
}).join("\n");
|
|
196
|
+
}
|
|
197
|
+
function renderKeyValueMarkdown(entries, options) {
|
|
198
|
+
return entries.map(([key, value]) => `- **${getLabel(key, options?.labels)}**: ${stringifyCell(value)}`).join("\n");
|
|
199
|
+
}
|
|
200
|
+
function renderKeyValueHtml(entries, options) {
|
|
201
|
+
return `<dl>${entries.map(([key, value]) => `<dt>${escapeHtml(getLabel(key, options?.labels))}</dt><dd>${escapeHtml(stringifyCell(value))}</dd>`).join("")}</dl>`;
|
|
202
|
+
}
|
|
203
|
+
//#endregion
|
|
204
|
+
export { renderKeyValue, renderList, renderTable, renderTree };
|
|
205
|
+
|
|
206
|
+
//# sourceMappingURL=primitives.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"primitives.mjs","names":[],"sources":["../../src/output/primitives.ts"],"sourcesContent":["import { escapeHtml, type OutputContext } from './styling.ts';\n\n// ── Table ───────────────────────────────────────────────────────────────\n\nexport type TableOptions = {\n /** Explicit column keys to display (default: infer from first row's keys). */\n columns?: string[];\n /** Column key → display header name mapping. */\n headers?: Record<string, string>;\n /** Column key → text alignment. */\n align?: Record<string, 'left' | 'right' | 'center'>;\n /** Maximum column width before truncation. */\n maxColumnWidth?: number;\n /** Show borders (default: true for ansi/text, false for others). */\n border?: boolean;\n};\n\nfunction stringifyCell(value: unknown): string {\n if (value === undefined || value === null) return '';\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n return JSON.stringify(value);\n}\n\nfunction truncate(text: string, max: number): string {\n if (max <= 0 || text.length <= max) return text;\n return max <= 1 ? '…' : `${text.slice(0, max - 1)}…`;\n}\n\nfunction padCell(text: string, width: number, alignment: 'left' | 'right' | 'center' = 'left'): string {\n const pad = width - text.length;\n if (pad <= 0) return text;\n if (alignment === 'right') return ' '.repeat(pad) + text;\n if (alignment === 'center') {\n const left = Math.floor(pad / 2);\n return ' '.repeat(left) + text + ' '.repeat(pad - left);\n }\n return text + ' '.repeat(pad);\n}\n\nexport function renderTable(data: Record<string, unknown>[], options: TableOptions | undefined, ctx: OutputContext): string {\n if (data.length === 0) return '';\n if (ctx.format === 'json') return JSON.stringify(data, null, 2);\n\n const columns = options?.columns ?? Object.keys(data[0]!);\n if (columns.length === 0) return '';\n\n const headers = columns.map((col) => options?.headers?.[col] ?? col);\n const maxCol = options?.maxColumnWidth;\n\n const rows = data.map((row) =>\n columns.map((col) => {\n const text = stringifyCell(row[col]);\n return maxCol ? truncate(text, maxCol) : text;\n }),\n );\n\n const colWidths = columns.map((_, i) => {\n const headerWidth = headers[i]!.length;\n const maxCellWidth = rows.reduce((max, row) => Math.max(max, row[i]!.length), 0);\n return Math.max(headerWidth, maxCellWidth);\n });\n\n const getAlign = (i: number): 'left' | 'right' | 'center' => options?.align?.[columns[i]!] ?? 'left';\n\n if (ctx.format === 'markdown') return renderTableMarkdown(headers, rows, colWidths, getAlign);\n if (ctx.format === 'html') return renderTableHtml(columns, headers, rows, data, getAlign);\n return renderTableText(headers, rows, colWidths, getAlign, options?.border !== false, ctx);\n}\n\nfunction renderTableText(\n headers: string[],\n rows: string[][],\n colWidths: number[],\n getAlign: (i: number) => 'left' | 'right' | 'center',\n border: boolean,\n ctx: OutputContext,\n): string {\n const { styler } = ctx;\n const formatRow = (cells: string[], style?: (s: string) => string) =>\n cells.map((cell, i) => {\n const padded = padCell(cell, colWidths[i]!, getAlign(i));\n return style ? style(padded) : padded;\n });\n\n if (border) {\n const sep = ctx.styler.meta('─');\n const divider = colWidths.map((w) => sep.repeat(w + 2)).join(styler.meta('┼'));\n const row = (cells: string[]) => cells.map((c, i) => ` ${padCell(c, colWidths[i]!, getAlign(i))} `).join(styler.meta('│'));\n const headerRow = row(headers.map((h) => styler.label(h)));\n const dataRows = rows.map((r) => row(r.map((c) => styler.description(c))));\n return [headerRow, styler.meta('─') + divider + styler.meta('─'), ...dataRows].join('\\n');\n }\n\n const headerCells = formatRow(headers, styler.label);\n const dataCells = rows.map((r) => formatRow(r, styler.description));\n const gap = ' ';\n return [headerCells.join(gap), ...dataCells.map((r) => r.join(gap))].join('\\n');\n}\n\nfunction renderTableMarkdown(\n headers: string[],\n rows: string[][],\n colWidths: number[],\n getAlign: (i: number) => 'left' | 'right' | 'center',\n): string {\n const headerLine = `| ${headers.map((h, i) => padCell(h, colWidths[i]!, 'left')).join(' | ')} |`;\n const separatorLine =\n '| ' +\n colWidths\n .map((w, i) => {\n const a = getAlign(i);\n const dashes = '─'.repeat(Math.max(w, 3));\n if (a === 'center') return `:${dashes}:`;\n if (a === 'right') return `${dashes}:`;\n return dashes;\n })\n .join(' | ') +\n ' |';\n const dataLines = rows.map((r) => `| ${r.map((c, i) => padCell(c, colWidths[i]!, 'left')).join(' | ')} |`);\n return [headerLine, separatorLine, ...dataLines].join('\\n');\n}\n\nfunction renderTableHtml(\n columns: string[],\n headers: string[],\n _rows: string[][],\n data: Record<string, unknown>[],\n getAlign: (i: number) => 'left' | 'right' | 'center',\n): string {\n const ths = headers.map((h, i) => {\n const a = getAlign(i);\n const style = a !== 'left' ? ` style=\"text-align: ${a};\"` : '';\n return `<th${style}>${escapeHtml(h)}</th>`;\n });\n const trs = data.map(\n (row) =>\n '<tr>' +\n columns\n .map((col, i) => {\n const a = getAlign(i);\n const style = a !== 'left' ? ` style=\"text-align: ${a};\"` : '';\n return `<td${style}>${escapeHtml(stringifyCell(row[col]))}</td>`;\n })\n .join('') +\n '</tr>',\n );\n return `<table><thead><tr>${ths.join('')}</tr></thead><tbody>${trs.join('')}</tbody></table>`;\n}\n\n// ── Tree ────────────────────────────────────────────────────────────────\n\nexport type TreeNode = {\n label: string;\n children?: TreeNode[];\n};\n\nexport type TreeOptions = {\n /** Characters per indent level (default: 2). */\n indent?: number;\n /** Show tree guide lines (default: true for ansi/text). */\n guides?: boolean;\n};\n\nexport function renderTree(data: TreeNode | TreeNode[], options: TreeOptions | undefined, ctx: OutputContext): string {\n const nodes = Array.isArray(data) ? data : [data];\n if (nodes.length === 0) return '';\n if (ctx.format === 'json') return JSON.stringify(nodes, null, 2);\n if (ctx.format === 'markdown') return renderTreeMarkdown(nodes, 0);\n if (ctx.format === 'html') return renderTreeHtml(nodes);\n\n const guides = options?.guides !== false;\n return renderTreeText(nodes, '', guides, ctx).join('\\n');\n}\n\nfunction renderTreeText(nodes: TreeNode[], prefix: string, guides: boolean, ctx: OutputContext): string[] {\n const lines: string[] = [];\n for (let i = 0; i < nodes.length; i++) {\n const node = nodes[i]!;\n const isLast = i === nodes.length - 1;\n if (guides) {\n const connector = isLast ? '└── ' : '├── ';\n const childPrefix = isLast ? ' ' : '│ ';\n lines.push(prefix + ctx.styler.meta(connector) + ctx.styler.label(node.label));\n if (node.children?.length) lines.push(...renderTreeText(node.children, prefix + ctx.styler.meta(childPrefix), guides, ctx));\n } else {\n const indent = prefix ? `${prefix} ` : '';\n lines.push(indent + ctx.styler.label(node.label));\n if (node.children?.length) lines.push(...renderTreeText(node.children, indent, guides, ctx));\n }\n }\n return lines;\n}\n\nfunction renderTreeMarkdown(nodes: TreeNode[], depth: number): string {\n return nodes\n .map((node) => {\n const indent = ' '.repeat(depth);\n const line = `${indent}- ${node.label}`;\n if (!node.children?.length) return line;\n return `${line}\\n${renderTreeMarkdown(node.children, depth + 1)}`;\n })\n .join('\\n');\n}\n\nfunction renderTreeHtml(nodes: TreeNode[]): string {\n const items = nodes\n .map((node) => {\n const label = escapeHtml(node.label);\n if (!node.children?.length) return `<li>${label}</li>`;\n return `<li>${label}${renderTreeHtml(node.children)}</li>`;\n })\n .join('');\n return `<ul>${items}</ul>`;\n}\n\n// ── List ────────────────────────────────────────────────────────────────\n\nexport type ListItem = string | { label: string; description?: string };\n\nexport type ListOptions = {\n /** Bullet character (default: '•' for ansi, '-' for text). */\n bullet?: string;\n /** Use numbered list instead of bullets. */\n numbered?: boolean;\n /** Indent level (default: 0). */\n indent?: number;\n};\n\nexport function renderList(data: ListItem[], options: ListOptions | undefined, ctx: OutputContext): string {\n if (data.length === 0) return '';\n if (ctx.format === 'json') {\n const normalized = data.map((item) => (typeof item === 'string' ? { label: item } : item));\n return JSON.stringify(normalized, null, 2);\n }\n if (ctx.format === 'markdown') return renderListMarkdown(data, options);\n if (ctx.format === 'html') return renderListHtml(data, options);\n return renderListText(data, options, ctx);\n}\n\nfunction renderListText(data: ListItem[], options: ListOptions | undefined, ctx: OutputContext): string {\n const { styler } = ctx;\n const numbered = options?.numbered ?? false;\n const bullet = options?.bullet ?? (ctx.format === 'ansi' ? '•' : '-');\n const baseIndent = ' '.repeat(options?.indent ?? 0);\n\n return data\n .map((item, i) => {\n const prefix = numbered ? `${i + 1}.` : bullet;\n const label = typeof item === 'string' ? item : item.label;\n const desc = typeof item === 'object' && item.description ? item.description : undefined;\n const line = `${baseIndent}${styler.meta(prefix)} ${styler.label(label)}`;\n if (!desc) return line;\n return `${line} ${styler.description(desc)}`;\n })\n .join('\\n');\n}\n\nfunction renderListMarkdown(data: ListItem[], options: ListOptions | undefined): string {\n const numbered = options?.numbered ?? false;\n return data\n .map((item, i) => {\n const prefix = numbered ? `${i + 1}.` : '-';\n const label = typeof item === 'string' ? item : item.label;\n const desc = typeof item === 'object' && item.description ? item.description : undefined;\n if (!desc) return `${prefix} ${label}`;\n return `${prefix} **${label}** — ${desc}`;\n })\n .join('\\n');\n}\n\nfunction renderListHtml(data: ListItem[], options: ListOptions | undefined): string {\n const tag = options?.numbered ? 'ol' : 'ul';\n const items = data\n .map((item) => {\n const label = typeof item === 'string' ? item : item.label;\n const desc = typeof item === 'object' && item.description ? item.description : undefined;\n if (!desc) return `<li>${escapeHtml(label)}</li>`;\n return `<li><strong>${escapeHtml(label)}</strong> — ${escapeHtml(desc)}</li>`;\n })\n .join('');\n return `<${tag}>${items}</${tag}>`;\n}\n\n// ── Key-Value ───────────────────────────────────────────────────────────\n\nexport type KeyValueOptions = {\n /** Separator between key and value (default: ': '). */\n separator?: string;\n /** Align values by padding keys to the same width. */\n align?: boolean;\n /** Key → display label mapping. */\n labels?: Record<string, string>;\n};\n\nexport function renderKeyValue(data: Record<string, unknown>, options: KeyValueOptions | undefined, ctx: OutputContext): string {\n const entries = Object.entries(data);\n if (entries.length === 0) return '';\n if (ctx.format === 'json') return JSON.stringify(data, null, 2);\n if (ctx.format === 'markdown') return renderKeyValueMarkdown(entries, options);\n if (ctx.format === 'html') return renderKeyValueHtml(entries, options);\n return renderKeyValueText(entries, options, ctx);\n}\n\nfunction getLabel(key: string, labels?: Record<string, string>): string {\n return labels?.[key] ?? key;\n}\n\nfunction renderKeyValueText(entries: [string, unknown][], options: KeyValueOptions | undefined, ctx: OutputContext): string {\n const { styler } = ctx;\n const sep = options?.separator ?? ': ';\n const shouldAlign = options?.align !== false;\n\n const displayLabels = entries.map(([k]) => getLabel(k, options?.labels));\n const maxWidth = shouldAlign ? Math.max(...displayLabels.map((l) => l.length)) : 0;\n\n return entries\n .map(([_key, value], i) => {\n const label = displayLabels[i]!;\n const paddedLabel = shouldAlign ? label + ' '.repeat(maxWidth - label.length) : label;\n return `${styler.label(paddedLabel)}${styler.meta(sep)}${styler.description(stringifyCell(value))}`;\n })\n .join('\\n');\n}\n\nfunction renderKeyValueMarkdown(entries: [string, unknown][], options: KeyValueOptions | undefined): string {\n return entries.map(([key, value]) => `- **${getLabel(key, options?.labels)}**: ${stringifyCell(value)}`).join('\\n');\n}\n\nfunction renderKeyValueHtml(entries: [string, unknown][], options: KeyValueOptions | undefined): string {\n const items = entries\n .map(([key, value]) => `<dt>${escapeHtml(getLabel(key, options?.labels))}</dt><dd>${escapeHtml(stringifyCell(value))}</dd>`)\n .join('');\n return `<dl>${items}</dl>`;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
//#region src/output/styling.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Styling functions for semantic text roles.
|
|
4
|
+
* Used by formatters to apply visual styles (ANSI, HTML, Markdown, etc.)
|
|
5
|
+
* to different types of content.
|
|
6
|
+
*/
|
|
7
|
+
type Styler = {
|
|
8
|
+
command: (text: string) => string;
|
|
9
|
+
arg: (text: string) => string;
|
|
10
|
+
type: (text: string) => string;
|
|
11
|
+
description: (text: string) => string;
|
|
12
|
+
label: (text: string) => string;
|
|
13
|
+
section: (text: string) => string;
|
|
14
|
+
meta: (text: string) => string;
|
|
15
|
+
example: (text: string) => string;
|
|
16
|
+
exampleValue: (text: string) => string;
|
|
17
|
+
deprecated: (text: string) => string;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Layout configuration for formatters.
|
|
21
|
+
*/
|
|
22
|
+
type LayoutConfig = {
|
|
23
|
+
newline: string;
|
|
24
|
+
indent: (level: number) => string;
|
|
25
|
+
join: (parts: string[]) => string;
|
|
26
|
+
wrapDocument?: (content: string) => string;
|
|
27
|
+
};
|
|
28
|
+
/** Resolved formatting context used by output primitives. */
|
|
29
|
+
type OutputFormat = 'text' | 'ansi' | 'json' | 'markdown' | 'html';
|
|
30
|
+
type OutputContext = {
|
|
31
|
+
format: OutputFormat;
|
|
32
|
+
styler: Styler;
|
|
33
|
+
layout: LayoutConfig;
|
|
34
|
+
terminalWidth?: number;
|
|
35
|
+
};
|
|
36
|
+
//#endregion
|
|
37
|
+
export { LayoutConfig, OutputContext, OutputFormat, Styler };
|
|
38
|
+
//# sourceMappingURL=styling.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styling.d.mts","names":[],"sources":["../../src/output/styling.ts"],"mappings":";;;;;;KAiCY,MAAA;EACV,OAAA,GAAU,IAAA;EACV,GAAA,GAAM,IAAA;EACN,IAAA,GAAO,IAAA;EACP,WAAA,GAAc,IAAA;EACd,KAAA,GAAQ,IAAA;EACR,OAAA,GAAU,IAAA;EACV,IAAA,GAAO,IAAA;EACP,OAAA,GAAU,IAAA;EACV,YAAA,GAAe,IAAA;EACf,UAAA,GAAa,IAAA;AAAA;;;;KAMH,YAAA;EACV,OAAA;EACA,MAAA,GAAS,KAAA;EACT,IAAA,GAAO,KAAA;EACP,YAAA,IAAgB,OAAA;AAAA;;KAiHN,YAAA;AAAA,KAEA,aAAA;EACV,MAAA,EAAQ,YAAA;EACR,MAAA,EAAQ,MAAA;EACR,MAAA,EAAQ,YAAA;EACR,aAAA;AAAA"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { createColorizer } from "./colorizer.mjs";
|
|
2
|
+
function wrapText(text, maxWidth) {
|
|
3
|
+
if (maxWidth <= 0 || text.length <= maxWidth) return [text];
|
|
4
|
+
const words = text.split(" ");
|
|
5
|
+
const lines = [];
|
|
6
|
+
let current = "";
|
|
7
|
+
for (const word of words) if (current && current.length + 1 + word.length > maxWidth) {
|
|
8
|
+
lines.push(current);
|
|
9
|
+
current = word;
|
|
10
|
+
} else current = current ? `${current} ${word}` : word;
|
|
11
|
+
if (current) lines.push(current);
|
|
12
|
+
return lines.length > 0 ? lines : [text];
|
|
13
|
+
}
|
|
14
|
+
function escapeHtml(text) {
|
|
15
|
+
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
16
|
+
}
|
|
17
|
+
function createTextStyler() {
|
|
18
|
+
return {
|
|
19
|
+
command: (text) => text,
|
|
20
|
+
arg: (text) => text,
|
|
21
|
+
type: (text) => text,
|
|
22
|
+
description: (text) => text,
|
|
23
|
+
label: (text) => text,
|
|
24
|
+
section: (text) => text,
|
|
25
|
+
meta: (text) => text,
|
|
26
|
+
example: (text) => text,
|
|
27
|
+
exampleValue: (text) => text,
|
|
28
|
+
deprecated: (text) => text
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function createAnsiStyler(theme) {
|
|
32
|
+
const colorizer = createColorizer(theme);
|
|
33
|
+
return {
|
|
34
|
+
command: colorizer.command,
|
|
35
|
+
arg: colorizer.arg,
|
|
36
|
+
type: colorizer.type,
|
|
37
|
+
description: colorizer.description,
|
|
38
|
+
label: colorizer.label,
|
|
39
|
+
section: colorizer.label,
|
|
40
|
+
meta: colorizer.meta,
|
|
41
|
+
example: colorizer.example,
|
|
42
|
+
exampleValue: colorizer.exampleValue,
|
|
43
|
+
deprecated: colorizer.deprecated
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function createConsoleStyler(theme) {
|
|
47
|
+
return createAnsiStyler(theme);
|
|
48
|
+
}
|
|
49
|
+
function createMarkdownStyler() {
|
|
50
|
+
return {
|
|
51
|
+
command: (text) => `**${text}**`,
|
|
52
|
+
arg: (text) => `\`${text}\``,
|
|
53
|
+
type: (text) => `\`${text}\``,
|
|
54
|
+
description: (text) => text,
|
|
55
|
+
label: (text) => `**${text}**`,
|
|
56
|
+
section: (text) => `### ${text}`,
|
|
57
|
+
meta: (text) => `*${text}*`,
|
|
58
|
+
example: (text) => `**${text}**`,
|
|
59
|
+
exampleValue: (text) => `\`${text}\``,
|
|
60
|
+
deprecated: (text) => `~~${text}~~`
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function createHtmlStyler() {
|
|
64
|
+
return {
|
|
65
|
+
command: (text) => `<strong style="color: #00bcd4;">${escapeHtml(text)}</strong>`,
|
|
66
|
+
arg: (text) => `<code style="color: #4caf50;">${escapeHtml(text)}</code>`,
|
|
67
|
+
type: (text) => `<code style="color: #ff9800;">${escapeHtml(text)}</code>`,
|
|
68
|
+
description: (text) => `<span style="color: #666;">${escapeHtml(text)}</span>`,
|
|
69
|
+
label: (text) => `<strong>${escapeHtml(text)}</strong>`,
|
|
70
|
+
section: (text) => `<h3>${escapeHtml(text)}</h3>`,
|
|
71
|
+
meta: (text) => `<span style="color: #999;">${escapeHtml(text)}</span>`,
|
|
72
|
+
example: (text) => `<strong style="text-decoration: underline;">${escapeHtml(text)}</strong>`,
|
|
73
|
+
exampleValue: (text) => `<em>${escapeHtml(text)}</em>`,
|
|
74
|
+
deprecated: (text) => `<del style="color: #999;">${escapeHtml(text)}</del>`
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
function createTextLayout() {
|
|
78
|
+
return {
|
|
79
|
+
newline: "\n",
|
|
80
|
+
indent: (level) => " ".repeat(level),
|
|
81
|
+
join: (parts) => parts.filter(Boolean).join(" ")
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
function createMarkdownLayout() {
|
|
85
|
+
return {
|
|
86
|
+
newline: "\n\n",
|
|
87
|
+
indent: (level) => {
|
|
88
|
+
if (level === 0) return "";
|
|
89
|
+
if (level === 1) return " ";
|
|
90
|
+
return " ";
|
|
91
|
+
},
|
|
92
|
+
join: (parts) => parts.filter(Boolean).join(" ")
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
function createHtmlLayout() {
|
|
96
|
+
return {
|
|
97
|
+
newline: "<br>",
|
|
98
|
+
indent: (level) => " ".repeat(level),
|
|
99
|
+
join: (parts) => parts.filter(Boolean).join(" "),
|
|
100
|
+
wrapDocument: (content) => `<div style="font-family: monospace; line-height: 1.6;">${content}</div>`
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
function shouldUseAnsi(env, isTTY) {
|
|
104
|
+
if (env?.NO_COLOR) return false;
|
|
105
|
+
if (env?.CI) return false;
|
|
106
|
+
if (typeof isTTY === "boolean") return isTTY;
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
/** Resolve the output format from the runtime and caller context. */
|
|
110
|
+
function resolveOutputFormat(runtime, caller) {
|
|
111
|
+
let format;
|
|
112
|
+
if (caller === "serve" || caller === "mcp" || caller === "tool") format = "json";
|
|
113
|
+
else if (runtime.format && runtime.format !== "auto" && runtime.format !== "console") format = runtime.format;
|
|
114
|
+
else format = shouldUseAnsi(runtime.env(), runtime.terminal?.isTTY) ? "ansi" : "text";
|
|
115
|
+
const terminalWidth = format === "markdown" || format === "html" ? void 0 : runtime.terminal?.columns ?? 80;
|
|
116
|
+
let styler;
|
|
117
|
+
let layout;
|
|
118
|
+
switch (format) {
|
|
119
|
+
case "ansi":
|
|
120
|
+
styler = createAnsiStyler(runtime.theme);
|
|
121
|
+
layout = createTextLayout();
|
|
122
|
+
break;
|
|
123
|
+
case "markdown":
|
|
124
|
+
styler = createMarkdownStyler();
|
|
125
|
+
layout = createMarkdownLayout();
|
|
126
|
+
break;
|
|
127
|
+
case "html":
|
|
128
|
+
styler = createHtmlStyler();
|
|
129
|
+
layout = createHtmlLayout();
|
|
130
|
+
break;
|
|
131
|
+
default:
|
|
132
|
+
styler = createTextStyler();
|
|
133
|
+
layout = createTextLayout();
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
return {
|
|
137
|
+
format,
|
|
138
|
+
styler,
|
|
139
|
+
layout,
|
|
140
|
+
terminalWidth
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
//#endregion
|
|
144
|
+
export { createAnsiStyler, createConsoleStyler, createHtmlLayout, createHtmlStyler, createMarkdownLayout, createMarkdownStyler, createTextLayout, createTextStyler, escapeHtml, resolveOutputFormat, shouldUseAnsi, wrapText };
|
|
145
|
+
|
|
146
|
+
//# sourceMappingURL=styling.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styling.mjs","names":[],"sources":["../../src/output/styling.ts"],"sourcesContent":["import type { PadroneActionContext } from '../types/index.ts';\nimport { type ColorConfig, type ColorTheme, createColorizer } from './colorizer.ts';\n\nexport const DEFAULT_TERMINAL_WIDTH = 80;\n\nexport function wrapText(text: string, maxWidth: number): string[] {\n if (maxWidth <= 0 || text.length <= maxWidth) return [text];\n const words = text.split(' ');\n const lines: string[] = [];\n let current = '';\n for (const word of words) {\n if (current && current.length + 1 + word.length > maxWidth) {\n lines.push(current);\n current = word;\n } else {\n current = current ? `${current} ${word}` : word;\n }\n }\n if (current) lines.push(current);\n return lines.length > 0 ? lines : [text];\n}\n\nexport function escapeHtml(text: string): string {\n return text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"').replace(/'/g, ''');\n}\n\n// ── Styler ──────────────────────────────────────────────────────────────\n\n/**\n * Styling functions for semantic text roles.\n * Used by formatters to apply visual styles (ANSI, HTML, Markdown, etc.)\n * to different types of content.\n */\nexport type Styler = {\n command: (text: string) => string;\n arg: (text: string) => string;\n type: (text: string) => string;\n description: (text: string) => string;\n label: (text: string) => string;\n section: (text: string) => string;\n meta: (text: string) => string;\n example: (text: string) => string;\n exampleValue: (text: string) => string;\n deprecated: (text: string) => string;\n};\n\n/**\n * Layout configuration for formatters.\n */\nexport type LayoutConfig = {\n newline: string;\n indent: (level: number) => string;\n join: (parts: string[]) => string;\n wrapDocument?: (content: string) => string;\n};\n\n// ── Styler Factories ────────────────────────────────────────────────────\n\nexport function createTextStyler(): Styler {\n return {\n command: (text) => text,\n arg: (text) => text,\n type: (text) => text,\n description: (text) => text,\n label: (text) => text,\n section: (text) => text,\n meta: (text) => text,\n example: (text) => text,\n exampleValue: (text) => text,\n deprecated: (text) => text,\n };\n}\n\nexport function createAnsiStyler(theme?: ColorTheme | ColorConfig): Styler {\n const colorizer = createColorizer(theme);\n return {\n command: colorizer.command,\n arg: colorizer.arg,\n type: colorizer.type,\n description: colorizer.description,\n label: colorizer.label,\n section: colorizer.label,\n meta: colorizer.meta,\n example: colorizer.example,\n exampleValue: colorizer.exampleValue,\n deprecated: colorizer.deprecated,\n };\n}\n\nexport function createConsoleStyler(theme?: ColorTheme | ColorConfig): Styler {\n return createAnsiStyler(theme);\n}\n\nexport function createMarkdownStyler(): Styler {\n return {\n command: (text) => `**${text}**`,\n arg: (text) => `\\`${text}\\``,\n type: (text) => `\\`${text}\\``,\n description: (text) => text,\n label: (text) => `**${text}**`,\n section: (text) => `### ${text}`,\n meta: (text) => `*${text}*`,\n example: (text) => `**${text}**`,\n exampleValue: (text) => `\\`${text}\\``,\n deprecated: (text) => `~~${text}~~`,\n };\n}\n\nexport function createHtmlStyler(): Styler {\n return {\n command: (text) => `<strong style=\"color: #00bcd4;\">${escapeHtml(text)}</strong>`,\n arg: (text) => `<code style=\"color: #4caf50;\">${escapeHtml(text)}</code>`,\n type: (text) => `<code style=\"color: #ff9800;\">${escapeHtml(text)}</code>`,\n description: (text) => `<span style=\"color: #666;\">${escapeHtml(text)}</span>`,\n label: (text) => `<strong>${escapeHtml(text)}</strong>`,\n section: (text) => `<h3>${escapeHtml(text)}</h3>`,\n meta: (text) => `<span style=\"color: #999;\">${escapeHtml(text)}</span>`,\n example: (text) => `<strong style=\"text-decoration: underline;\">${escapeHtml(text)}</strong>`,\n exampleValue: (text) => `<em>${escapeHtml(text)}</em>`,\n deprecated: (text) => `<del style=\"color: #999;\">${escapeHtml(text)}</del>`,\n };\n}\n\n// ── Layout Factories ────────────────────────────────────────────────────\n\nexport function createTextLayout(): LayoutConfig {\n return {\n newline: '\\n',\n indent: (level) => ' '.repeat(level),\n join: (parts) => parts.filter(Boolean).join(' '),\n };\n}\n\nexport function createMarkdownLayout(): LayoutConfig {\n return {\n newline: '\\n\\n',\n indent: (level) => {\n if (level === 0) return '';\n if (level === 1) return ' ';\n return ' ';\n },\n join: (parts) => parts.filter(Boolean).join(' '),\n };\n}\n\nexport function createHtmlLayout(): LayoutConfig {\n return {\n newline: '<br>',\n indent: (level) => ' '.repeat(level),\n join: (parts) => parts.filter(Boolean).join(' '),\n wrapDocument: (content) => `<div style=\"font-family: monospace; line-height: 1.6;\">${content}</div>`,\n };\n}\n\n// ── Format Detection ────────────────────────────────────────────────────\n\nexport function shouldUseAnsi(env?: Record<string, string | undefined>, isTTY?: boolean): boolean {\n if (env?.NO_COLOR) return false;\n if (env?.CI) return false;\n if (typeof isTTY === 'boolean') return isTTY;\n return false;\n}\n\n// ── Output Context ──────────────────────────────────────────────────────\n\n/** Resolved formatting context used by output primitives. */\nexport type OutputFormat = 'text' | 'ansi' | 'json' | 'markdown' | 'html';\n\nexport type OutputContext = {\n format: OutputFormat;\n styler: Styler;\n layout: LayoutConfig;\n terminalWidth?: number;\n};\n\n/** Resolve the output format from the runtime and caller context. */\nexport function resolveOutputFormat(\n runtime: {\n format?: string;\n theme?: ColorTheme | ColorConfig;\n terminal?: { columns?: number; isTTY?: boolean };\n env: () => Record<string, string | undefined>;\n },\n caller?: PadroneActionContext['caller'],\n): OutputContext {\n let format: OutputFormat;\n\n if (caller === 'serve' || caller === 'mcp' || caller === 'tool') {\n format = 'json';\n } else if (runtime.format && runtime.format !== 'auto' && runtime.format !== 'console') {\n format = runtime.format as OutputFormat;\n } else {\n format = shouldUseAnsi(runtime.env(), runtime.terminal?.isTTY) ? 'ansi' : 'text';\n }\n\n const terminalWidth = format === 'markdown' || format === 'html' ? undefined : (runtime.terminal?.columns ?? DEFAULT_TERMINAL_WIDTH);\n\n let styler: Styler;\n let layout: LayoutConfig;\n\n switch (format) {\n case 'ansi':\n styler = createAnsiStyler(runtime.theme);\n layout = createTextLayout();\n break;\n case 'markdown':\n styler = createMarkdownStyler();\n layout = createMarkdownLayout();\n break;\n case 'html':\n styler = createHtmlStyler();\n layout = createHtmlLayout();\n break;\n default:\n styler = createTextStyler();\n layout = createTextLayout();\n break;\n }\n\n return { format, styler, layout, terminalWidth };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zod.d.mts","names":["GlobalMeta","PadroneFieldMeta"],"sources":["../../src/schema/zod.d.ts"],"mappings":";;;mBAGmBA,UAAAA,SAAmB,gBAAgB;AAAA"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { asyncStream } from "../util/stream.mjs";
|
|
2
|
+
import * as z from "zod/v4";
|
|
3
|
+
//#region src/schema/zod.ts
|
|
4
|
+
/**
|
|
5
|
+
* Creates a Zod schema for an async stream field, ready to use in `.arguments()`.
|
|
6
|
+
* Wraps `z.custom<AsyncIterable<T>>()` with the `asyncStream()` metadata automatically.
|
|
7
|
+
*
|
|
8
|
+
* @param itemSchema - Optional item schema for per-item validation.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { zodAsyncStream } from 'padrone/zod';
|
|
13
|
+
*
|
|
14
|
+
* // String lines
|
|
15
|
+
* z.object({ lines: zodAsyncStream() })
|
|
16
|
+
*
|
|
17
|
+
* // Typed items — each line JSON.parse'd and validated
|
|
18
|
+
* const recordSchema = z.object({ name: z.string(), age: z.number() });
|
|
19
|
+
* z.object({ records: zodAsyncStream(jsonCodec(recordSchema)) })
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
function zodAsyncStream(itemSchema) {
|
|
23
|
+
return z.custom().meta(asyncStream(itemSchema));
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* JSON codec for Zod schemas
|
|
27
|
+
* @see https://zod.dev/codecs?id=jsonschema
|
|
28
|
+
* Unlike the example in the docs, this codec also handles the case where the input is already an object
|
|
29
|
+
*/
|
|
30
|
+
const jsonCodec = (schema) => z.codec(z.union([z.string(), z.unknown()]), schema, {
|
|
31
|
+
decode: (jsonString, ctx) => {
|
|
32
|
+
try {
|
|
33
|
+
if (typeof jsonString !== "string") return jsonString;
|
|
34
|
+
return JSON.parse(jsonString);
|
|
35
|
+
} catch (err) {
|
|
36
|
+
ctx.issues.push({
|
|
37
|
+
code: "invalid_format",
|
|
38
|
+
format: "json",
|
|
39
|
+
input: typeof jsonString === "string" ? jsonString : JSON.stringify(jsonString),
|
|
40
|
+
message: err.message
|
|
41
|
+
});
|
|
42
|
+
return z.NEVER;
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
encode: (value) => JSON.stringify(value)
|
|
46
|
+
});
|
|
47
|
+
//#endregion
|
|
48
|
+
export { jsonCodec, zodAsyncStream };
|
|
49
|
+
|
|
50
|
+
//# sourceMappingURL=zod.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zod.mjs","names":[],"sources":["../../src/schema/zod.ts"],"sourcesContent":["import * as z from 'zod/v4';\nimport type { PadroneSchema } from '../types/index.ts';\nimport { asyncStream } from '../util/stream.ts';\n\n/**\n * Creates a Zod schema for an async stream field, ready to use in `.arguments()`.\n * Wraps `z.custom<AsyncIterable<T>>()` with the `asyncStream()` metadata automatically.\n *\n * @param itemSchema - Optional item schema for per-item validation.\n *\n * @example\n * ```ts\n * import { zodAsyncStream } from 'padrone/zod';\n *\n * // String lines\n * z.object({ lines: zodAsyncStream() })\n *\n * // Typed items — each line JSON.parse'd and validated\n * const recordSchema = z.object({ name: z.string(), age: z.number() });\n * z.object({ records: zodAsyncStream(jsonCodec(recordSchema)) })\n * ```\n */\nexport function zodAsyncStream<T = string>(itemSchema?: PadroneSchema<unknown, T>) {\n return z.custom<AsyncIterable<T>>().meta(asyncStream(itemSchema));\n}\n\n/**\n * JSON codec for Zod schemas\n * @see https://zod.dev/codecs?id=jsonschema\n * Unlike the example in the docs, this codec also handles the case where the input is already an object\n */\nexport const jsonCodec = <T extends z.ZodType>(schema: T) =>\n z.codec(z.union([z.string(), z.unknown()]), schema, {\n decode: (jsonString, ctx) => {\n try {\n // HACK: in some cases the object is already deserialized, we just need to validate it\n if (typeof jsonString !== 'string') return jsonString as z.input<T>;\n return JSON.parse(jsonString) as z.input<T>;\n } catch (err: any) {\n ctx.issues.push({\n code: 'invalid_format',\n format: 'json',\n input: typeof jsonString === 'string' ? jsonString : JSON.stringify(jsonString),\n message: err.message,\n });\n return z.NEVER;\n }\n },\n encode: (value) => JSON.stringify(value),\n });\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAsBA,SAAgB,eAA2B,YAAwC;CACjF,OAAO,EAAE,OAAyB,CAAC,CAAC,KAAK,YAAY,UAAU,CAAC;AAClE;;;;;;AAOA,MAAa,aAAkC,WAC7C,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC,CAAC,GAAG,QAAQ;CAClD,SAAS,YAAY,QAAQ;EAC3B,IAAI;GAEF,IAAI,OAAO,eAAe,UAAU,OAAO;GAC3C,OAAO,KAAK,MAAM,UAAU;EAC9B,SAAS,KAAU;GACjB,IAAI,OAAO,KAAK;IACd,MAAM;IACN,QAAQ;IACR,OAAO,OAAO,eAAe,WAAW,aAAa,KAAK,UAAU,UAAU;IAC9E,SAAS,IAAI;GACf,CAAC;GACD,OAAO,EAAE;EACX;CACF;CACA,SAAS,UAAU,KAAK,UAAU,KAAK;AACzC,CAAC"}
|
package/dist/serve.d.mts
ADDED
package/dist/serve.mjs
ADDED