padrone 1.9.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (328) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +2 -2
  3. package/dist/codegen/code-builder.d.mts +10 -0
  4. package/dist/codegen/code-builder.d.mts.map +1 -0
  5. package/dist/codegen/code-builder.mjs +185 -0
  6. package/dist/codegen/code-builder.mjs.map +1 -0
  7. package/dist/codegen/discovery.d.mts +44 -0
  8. package/dist/codegen/discovery.d.mts.map +1 -0
  9. package/dist/codegen/discovery.mjs +179 -0
  10. package/dist/codegen/discovery.mjs.map +1 -0
  11. package/dist/codegen/file-emitter.d.mts +10 -0
  12. package/dist/codegen/file-emitter.d.mts.map +1 -0
  13. package/dist/codegen/file-emitter.mjs +58 -0
  14. package/dist/codegen/file-emitter.mjs.map +1 -0
  15. package/dist/codegen/generators/barrel-file.d.mts +10 -0
  16. package/dist/codegen/generators/barrel-file.d.mts.map +1 -0
  17. package/dist/codegen/generators/barrel-file.mjs +16 -0
  18. package/dist/codegen/generators/barrel-file.mjs.map +1 -0
  19. package/dist/codegen/generators/command-file.d.mts +25 -0
  20. package/dist/codegen/generators/command-file.d.mts.map +1 -0
  21. package/dist/codegen/generators/command-file.mjs +130 -0
  22. package/dist/codegen/generators/command-file.mjs.map +1 -0
  23. package/dist/codegen/generators/command-tree.d.mts +17 -0
  24. package/dist/codegen/generators/command-tree.d.mts.map +1 -0
  25. package/dist/codegen/generators/command-tree.mjs +72 -0
  26. package/dist/codegen/generators/command-tree.mjs.map +1 -0
  27. package/dist/codegen/index.d.mts +15 -330
  28. package/dist/codegen/index.mjs +13 -1507
  29. package/dist/codegen/parsers/bash.d.mts +19 -0
  30. package/dist/codegen/parsers/bash.d.mts.map +1 -0
  31. package/dist/codegen/parsers/bash.mjs +112 -0
  32. package/dist/codegen/parsers/bash.mjs.map +1 -0
  33. package/dist/codegen/parsers/fish.d.mts +13 -0
  34. package/dist/codegen/parsers/fish.d.mts.map +1 -0
  35. package/dist/codegen/parsers/fish.mjs +108 -0
  36. package/dist/codegen/parsers/fish.mjs.map +1 -0
  37. package/dist/codegen/parsers/help.d.mts +15 -0
  38. package/dist/codegen/parsers/help.d.mts.map +1 -0
  39. package/dist/codegen/parsers/help.mjs +271 -0
  40. package/dist/codegen/parsers/help.mjs.map +1 -0
  41. package/dist/codegen/parsers/merge.d.mts +14 -0
  42. package/dist/codegen/parsers/merge.d.mts.map +1 -0
  43. package/dist/codegen/parsers/merge.mjs +76 -0
  44. package/dist/codegen/parsers/merge.mjs.map +1 -0
  45. package/dist/codegen/parsers/zsh.d.mts +16 -0
  46. package/dist/codegen/parsers/zsh.d.mts.map +1 -0
  47. package/dist/codegen/parsers/zsh.mjs +161 -0
  48. package/dist/codegen/parsers/zsh.mjs.map +1 -0
  49. package/dist/codegen/schema-to-code.d.mts +24 -0
  50. package/dist/codegen/schema-to-code.d.mts.map +1 -0
  51. package/dist/codegen/schema-to-code.mjs +147 -0
  52. package/dist/codegen/schema-to-code.mjs.map +1 -0
  53. package/dist/codegen/template.d.mts +18 -0
  54. package/dist/codegen/template.d.mts.map +1 -0
  55. package/dist/codegen/template.mjs +37 -0
  56. package/dist/codegen/template.mjs.map +1 -0
  57. package/dist/codegen/types.d.mts +144 -0
  58. package/dist/codegen/types.d.mts.map +1 -0
  59. package/dist/completion.d.mts +2 -0
  60. package/dist/completion.mjs +2 -0
  61. package/dist/core/args.d.mts +3 -0
  62. package/dist/{args-WmyGc59s.mjs → core/args.mjs} +5 -81
  63. package/dist/core/args.mjs.map +1 -0
  64. package/dist/core/commands.d.mts +13 -0
  65. package/dist/core/commands.d.mts.map +1 -0
  66. package/dist/{commands-ohEApqIw.mjs → core/commands.mjs} +4 -232
  67. package/dist/core/commands.mjs.map +1 -0
  68. package/dist/core/create.d.mts +63 -0
  69. package/dist/core/create.d.mts.map +1 -0
  70. package/dist/core/create.mjs +230 -0
  71. package/dist/core/create.mjs.map +1 -0
  72. package/dist/core/default-runtime.mjs +198 -0
  73. package/dist/core/default-runtime.mjs.map +1 -0
  74. package/dist/core/errors.d.mts +107 -0
  75. package/dist/core/errors.d.mts.map +1 -0
  76. package/dist/{errors-DA4KzK1M.mjs → core/errors.mjs} +2 -2
  77. package/dist/core/errors.mjs.map +1 -0
  78. package/dist/core/exec.mjs +191 -0
  79. package/dist/core/exec.mjs.map +1 -0
  80. package/dist/core/interceptors.d.mts +33 -0
  81. package/dist/core/interceptors.d.mts.map +1 -0
  82. package/dist/core/interceptors.mjs +253 -0
  83. package/dist/core/interceptors.mjs.map +1 -0
  84. package/dist/core/parse.mjs +181 -0
  85. package/dist/core/parse.mjs.map +1 -0
  86. package/dist/core/program-methods.mjs +256 -0
  87. package/dist/core/program-methods.mjs.map +1 -0
  88. package/dist/core/results.d.mts +13 -0
  89. package/dist/core/results.d.mts.map +1 -0
  90. package/dist/core/results.mjs +150 -0
  91. package/dist/core/results.mjs.map +1 -0
  92. package/dist/core/runtime.d.mts +213 -0
  93. package/dist/core/runtime.d.mts.map +1 -0
  94. package/dist/core/runtime.mjs +10 -0
  95. package/dist/core/runtime.mjs.map +1 -0
  96. package/dist/core/validate.mjs +220 -0
  97. package/dist/core/validate.mjs.map +1 -0
  98. package/dist/docs/index.d.mts +1 -1
  99. package/dist/docs/index.d.mts.map +1 -1
  100. package/dist/docs/index.mjs +2 -2
  101. package/dist/docs/index.mjs.map +1 -1
  102. package/dist/extension/auto-output.d.mts +53 -0
  103. package/dist/extension/auto-output.d.mts.map +1 -0
  104. package/dist/extension/auto-output.mjs +116 -0
  105. package/dist/extension/auto-output.mjs.map +1 -0
  106. package/dist/extension/color.d.mts +19 -0
  107. package/dist/extension/color.d.mts.map +1 -0
  108. package/dist/extension/color.mjs +37 -0
  109. package/dist/extension/color.mjs.map +1 -0
  110. package/dist/extension/completion.d.mts +25 -0
  111. package/dist/extension/completion.d.mts.map +1 -0
  112. package/dist/extension/completion.mjs +40 -0
  113. package/dist/extension/completion.mjs.map +1 -0
  114. package/dist/extension/config.d.mts +55 -0
  115. package/dist/extension/config.d.mts.map +1 -0
  116. package/dist/extension/config.mjs +162 -0
  117. package/dist/extension/config.mjs.map +1 -0
  118. package/dist/extension/env.d.mts +42 -0
  119. package/dist/extension/env.d.mts.map +1 -0
  120. package/dist/extension/env.mjs +44 -0
  121. package/dist/extension/env.mjs.map +1 -0
  122. package/dist/extension/help.d.mts +29 -0
  123. package/dist/extension/help.d.mts.map +1 -0
  124. package/dist/extension/help.mjs +161 -0
  125. package/dist/extension/help.mjs.map +1 -0
  126. package/dist/extension/index.d.mts +18 -0
  127. package/dist/extension/ink.d.mts +31 -0
  128. package/dist/extension/ink.d.mts.map +1 -0
  129. package/dist/extension/ink.mjs +69 -0
  130. package/dist/extension/ink.mjs.map +1 -0
  131. package/dist/extension/interactive.d.mts +16 -0
  132. package/dist/extension/interactive.d.mts.map +1 -0
  133. package/dist/extension/interactive.mjs +89 -0
  134. package/dist/extension/interactive.mjs.map +1 -0
  135. package/dist/extension/logger.d.mts +67 -0
  136. package/dist/extension/logger.d.mts.map +1 -0
  137. package/dist/extension/logger.mjs +188 -0
  138. package/dist/extension/logger.mjs.map +1 -0
  139. package/dist/extension/man.d.mts +25 -0
  140. package/dist/extension/man.d.mts.map +1 -0
  141. package/dist/extension/man.mjs +41 -0
  142. package/dist/extension/man.mjs.map +1 -0
  143. package/dist/extension/mcp.d.mts +28 -0
  144. package/dist/extension/mcp.d.mts.map +1 -0
  145. package/dist/extension/mcp.mjs +44 -0
  146. package/dist/extension/mcp.mjs.map +1 -0
  147. package/dist/extension/progress-renderer.d.mts +13 -0
  148. package/dist/extension/progress-renderer.d.mts.map +1 -0
  149. package/dist/extension/progress-renderer.mjs +351 -0
  150. package/dist/extension/progress-renderer.mjs.map +1 -0
  151. package/dist/extension/progress.d.mts +76 -0
  152. package/dist/extension/progress.d.mts.map +1 -0
  153. package/dist/extension/progress.mjs +225 -0
  154. package/dist/extension/progress.mjs.map +1 -0
  155. package/dist/extension/repl.d.mts +26 -0
  156. package/dist/extension/repl.d.mts.map +1 -0
  157. package/dist/extension/repl.mjs +67 -0
  158. package/dist/extension/repl.mjs.map +1 -0
  159. package/dist/extension/serve.d.mts +27 -0
  160. package/dist/extension/serve.d.mts.map +1 -0
  161. package/dist/extension/serve.mjs +41 -0
  162. package/dist/extension/serve.mjs.map +1 -0
  163. package/dist/extension/signal.d.mts +19 -0
  164. package/dist/extension/signal.d.mts.map +1 -0
  165. package/dist/extension/signal.mjs +81 -0
  166. package/dist/extension/signal.mjs.map +1 -0
  167. package/dist/extension/stdin.d.mts +19 -0
  168. package/dist/extension/stdin.d.mts.map +1 -0
  169. package/dist/extension/stdin.mjs +52 -0
  170. package/dist/extension/stdin.mjs.map +1 -0
  171. package/dist/extension/suggestions.d.mts +6 -0
  172. package/dist/extension/suggestions.d.mts.map +1 -0
  173. package/dist/extension/suggestions.mjs +113 -0
  174. package/dist/extension/suggestions.mjs.map +1 -0
  175. package/dist/extension/timing.d.mts +27 -0
  176. package/dist/extension/timing.d.mts.map +1 -0
  177. package/dist/extension/timing.mjs +71 -0
  178. package/dist/extension/timing.mjs.map +1 -0
  179. package/dist/extension/tracing.d.mts +85 -0
  180. package/dist/extension/tracing.d.mts.map +1 -0
  181. package/dist/extension/tracing.mjs +107 -0
  182. package/dist/extension/tracing.mjs.map +1 -0
  183. package/dist/extension/update-check.d.mts +20 -0
  184. package/dist/extension/update-check.d.mts.map +1 -0
  185. package/dist/extension/update-check.mjs +62 -0
  186. package/dist/extension/update-check.mjs.map +1 -0
  187. package/dist/extension/utils.mjs +43 -0
  188. package/dist/extension/utils.mjs.map +1 -0
  189. package/dist/extension/version.d.mts +20 -0
  190. package/dist/extension/version.d.mts.map +1 -0
  191. package/dist/extension/version.mjs +51 -0
  192. package/dist/extension/version.mjs.map +1 -0
  193. package/dist/{completion-D8qkAinX.mjs → feature/completion.mjs} +4 -3
  194. package/dist/feature/completion.mjs.map +1 -0
  195. package/dist/feature/interactive.mjs +145 -0
  196. package/dist/feature/interactive.mjs.map +1 -0
  197. package/dist/feature/mcp.d.mts +18 -0
  198. package/dist/feature/mcp.d.mts.map +1 -0
  199. package/dist/{mcp-wCoVFTXz.mjs → feature/mcp.mjs} +6 -6
  200. package/dist/feature/mcp.mjs.map +1 -0
  201. package/dist/feature/repl-loop.mjs +217 -0
  202. package/dist/feature/repl-loop.mjs.map +1 -0
  203. package/dist/feature/serve.d.mts +18 -0
  204. package/dist/feature/serve.d.mts.map +1 -0
  205. package/dist/{serve-ICZFl3xr.mjs → feature/serve.mjs} +7 -7
  206. package/dist/feature/serve.mjs.map +1 -0
  207. package/dist/feature/test.d.mts +109 -0
  208. package/dist/feature/test.d.mts.map +1 -0
  209. package/dist/feature/test.mjs +116 -0
  210. package/dist/feature/test.mjs.map +1 -0
  211. package/dist/feature/update-check.d.mts +35 -0
  212. package/dist/feature/update-check.d.mts.map +1 -0
  213. package/dist/{update-check-CZ2VqjnV.mjs → feature/update-check.mjs} +2 -2
  214. package/dist/feature/update-check.mjs.map +1 -0
  215. package/dist/feature/wrap.d.mts +58 -0
  216. package/dist/feature/wrap.d.mts.map +1 -0
  217. package/dist/feature/wrap.mjs +77 -0
  218. package/dist/feature/wrap.mjs.map +1 -0
  219. package/dist/index.d.mts +38 -902
  220. package/dist/index.mjs +25 -4377
  221. package/dist/ink.d.mts +2 -0
  222. package/dist/ink.mjs +2 -0
  223. package/dist/man.d.mts +2 -0
  224. package/dist/man.mjs +2 -0
  225. package/dist/mcp.d.mts +3 -0
  226. package/dist/mcp.mjs +2 -0
  227. package/dist/output/colorizer.d.mts +28 -0
  228. package/dist/output/colorizer.d.mts.map +1 -0
  229. package/dist/output/colorizer.mjs +94 -0
  230. package/dist/output/colorizer.mjs.map +1 -0
  231. package/dist/{formatter-CY3KrOEd.d.mts → output/formatter.d.mts} +2 -28
  232. package/dist/output/formatter.d.mts.map +1 -0
  233. package/dist/output/formatter.mjs +360 -0
  234. package/dist/output/formatter.mjs.map +1 -0
  235. package/dist/output/help.d.mts +18 -0
  236. package/dist/output/help.d.mts.map +1 -0
  237. package/dist/output/help.mjs +267 -0
  238. package/dist/output/help.mjs.map +1 -0
  239. package/dist/output/output-indicator.d.mts +27 -0
  240. package/dist/output/output-indicator.d.mts.map +1 -0
  241. package/dist/output/output-indicator.mjs +54 -0
  242. package/dist/output/output-indicator.mjs.map +1 -0
  243. package/dist/output/primitives.d.mts +33 -0
  244. package/dist/output/primitives.d.mts.map +1 -0
  245. package/dist/output/primitives.mjs +206 -0
  246. package/dist/output/primitives.mjs.map +1 -0
  247. package/dist/output/styling.d.mts +38 -0
  248. package/dist/output/styling.d.mts.map +1 -0
  249. package/dist/output/styling.mjs +146 -0
  250. package/dist/output/styling.mjs.map +1 -0
  251. package/dist/schema/zod.d.mts +6 -0
  252. package/dist/schema/zod.d.mts.map +1 -0
  253. package/dist/schema/zod.mjs +50 -0
  254. package/dist/schema/zod.mjs.map +1 -0
  255. package/dist/serve.d.mts +2 -0
  256. package/dist/serve.mjs +2 -0
  257. package/dist/test.d.mts +2 -109
  258. package/dist/test.mjs +1 -115
  259. package/dist/tracing.d.mts +2 -0
  260. package/dist/tracing.mjs +2 -0
  261. package/dist/types/args-meta.d.mts +129 -0
  262. package/dist/types/args-meta.d.mts.map +1 -0
  263. package/dist/types/builder.d.mts +212 -0
  264. package/dist/types/builder.d.mts.map +1 -0
  265. package/dist/types/command.d.mts +112 -0
  266. package/dist/types/command.d.mts.map +1 -0
  267. package/dist/types/index.d.mts +8 -0
  268. package/dist/types/interceptor.d.mts +232 -0
  269. package/dist/types/interceptor.d.mts.map +1 -0
  270. package/dist/types/preferences.d.mts +79 -0
  271. package/dist/types/preferences.d.mts.map +1 -0
  272. package/dist/types/result.d.mts +61 -0
  273. package/dist/types/result.d.mts.map +1 -0
  274. package/dist/types/schema.d.mts +24 -0
  275. package/dist/types/schema.d.mts.map +1 -0
  276. package/dist/util/dotenv.mjs +174 -0
  277. package/dist/util/dotenv.mjs.map +1 -0
  278. package/dist/util/shell-utils.mjs +80 -0
  279. package/dist/util/shell-utils.mjs.map +1 -0
  280. package/dist/util/stream.d.mts +33 -0
  281. package/dist/util/stream.d.mts.map +1 -0
  282. package/dist/{stream-DC4H8YTx.mjs → util/stream.mjs} +2 -2
  283. package/dist/util/stream.mjs.map +1 -0
  284. package/dist/util/type-helpers.d.mts +74 -0
  285. package/dist/util/type-helpers.d.mts.map +1 -0
  286. package/dist/util/type-utils.d.mts +186 -0
  287. package/dist/util/type-utils.d.mts.map +1 -0
  288. package/dist/util/utils.mjs +43 -0
  289. package/dist/util/utils.mjs.map +1 -0
  290. package/dist/zod.d.mts +1 -32
  291. package/dist/zod.mjs +1 -49
  292. package/package.json +65 -17
  293. package/src/completion.ts +2 -0
  294. package/src/extension/completion.ts +3 -0
  295. package/src/extension/index.ts +0 -12
  296. package/src/extension/ink.ts +2 -1
  297. package/src/extension/man.ts +3 -0
  298. package/src/extension/mcp.ts +3 -0
  299. package/src/extension/serve.ts +3 -0
  300. package/src/extension/tracing.ts +2 -0
  301. package/src/index.ts +0 -19
  302. package/src/ink.ts +2 -0
  303. package/src/man.ts +2 -0
  304. package/src/mcp.ts +3 -0
  305. package/src/serve.ts +2 -0
  306. package/src/tracing.ts +9 -0
  307. package/src/zod.ts +1 -1
  308. package/dist/args-WmyGc59s.mjs.map +0 -1
  309. package/dist/codegen/index.d.mts.map +0 -1
  310. package/dist/codegen/index.mjs.map +0 -1
  311. package/dist/commands-ohEApqIw.mjs.map +0 -1
  312. package/dist/completion-D8qkAinX.mjs.map +0 -1
  313. package/dist/errors-DA4KzK1M.mjs.map +0 -1
  314. package/dist/formatter-CY3KrOEd.d.mts.map +0 -1
  315. package/dist/help-CeI45CJx.mjs +0 -892
  316. package/dist/help-CeI45CJx.mjs.map +0 -1
  317. package/dist/index-C3Ed1LYN.d.mts +0 -1432
  318. package/dist/index-C3Ed1LYN.d.mts.map +0 -1
  319. package/dist/index.d.mts.map +0 -1
  320. package/dist/index.mjs.map +0 -1
  321. package/dist/mcp-wCoVFTXz.mjs.map +0 -1
  322. package/dist/serve-ICZFl3xr.mjs.map +0 -1
  323. package/dist/stream-DC4H8YTx.mjs.map +0 -1
  324. package/dist/test.d.mts.map +0 -1
  325. package/dist/test.mjs.map +0 -1
  326. package/dist/update-check-CZ2VqjnV.mjs.map +0 -1
  327. package/dist/zod.d.mts.map +0 -1
  328. package/dist/zod.mjs.map +0 -1
@@ -0,0 +1,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":";;AAiBA,SAAS,cAAc,OAAwB;CAC7C,IAAI,UAAU,KAAA,KAAa,UAAU,MAAM,OAAO;CAClD,IAAI,OAAO,UAAU,UAAU,OAAO;CACtC,IAAI,OAAO,UAAU,YAAY,OAAO,UAAU,WAAW,OAAO,OAAO,KAAK;CAChF,OAAO,KAAK,UAAU,KAAK;AAC7B;AAEA,SAAS,SAAS,MAAc,KAAqB;CACnD,IAAI,OAAO,KAAK,KAAK,UAAU,KAAK,OAAO;CAC3C,OAAO,OAAO,IAAI,MAAM,GAAG,KAAK,MAAM,GAAG,MAAM,CAAC,EAAE;AACpD;AAEA,SAAS,QAAQ,MAAc,OAAe,YAAyC,QAAgB;CACrG,MAAM,MAAM,QAAQ,KAAK;CACzB,IAAI,OAAO,GAAG,OAAO;CACrB,IAAI,cAAc,SAAS,OAAO,IAAI,OAAO,GAAG,IAAI;CACpD,IAAI,cAAc,UAAU;EAC1B,MAAM,OAAO,KAAK,MAAM,MAAM,CAAC;EAC/B,OAAO,IAAI,OAAO,IAAI,IAAI,OAAO,IAAI,OAAO,MAAM,IAAI;CACxD;CACA,OAAO,OAAO,IAAI,OAAO,GAAG;AAC9B;AAEA,SAAgB,YAAY,MAAiC,SAAmC,KAA4B;CAC1H,IAAI,KAAK,WAAW,GAAG,OAAO;CAC9B,IAAI,IAAI,WAAW,QAAQ,OAAO,KAAK,UAAU,MAAM,MAAM,CAAC;CAE9D,MAAM,UAAU,SAAS,WAAW,OAAO,KAAK,KAAK,EAAG;CACxD,IAAI,QAAQ,WAAW,GAAG,OAAO;CAEjC,MAAM,UAAU,QAAQ,KAAK,QAAQ,SAAS,UAAU,QAAQ,GAAG;CACnE,MAAM,SAAS,SAAS;CAExB,MAAM,OAAO,KAAK,KAAK,QACrB,QAAQ,KAAK,QAAQ;EACnB,MAAM,OAAO,cAAc,IAAI,IAAI;EACnC,OAAO,SAAS,SAAS,MAAM,MAAM,IAAI;CAC3C,CAAC,CACH;CAEA,MAAM,YAAY,QAAQ,KAAK,GAAG,MAAM;EACtC,MAAM,cAAc,QAAQ,EAAE,CAAE;EAChC,MAAM,eAAe,KAAK,QAAQ,KAAK,QAAQ,KAAK,IAAI,KAAK,IAAI,EAAE,CAAE,MAAM,GAAG,CAAC;EAC/E,OAAO,KAAK,IAAI,aAAa,YAAY;CAC3C,CAAC;CAED,MAAM,YAAY,MAA2C,SAAS,QAAQ,QAAQ,OAAQ;CAE9F,IAAI,IAAI,WAAW,YAAY,OAAO,oBAAoB,SAAS,MAAM,WAAW,QAAQ;CAC5F,IAAI,IAAI,WAAW,QAAQ,OAAO,gBAAgB,SAAS,SAAS,MAAM,MAAM,QAAQ;CACxF,OAAO,gBAAgB,SAAS,MAAM,WAAW,UAAU,SAAS,WAAW,OAAO,GAAG;AAC3F;AAEA,SAAS,gBACP,SACA,MACA,WACA,UACA,QACA,KACQ;CACR,MAAM,EAAE,WAAW;CACnB,MAAM,aAAa,OAAiB,UAClC,MAAM,KAAK,MAAM,MAAM;EACrB,MAAM,SAAS,QAAQ,MAAM,UAAU,IAAK,SAAS,CAAC,CAAC;EACvD,OAAO,QAAQ,MAAM,MAAM,IAAI;CACjC,CAAC;CAEH,IAAI,QAAQ;EACV,MAAM,MAAM,IAAI,OAAO,KAAK,GAAG;EAC/B,MAAM,UAAU,UAAU,KAAK,MAAM,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,OAAO,KAAK,GAAG,CAAC;EAC7E,MAAM,OAAO,UAAoB,MAAM,KAAK,GAAG,MAAM,IAAI,QAAQ,GAAG,UAAU,IAAK,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,OAAO,KAAK,GAAG,CAAC;EACzH,MAAM,YAAY,IAAI,QAAQ,KAAK,MAAM,OAAO,MAAM,CAAC,CAAC,CAAC;EACzD,MAAM,WAAW,KAAK,KAAK,MAAM,IAAI,EAAE,KAAK,MAAM,OAAO,YAAY,CAAC,CAAC,CAAC,CAAC;EACzE,OAAO;GAAC;GAAW,OAAO,KAAK,GAAG,IAAI,UAAU,OAAO,KAAK,GAAG;GAAG,GAAG;EAAQ,CAAC,CAAC,KAAK,IAAI;CAC1F;CAEA,MAAM,cAAc,UAAU,SAAS,OAAO,KAAK;CACnD,MAAM,YAAY,KAAK,KAAK,MAAM,UAAU,GAAG,OAAO,WAAW,CAAC;CAClE,MAAM,MAAM;CACZ,OAAO,CAAC,YAAY,KAAK,GAAG,GAAG,GAAG,UAAU,KAAK,MAAM,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI;AAChF;AAEA,SAAS,oBACP,SACA,MACA,WACA,UACQ;CAeR,OAAO;EAAC,KAdgB,QAAQ,KAAK,GAAG,MAAM,QAAQ,GAAG,UAAU,IAAK,MAAM,CAAC,CAAC,CAAC,KAAK,KAAK,EAAE;EAE3F,OACA,UACG,KAAK,GAAG,MAAM;GACb,MAAM,IAAI,SAAS,CAAC;GACpB,MAAM,SAAS,IAAI,OAAO,KAAK,IAAI,GAAG,CAAC,CAAC;GACxC,IAAI,MAAM,UAAU,OAAO,IAAI,OAAO;GACtC,IAAI,MAAM,SAAS,OAAO,GAAG,OAAO;GACpC,OAAO;EACT,CAAC,CAAC,CACD,KAAK,KAAK,IACb;EAEiC,GADjB,KAAK,KAAK,MAAM,KAAK,EAAE,KAAK,GAAG,MAAM,QAAQ,GAAG,UAAU,IAAK,MAAM,CAAC,CAAC,CAAC,KAAK,KAAK,EAAE,GACxD;CAAC,CAAC,CAAC,KAAK,IAAI;AAC5D;AAEA,SAAS,gBACP,SACA,SACA,OACA,MACA,UACQ;CACR,MAAM,MAAM,QAAQ,KAAK,GAAG,MAAM;EAChC,MAAM,IAAI,SAAS,CAAC;EAEpB,OAAO,MADO,MAAM,SAAS,uBAAuB,EAAE,MAAM,GACzC,GAAG,WAAW,CAAC,EAAE;CACtC,CAAC;CACD,MAAM,MAAM,KAAK,KACd,QACC,SACA,QACG,KAAK,KAAK,MAAM;EACf,MAAM,IAAI,SAAS,CAAC;EAEpB,OAAO,MADO,MAAM,SAAS,uBAAuB,EAAE,MAAM,GACzC,GAAG,WAAW,cAAc,IAAI,IAAI,CAAC,EAAE;CAC5D,CAAC,CAAC,CACD,KAAK,EAAE,IACV,OACJ;CACA,OAAO,qBAAqB,IAAI,KAAK,EAAE,EAAE,sBAAsB,IAAI,KAAK,EAAE,EAAE;AAC9E;AAgBA,SAAgB,WAAW,MAA6B,SAAkC,KAA4B;CACpH,MAAM,QAAQ,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC,IAAI;CAChD,IAAI,MAAM,WAAW,GAAG,OAAO;CAC/B,IAAI,IAAI,WAAW,QAAQ,OAAO,KAAK,UAAU,OAAO,MAAM,CAAC;CAC/D,IAAI,IAAI,WAAW,YAAY,OAAO,mBAAmB,OAAO,CAAC;CACjE,IAAI,IAAI,WAAW,QAAQ,OAAO,eAAe,KAAK;CAGtD,OAAO,eAAe,OAAO,IADd,SAAS,WAAW,OACM,GAAG,CAAC,CAAC,KAAK,IAAI;AACzD;AAEA,SAAS,eAAe,OAAmB,QAAgB,QAAiB,KAA8B;CACxG,MAAM,QAAkB,CAAC;CACzB,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;EACrC,MAAM,OAAO,MAAM;EACnB,MAAM,SAAS,MAAM,MAAM,SAAS;EACpC,IAAI,QAAQ;GACV,MAAM,YAAY,SAAS,SAAS;GACpC,MAAM,cAAc,SAAS,SAAS;GACtC,MAAM,KAAK,SAAS,IAAI,OAAO,KAAK,SAAS,IAAI,IAAI,OAAO,MAAM,KAAK,KAAK,CAAC;GAC7E,IAAI,KAAK,UAAU,QAAQ,MAAM,KAAK,GAAG,eAAe,KAAK,UAAU,SAAS,IAAI,OAAO,KAAK,WAAW,GAAG,QAAQ,GAAG,CAAC;EAC5H,OAAO;GACL,MAAM,SAAS,SAAS,GAAG,OAAO,MAAM;GACxC,MAAM,KAAK,SAAS,IAAI,OAAO,MAAM,KAAK,KAAK,CAAC;GAChD,IAAI,KAAK,UAAU,QAAQ,MAAM,KAAK,GAAG,eAAe,KAAK,UAAU,QAAQ,QAAQ,GAAG,CAAC;EAC7F;CACF;CACA,OAAO;AACT;AAEA,SAAS,mBAAmB,OAAmB,OAAuB;CACpE,OAAO,MACJ,KAAK,SAAS;EAEb,MAAM,OAAO,GADE,KAAK,OAAO,KACN,EAAE,IAAI,KAAK;EAChC,IAAI,CAAC,KAAK,UAAU,QAAQ,OAAO;EACnC,OAAO,GAAG,KAAK,IAAI,mBAAmB,KAAK,UAAU,QAAQ,CAAC;CAChE,CAAC,CAAC,CACD,KAAK,IAAI;AACd;AAEA,SAAS,eAAe,OAA2B;CAQjD,OAAO,OAPO,MACX,KAAK,SAAS;EACb,MAAM,QAAQ,WAAW,KAAK,KAAK;EACnC,IAAI,CAAC,KAAK,UAAU,QAAQ,OAAO,OAAO,MAAM;EAChD,OAAO,OAAO,QAAQ,eAAe,KAAK,QAAQ,EAAE;CACtD,CAAC,CAAC,CACD,KAAK,EACU,EAAE;AACtB;AAeA,SAAgB,WAAW,MAAkB,SAAkC,KAA4B;CACzG,IAAI,KAAK,WAAW,GAAG,OAAO;CAC9B,IAAI,IAAI,WAAW,QAAQ;EACzB,MAAM,aAAa,KAAK,KAAK,SAAU,OAAO,SAAS,WAAW,EAAE,OAAO,KAAK,IAAI,IAAK;EACzF,OAAO,KAAK,UAAU,YAAY,MAAM,CAAC;CAC3C;CACA,IAAI,IAAI,WAAW,YAAY,OAAO,mBAAmB,MAAM,OAAO;CACtE,IAAI,IAAI,WAAW,QAAQ,OAAO,eAAe,MAAM,OAAO;CAC9D,OAAO,eAAe,MAAM,SAAS,GAAG;AAC1C;AAEA,SAAS,eAAe,MAAkB,SAAkC,KAA4B;CACtG,MAAM,EAAE,WAAW;CACnB,MAAM,WAAW,SAAS,YAAY;CACtC,MAAM,SAAS,SAAS,WAAW,IAAI,WAAW,SAAS,MAAM;CACjE,MAAM,aAAa,KAAK,OAAO,SAAS,UAAU,CAAC;CAEnD,OAAO,KACJ,KAAK,MAAM,MAAM;EAChB,MAAM,SAAS,WAAW,GAAG,IAAI,EAAE,KAAK;EACxC,MAAM,QAAQ,OAAO,SAAS,WAAW,OAAO,KAAK;EACrD,MAAM,OAAO,OAAO,SAAS,YAAY,KAAK,cAAc,KAAK,cAAc,KAAA;EAC/E,MAAM,OAAO,GAAG,aAAa,OAAO,KAAK,MAAM,EAAE,GAAG,OAAO,MAAM,KAAK;EACtE,IAAI,CAAC,MAAM,OAAO;EAClB,OAAO,GAAG,KAAK,IAAI,OAAO,YAAY,IAAI;CAC5C,CAAC,CAAC,CACD,KAAK,IAAI;AACd;AAEA,SAAS,mBAAmB,MAAkB,SAA0C;CACtF,MAAM,WAAW,SAAS,YAAY;CACtC,OAAO,KACJ,KAAK,MAAM,MAAM;EAChB,MAAM,SAAS,WAAW,GAAG,IAAI,EAAE,KAAK;EACxC,MAAM,QAAQ,OAAO,SAAS,WAAW,OAAO,KAAK;EACrD,MAAM,OAAO,OAAO,SAAS,YAAY,KAAK,cAAc,KAAK,cAAc,KAAA;EAC/E,IAAI,CAAC,MAAM,OAAO,GAAG,OAAO,GAAG;EAC/B,OAAO,GAAG,OAAO,KAAK,MAAM,OAAO;CACrC,CAAC,CAAC,CACD,KAAK,IAAI;AACd;AAEA,SAAS,eAAe,MAAkB,SAA0C;CAClF,MAAM,MAAM,SAAS,WAAW,OAAO;CASvC,OAAO,IAAI,IAAI,GARD,KACX,KAAK,SAAS;EACb,MAAM,QAAQ,OAAO,SAAS,WAAW,OAAO,KAAK;EACrD,MAAM,OAAO,OAAO,SAAS,YAAY,KAAK,cAAc,KAAK,cAAc,KAAA;EAC/E,IAAI,CAAC,MAAM,OAAO,OAAO,WAAW,KAAK,EAAE;EAC3C,OAAO,eAAe,WAAW,KAAK,EAAE,cAAc,WAAW,IAAI,EAAE;CACzE,CAAC,CAAC,CACD,KAAK,EACc,EAAE,IAAI,IAAI;AAClC;AAaA,SAAgB,eAAe,MAA+B,SAAsC,KAA4B;CAC9H,MAAM,UAAU,OAAO,QAAQ,IAAI;CACnC,IAAI,QAAQ,WAAW,GAAG,OAAO;CACjC,IAAI,IAAI,WAAW,QAAQ,OAAO,KAAK,UAAU,MAAM,MAAM,CAAC;CAC9D,IAAI,IAAI,WAAW,YAAY,OAAO,uBAAuB,SAAS,OAAO;CAC7E,IAAI,IAAI,WAAW,QAAQ,OAAO,mBAAmB,SAAS,OAAO;CACrE,OAAO,mBAAmB,SAAS,SAAS,GAAG;AACjD;AAEA,SAAS,SAAS,KAAa,QAAyC;CACtE,OAAO,SAAS,QAAQ;AAC1B;AAEA,SAAS,mBAAmB,SAA8B,SAAsC,KAA4B;CAC1H,MAAM,EAAE,WAAW;CACnB,MAAM,MAAM,SAAS,aAAa;CAClC,MAAM,cAAc,SAAS,UAAU;CAEvC,MAAM,gBAAgB,QAAQ,KAAK,CAAC,OAAO,SAAS,GAAG,SAAS,MAAM,CAAC;CACvE,MAAM,WAAW,cAAc,KAAK,IAAI,GAAG,cAAc,KAAK,MAAM,EAAE,MAAM,CAAC,IAAI;CAEjF,OAAO,QACJ,KAAK,CAAC,MAAM,QAAQ,MAAM;EACzB,MAAM,QAAQ,cAAc;EAC5B,MAAM,cAAc,cAAc,QAAQ,IAAI,OAAO,WAAW,MAAM,MAAM,IAAI;EAChF,OAAO,GAAG,OAAO,MAAM,WAAW,IAAI,OAAO,KAAK,GAAG,IAAI,OAAO,YAAY,cAAc,KAAK,CAAC;CAClG,CAAC,CAAC,CACD,KAAK,IAAI;AACd;AAEA,SAAS,uBAAuB,SAA8B,SAA8C;CAC1G,OAAO,QAAQ,KAAK,CAAC,KAAK,WAAW,OAAO,SAAS,KAAK,SAAS,MAAM,EAAE,MAAM,cAAc,KAAK,GAAG,CAAC,CAAC,KAAK,IAAI;AACpH;AAEA,SAAS,mBAAmB,SAA8B,SAA8C;CAItG,OAAO,OAHO,QACX,KAAK,CAAC,KAAK,WAAW,OAAO,WAAW,SAAS,KAAK,SAAS,MAAM,CAAC,EAAE,WAAW,WAAW,cAAc,KAAK,CAAC,EAAE,MAAM,CAAC,CAC3H,KAAK,EACU,EAAE;AACtB"}
@@ -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, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
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) => "&nbsp;&nbsp;".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, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;').replace(/'/g, '&#039;');\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) => '&nbsp;&nbsp;'.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,6 @@
1
+ import { PadroneFieldMeta } from "../types/args-meta.mjs";
2
+ //#region src/schema/zod.d.ts
3
+ declare module 'zod/v4/core' {
4
+ export interface GlobalMeta extends PadroneFieldMeta {}
5
+ }
6
+ //# sourceMappingURL=zod.d.mts.map
@@ -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"}
@@ -0,0 +1,2 @@
1
+ import { WithServe, padroneServe } from "./extension/serve.mjs";
2
+ export { type WithServe, padroneServe };
package/dist/serve.mjs ADDED
@@ -0,0 +1,2 @@
1
+ import { padroneServe } from "./extension/serve.mjs";
2
+ export { padroneServe };