toolcraft-openapi 0.0.17 → 0.0.19

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 (88) hide show
  1. package/dist/bin/generate.js +7 -0
  2. package/dist/define-client.js +2 -2
  3. package/dist/generate.js +2 -2
  4. package/dist/http.d.ts +21 -2
  5. package/dist/http.js +147 -22
  6. package/dist/index.d.ts +1 -1
  7. package/dist/lock.d.ts +1 -1
  8. package/dist/lock.js +109 -5
  9. package/dist/mock/fetch.js +1 -1
  10. package/dist/network-error.d.ts +2 -0
  11. package/dist/network-error.js +83 -0
  12. package/dist/spec-source.js +103 -3
  13. package/node_modules/@poe-code/design-system/dist/acp/components.js +15 -13
  14. package/node_modules/@poe-code/design-system/dist/components/color.d.ts +31 -0
  15. package/node_modules/@poe-code/design-system/dist/components/color.js +101 -0
  16. package/node_modules/@poe-code/design-system/dist/components/help-formatter-plain.d.ts +1 -0
  17. package/node_modules/@poe-code/design-system/dist/components/help-formatter-plain.js +1 -1
  18. package/node_modules/@poe-code/design-system/dist/components/index.d.ts +4 -0
  19. package/node_modules/@poe-code/design-system/dist/components/index.js +2 -0
  20. package/node_modules/@poe-code/design-system/dist/components/logger.js +2 -2
  21. package/node_modules/@poe-code/design-system/dist/components/symbols.js +3 -3
  22. package/node_modules/@poe-code/design-system/dist/components/table.js +191 -40
  23. package/node_modules/@poe-code/design-system/dist/components/template.d.ts +6 -0
  24. package/node_modules/@poe-code/design-system/dist/components/template.js +271 -0
  25. package/node_modules/@poe-code/design-system/dist/components/text.d.ts +1 -0
  26. package/node_modules/@poe-code/design-system/dist/components/text.js +11 -3
  27. package/node_modules/@poe-code/design-system/dist/dashboard/buffer.js +20 -13
  28. package/node_modules/@poe-code/design-system/dist/dashboard/keymap.d.ts +5 -0
  29. package/node_modules/@poe-code/design-system/dist/dashboard/keymap.js +146 -12
  30. package/node_modules/@poe-code/design-system/dist/dashboard/terminal.js +31 -0
  31. package/node_modules/@poe-code/design-system/dist/dashboard/types.d.ts +1 -0
  32. package/node_modules/@poe-code/design-system/dist/explorer/actions.d.ts +16 -0
  33. package/node_modules/@poe-code/design-system/dist/explorer/actions.js +39 -0
  34. package/node_modules/@poe-code/design-system/dist/explorer/demo.d.ts +13 -0
  35. package/node_modules/@poe-code/design-system/dist/explorer/demo.js +297 -0
  36. package/node_modules/@poe-code/design-system/dist/explorer/events.d.ts +61 -0
  37. package/node_modules/@poe-code/design-system/dist/explorer/events.js +1 -0
  38. package/node_modules/@poe-code/design-system/dist/explorer/filter.d.ts +10 -0
  39. package/node_modules/@poe-code/design-system/dist/explorer/filter.js +95 -0
  40. package/node_modules/@poe-code/design-system/dist/explorer/index.d.ts +8 -0
  41. package/node_modules/@poe-code/design-system/dist/explorer/index.js +8 -0
  42. package/node_modules/@poe-code/design-system/dist/explorer/jobs.d.ts +7 -0
  43. package/node_modules/@poe-code/design-system/dist/explorer/jobs.js +59 -0
  44. package/node_modules/@poe-code/design-system/dist/explorer/keymap.d.ts +21 -0
  45. package/node_modules/@poe-code/design-system/dist/explorer/keymap.js +363 -0
  46. package/node_modules/@poe-code/design-system/dist/explorer/layout.d.ts +20 -0
  47. package/node_modules/@poe-code/design-system/dist/explorer/layout.js +73 -0
  48. package/node_modules/@poe-code/design-system/dist/explorer/reducer.d.ts +9 -0
  49. package/node_modules/@poe-code/design-system/dist/explorer/reducer.js +704 -0
  50. package/node_modules/@poe-code/design-system/dist/explorer/render/detail.d.ts +4 -0
  51. package/node_modules/@poe-code/design-system/dist/explorer/render/detail.js +96 -0
  52. package/node_modules/@poe-code/design-system/dist/explorer/render/footer.d.ts +4 -0
  53. package/node_modules/@poe-code/design-system/dist/explorer/render/footer.js +49 -0
  54. package/node_modules/@poe-code/design-system/dist/explorer/render/header.d.ts +4 -0
  55. package/node_modules/@poe-code/design-system/dist/explorer/render/header.js +56 -0
  56. package/node_modules/@poe-code/design-system/dist/explorer/render/index.d.ts +8 -0
  57. package/node_modules/@poe-code/design-system/dist/explorer/render/index.js +61 -0
  58. package/node_modules/@poe-code/design-system/dist/explorer/render/list.d.ts +4 -0
  59. package/node_modules/@poe-code/design-system/dist/explorer/render/list.js +106 -0
  60. package/node_modules/@poe-code/design-system/dist/explorer/render/modal.d.ts +3 -0
  61. package/node_modules/@poe-code/design-system/dist/explorer/render/modal.js +91 -0
  62. package/node_modules/@poe-code/design-system/dist/explorer/render/test-fixtures.d.ts +8 -0
  63. package/node_modules/@poe-code/design-system/dist/explorer/render/test-fixtures.js +156 -0
  64. package/node_modules/@poe-code/design-system/dist/explorer/runtime.d.ts +2 -0
  65. package/node_modules/@poe-code/design-system/dist/explorer/runtime.js +282 -0
  66. package/node_modules/@poe-code/design-system/dist/explorer/runtime.test-helpers.d.ts +50 -0
  67. package/node_modules/@poe-code/design-system/dist/explorer/runtime.test-helpers.js +101 -0
  68. package/node_modules/@poe-code/design-system/dist/explorer/state.d.ts +130 -0
  69. package/node_modules/@poe-code/design-system/dist/explorer/state.js +87 -0
  70. package/node_modules/@poe-code/design-system/dist/explorer/theme.d.ts +27 -0
  71. package/node_modules/@poe-code/design-system/dist/explorer/theme.js +97 -0
  72. package/node_modules/@poe-code/design-system/dist/index.d.ts +7 -0
  73. package/node_modules/@poe-code/design-system/dist/index.js +5 -0
  74. package/node_modules/@poe-code/design-system/dist/internal/color-support.d.ts +9 -0
  75. package/node_modules/@poe-code/design-system/dist/internal/color-support.js +12 -0
  76. package/node_modules/@poe-code/design-system/dist/prompts/index.js +2 -2
  77. package/node_modules/@poe-code/design-system/dist/prompts/primitives/cancel.js +2 -2
  78. package/node_modules/@poe-code/design-system/dist/prompts/primitives/intro.js +2 -2
  79. package/node_modules/@poe-code/design-system/dist/prompts/primitives/log.js +4 -4
  80. package/node_modules/@poe-code/design-system/dist/prompts/primitives/note.js +5 -5
  81. package/node_modules/@poe-code/design-system/dist/prompts/primitives/outro.js +2 -2
  82. package/node_modules/@poe-code/design-system/dist/prompts/primitives/spinner.js +3 -3
  83. package/node_modules/@poe-code/design-system/dist/static/menu.js +5 -5
  84. package/node_modules/@poe-code/design-system/dist/static/spinner.js +8 -8
  85. package/node_modules/@poe-code/design-system/dist/tokens/colors.js +29 -29
  86. package/node_modules/@poe-code/design-system/dist/tokens/typography.js +6 -6
  87. package/node_modules/@poe-code/design-system/package.json +6 -3
  88. package/package.json +2 -4
@@ -1,4 +1,4 @@
1
- import chalk from "chalk";
1
+ import { color } from "../components/color.js";
2
2
  import { resolveOutputFormat } from "../internal/output-format.js";
3
3
  import { renderMarkdown } from "../terminal-markdown/index.js";
4
4
  import { getAcpWriter } from "./writer.js";
@@ -10,20 +10,22 @@ function truncate(text, maxLength) {
10
10
  return `${text.slice(0, maxLength - 3)}...`;
11
11
  }
12
12
  const KIND_COLORS = {
13
- exec: (text) => chalk.yellow(text),
14
- edit: (text) => chalk.magenta(text),
15
- read: (text) => chalk.cyan(text),
16
- search: (text) => chalk.blue(text),
17
- think: (text) => chalk.dim(text),
18
- other: (text) => chalk.dim(text)
13
+ exec: (text) => color.yellow(text),
14
+ edit: (text) => color.magenta(text),
15
+ read: (text) => color.cyan(text),
16
+ search: (text) => color.blue(text),
17
+ think: (text) => color.dim(text),
18
+ other: (text) => color.dim(text)
19
19
  };
20
20
  function colorForKind(kind) {
21
- return KIND_COLORS[kind] ?? ((text) => chalk.dim(text));
21
+ return KIND_COLORS[kind] ?? ((text) => color.dim(text));
22
22
  }
23
23
  function writeLine(line) {
24
24
  getAcpWriter()(line);
25
25
  }
26
- const AGENT_PREFIX = `${chalk.green.bold("✓")} agent: `;
26
+ function agentPrefix() {
27
+ return `${color.green.bold("✓")} agent: `;
28
+ }
27
29
  function formatCost(costUsd) {
28
30
  return new Intl.NumberFormat("en-US", {
29
31
  style: "currency",
@@ -43,7 +45,7 @@ export function renderAgentMessage(text) {
43
45
  return;
44
46
  }
45
47
  const rendered = renderMarkdown(text).trimEnd();
46
- writeLine(`${AGENT_PREFIX}${rendered}`);
48
+ writeLine(`${agentPrefix()}${rendered}`);
47
49
  }
48
50
  export function renderToolStart(kind, title) {
49
51
  const format = resolveOutputFormat();
@@ -81,7 +83,7 @@ export function renderReasoning(text) {
81
83
  writeLine(JSON.stringify({ event: "reasoning", text }));
82
84
  return;
83
85
  }
84
- writeLine(chalk.dim(` ✓ ${truncate(text, 80)}`));
86
+ writeLine(color.dim(` ✓ ${truncate(text, 80)}`));
85
87
  }
86
88
  export function renderUsage(tokens) {
87
89
  const format = resolveOutputFormat();
@@ -105,7 +107,7 @@ export function renderUsage(tokens) {
105
107
  return;
106
108
  }
107
109
  writeLine("");
108
- writeLine(chalk.green(`✓ tokens: ${tokens.input} in${cached} → ${tokens.output} out${cost}`));
110
+ writeLine(color.green(`✓ tokens: ${tokens.input} in${cached} → ${tokens.output} out${cost}`));
109
111
  }
110
112
  export function renderError(message) {
111
113
  const format = resolveOutputFormat();
@@ -117,5 +119,5 @@ export function renderError(message) {
117
119
  writeLine(JSON.stringify({ event: "error", message }));
118
120
  return;
119
121
  }
120
- writeLine(chalk.red(`✗ ${message}`));
122
+ writeLine(color.red(`✗ ${message}`));
121
123
  }
@@ -0,0 +1,31 @@
1
+ export interface Color {
2
+ (text: string): string;
3
+ reset: Color;
4
+ bold: Color;
5
+ dim: Color;
6
+ italic: Color;
7
+ underline: Color;
8
+ inverse: Color;
9
+ strikethrough: Color;
10
+ black: Color;
11
+ red: Color;
12
+ green: Color;
13
+ yellow: Color;
14
+ blue: Color;
15
+ magenta: Color;
16
+ cyan: Color;
17
+ white: Color;
18
+ gray: Color;
19
+ magentaBright: Color;
20
+ cyanBright: Color;
21
+ bgRed: Color;
22
+ bgGreen: Color;
23
+ bgYellow: Color;
24
+ bgBlue: Color;
25
+ bgMagenta: Color;
26
+ hex: (value: string) => Color;
27
+ rgb: (red: number, green: number, blue: number) => Color;
28
+ bgHex: (value: string) => Color;
29
+ bgRgb: (red: number, green: number, blue: number) => Color;
30
+ }
31
+ export declare const color: Color;
@@ -0,0 +1,101 @@
1
+ import { supportsColor } from "../internal/color-support.js";
2
+ const reset = "\x1b[0m";
3
+ const ansiStyles = {
4
+ reset: { open: reset },
5
+ bold: { open: "\x1b[1m" },
6
+ dim: { open: "\x1b[2m" },
7
+ italic: { open: "\x1b[3m" },
8
+ underline: { open: "\x1b[4m" },
9
+ inverse: { open: "\x1b[7m" },
10
+ strikethrough: { open: "\x1b[9m" },
11
+ black: { open: "\x1b[30m" },
12
+ red: { open: "\x1b[31m" },
13
+ green: { open: "\x1b[32m" },
14
+ yellow: { open: "\x1b[33m" },
15
+ blue: { open: "\x1b[34m" },
16
+ magenta: { open: "\x1b[35m" },
17
+ cyan: { open: "\x1b[36m" },
18
+ white: { open: "\x1b[37m" },
19
+ gray: { open: "\x1b[90m" },
20
+ magentaBright: { open: "\x1b[95m" },
21
+ cyanBright: { open: "\x1b[96m" },
22
+ bgRed: { open: "\x1b[41m" },
23
+ bgGreen: { open: "\x1b[42m" },
24
+ bgYellow: { open: "\x1b[43m" },
25
+ bgBlue: { open: "\x1b[44m" },
26
+ bgMagenta: { open: "\x1b[45m" }
27
+ };
28
+ const styleNames = Object.keys(ansiStyles);
29
+ function replaceAll(value, search, replacement) {
30
+ return value.split(search).join(replacement);
31
+ }
32
+ function applyStyles(text, styles) {
33
+ if (!supportsColor() || styles.length === 0) {
34
+ return text;
35
+ }
36
+ const open = styles.map((style) => style.open).join("");
37
+ const output = text.includes(reset) ? replaceAll(text, reset, `${reset}${open}`) : text;
38
+ return `${open}${output}${reset}`;
39
+ }
40
+ function clampRgb(value) {
41
+ if (Number.isNaN(value)) {
42
+ return 0;
43
+ }
44
+ return Math.min(255, Math.max(0, Math.round(value)));
45
+ }
46
+ function hexChannel(value, offset) {
47
+ return Number.parseInt(value.slice(offset, offset + 2), 16);
48
+ }
49
+ function normalizeHex(value) {
50
+ const normalized = value.startsWith("#") ? value.slice(1) : value;
51
+ if (normalized.length === 3) {
52
+ const red = normalized[0];
53
+ const green = normalized[1];
54
+ const blue = normalized[2];
55
+ return [
56
+ Number.parseInt(`${red}${red}`, 16),
57
+ Number.parseInt(`${green}${green}`, 16),
58
+ Number.parseInt(`${blue}${blue}`, 16)
59
+ ];
60
+ }
61
+ if (normalized.length === 6) {
62
+ return [
63
+ hexChannel(normalized, 0),
64
+ hexChannel(normalized, 2),
65
+ hexChannel(normalized, 4)
66
+ ];
67
+ }
68
+ return [0, 0, 0];
69
+ }
70
+ function rgbStyle(red, green, blue) {
71
+ return {
72
+ open: `\x1b[38;2;${clampRgb(red)};${clampRgb(green)};${clampRgb(blue)}m`
73
+ };
74
+ }
75
+ function bgRgbStyle(red, green, blue) {
76
+ return {
77
+ open: `\x1b[48;2;${clampRgb(red)};${clampRgb(green)};${clampRgb(blue)}m`
78
+ };
79
+ }
80
+ function createColor(styles = []) {
81
+ const builder = ((text) => applyStyles(String(text), styles));
82
+ for (const name of styleNames) {
83
+ Object.defineProperty(builder, name, {
84
+ configurable: true,
85
+ enumerable: true,
86
+ get: () => createColor([...styles, ansiStyles[name]])
87
+ });
88
+ }
89
+ builder.hex = (value) => {
90
+ const [red, green, blue] = normalizeHex(value);
91
+ return createColor([...styles, rgbStyle(red, green, blue)]);
92
+ };
93
+ builder.rgb = (red, green, blue) => createColor([...styles, rgbStyle(red, green, blue)]);
94
+ builder.bgHex = (value) => {
95
+ const [red, green, blue] = normalizeHex(value);
96
+ return createColor([...styles, bgRgbStyle(red, green, blue)]);
97
+ };
98
+ builder.bgRgb = (red, green, blue) => createColor([...styles, bgRgbStyle(red, green, blue)]);
99
+ return builder;
100
+ }
101
+ export const color = createColor();
@@ -1,4 +1,5 @@
1
1
  import type { CommandInfo, FormatColumnsOptions, OptionInfo } from "./help-formatter.js";
2
+ export declare function stripAnsi(value: string): string;
2
3
  export declare function formatColumns(opts: FormatColumnsOptions): string;
3
4
  export declare function formatCommandList(commands: CommandInfo[]): string;
4
5
  export declare function formatOptionList(options: OptionInfo[]): string;
@@ -1,4 +1,4 @@
1
- function stripAnsi(value) {
1
+ export function stripAnsi(value) {
2
2
  let output = "";
3
3
  for (let index = 0; index < value.length; index += 1) {
4
4
  if (value[index] === "\u001b") {
@@ -1,4 +1,6 @@
1
1
  export { text } from "./text.js";
2
+ export { color } from "./color.js";
3
+ export type { Color } from "./color.js";
2
4
  export { symbols } from "./symbols.js";
3
5
  export { createLogger, logger } from "./logger.js";
4
6
  export type { LoggerOutput } from "./logger.js";
@@ -8,3 +10,5 @@ export { formatCommandNotFound } from "./command-errors.js";
8
10
  export { formatCommandNotFoundPanel } from "./command-errors.js";
9
11
  export { renderTable } from "./table.js";
10
12
  export type { TableColumn, RenderTableOptions } from "./table.js";
13
+ export { renderTemplate } from "./template.js";
14
+ export type { RenderTemplateOptions, TemplateEscape } from "./template.js";
@@ -1,7 +1,9 @@
1
1
  export { text } from "./text.js";
2
+ export { color } from "./color.js";
2
3
  export { symbols } from "./symbols.js";
3
4
  export { createLogger, logger } from "./logger.js";
4
5
  export { helpFormatter, formatColumns, formatCommand, formatUsage, formatOption, formatCommandList, formatOptionList } from "./help-formatter.js";
5
6
  export { formatCommandNotFound } from "./command-errors.js";
6
7
  export { formatCommandNotFoundPanel } from "./command-errors.js";
7
8
  export { renderTable } from "./table.js";
9
+ export { renderTemplate } from "./template.js";
@@ -1,4 +1,4 @@
1
- import chalk from "chalk";
1
+ import { color } from "./color.js";
2
2
  import { log } from "../prompts/primitives/log.js";
3
3
  import { symbols } from "./symbols.js";
4
4
  export function createLogger(emitter) {
@@ -53,7 +53,7 @@ export function createLogger(emitter) {
53
53
  emitter(message);
54
54
  return;
55
55
  }
56
- log.message(message, { symbol: symbol ?? chalk.gray("│") });
56
+ log.message(message, { symbol: symbol ?? color.gray("│") });
57
57
  }
58
58
  };
59
59
  }
@@ -1,4 +1,4 @@
1
- import chalk from "chalk";
1
+ import { color } from "./color.js";
2
2
  import { resolveOutputFormat } from "../internal/output-format.js";
3
3
  import { getTheme } from "../internal/theme-detect.js";
4
4
  export const symbols = {
@@ -8,7 +8,7 @@ export const symbols = {
8
8
  return "info";
9
9
  if (format === "markdown")
10
10
  return "(i)";
11
- return chalk.magenta("●");
11
+ return color.magenta("●");
12
12
  },
13
13
  get success() {
14
14
  const format = resolveOutputFormat();
@@ -16,7 +16,7 @@ export const symbols = {
16
16
  return "success";
17
17
  if (format === "markdown")
18
18
  return "[ok]";
19
- return chalk.magenta("◆");
19
+ return color.magenta("◆");
20
20
  },
21
21
  get resolved() {
22
22
  const format = resolveOutputFormat();
@@ -1,52 +1,203 @@
1
- import { Table } from "console-table-printer";
2
1
  import { resolveOutputFormat } from "../internal/output-format.js";
3
2
  import { stripAnsi } from "../internal/strip-ansi.js";
3
+ const reset = "\x1b[0m";
4
+ const ellipsis = "…";
5
+ const graphemeSegmenter = new Intl.Segmenter(undefined, { granularity: "grapheme" });
6
+ function isAnsiSequence(value, index) {
7
+ return value[index] === "\u001b" && value[index + 1] === "[";
8
+ }
9
+ function readAnsiSequence(value, index) {
10
+ let nextIndex = index + 2;
11
+ while (nextIndex < value.length && value[nextIndex] !== "m") {
12
+ nextIndex += 1;
13
+ }
14
+ if (nextIndex < value.length) {
15
+ nextIndex += 1;
16
+ }
17
+ return { sequence: value.slice(index, nextIndex), nextIndex };
18
+ }
19
+ function isCombiningCodePoint(codePoint) {
20
+ return ((codePoint >= 0x0300 && codePoint <= 0x036f) ||
21
+ (codePoint >= 0x1ab0 && codePoint <= 0x1aff) ||
22
+ (codePoint >= 0x1dc0 && codePoint <= 0x1dff) ||
23
+ (codePoint >= 0x20d0 && codePoint <= 0x20ff) ||
24
+ (codePoint >= 0xfe20 && codePoint <= 0xfe2f));
25
+ }
26
+ function isWideCodePoint(codePoint) {
27
+ return ((codePoint >= 0x1100 && codePoint <= 0x115f) ||
28
+ codePoint === 0x2329 ||
29
+ codePoint === 0x232a ||
30
+ (codePoint >= 0x2e80 && codePoint <= 0xa4cf && codePoint !== 0x303f) ||
31
+ (codePoint >= 0xac00 && codePoint <= 0xd7a3) ||
32
+ (codePoint >= 0xf900 && codePoint <= 0xfaff) ||
33
+ (codePoint >= 0xfe10 && codePoint <= 0xfe19) ||
34
+ (codePoint >= 0xfe30 && codePoint <= 0xfe6f) ||
35
+ (codePoint >= 0xff00 && codePoint <= 0xff60) ||
36
+ (codePoint >= 0xffe0 && codePoint <= 0xffe6) ||
37
+ (codePoint >= 0x2600 && codePoint <= 0x27bf) ||
38
+ (codePoint >= 0x1f300 && codePoint <= 0x1faff) ||
39
+ (codePoint >= 0x20000 && codePoint <= 0x3fffd));
40
+ }
41
+ function isEmojiClusterCodePoint(codePoint) {
42
+ return ((codePoint >= 0x1f1e6 && codePoint <= 0x1f1ff) ||
43
+ (codePoint >= 0x1f300 && codePoint <= 0x1faff) ||
44
+ (codePoint >= 0x2600 && codePoint <= 0x27bf));
45
+ }
46
+ function codePointWidth(char) {
47
+ const codePoint = char.codePointAt(0) ?? 0;
48
+ if (codePoint === 0 || codePoint < 0x20 || (codePoint >= 0x7f && codePoint < 0xa0)) {
49
+ return 0;
50
+ }
51
+ if (codePoint === 0x200d ||
52
+ (codePoint >= 0xfe00 && codePoint <= 0xfe0f) ||
53
+ isCombiningCodePoint(codePoint)) {
54
+ return 0;
55
+ }
56
+ return isWideCodePoint(codePoint) ? 2 : 1;
57
+ }
58
+ function readPrintableCluster(value, index) {
59
+ const nextAnsiIndex = value.indexOf("\u001b[", index);
60
+ const plainText = value.slice(index, nextAnsiIndex === -1 ? undefined : nextAnsiIndex);
61
+ const firstSegment = graphemeSegmenter.segment(plainText)[Symbol.iterator]().next().value;
62
+ return firstSegment?.segment ?? Array.from(plainText)[0] ?? "";
63
+ }
64
+ function clusterWidth(cluster) {
65
+ const codePoints = Array.from(cluster).map((char) => char.codePointAt(0) ?? 0);
66
+ const isEmojiCluster = codePoints.length > 1 &&
67
+ codePoints.some((codePoint) => codePoint === 0x200d ||
68
+ (codePoint >= 0xfe00 && codePoint <= 0xfe0f) ||
69
+ isEmojiClusterCodePoint(codePoint));
70
+ if (isEmojiCluster) {
71
+ return 2;
72
+ }
73
+ return codePoints.reduce((width, codePoint) => width + codePointWidth(String.fromCodePoint(codePoint)), 0);
74
+ }
75
+ function displayWidth(value) {
76
+ let width = 0;
77
+ let index = 0;
78
+ while (index < value.length) {
79
+ if (isAnsiSequence(value, index)) {
80
+ index = readAnsiSequence(value, index).nextIndex;
81
+ continue;
82
+ }
83
+ const cluster = readPrintableCluster(value, index);
84
+ width += clusterWidth(cluster);
85
+ index += cluster.length;
86
+ }
87
+ return width;
88
+ }
89
+ function truncateToWidth(value, width) {
90
+ if (displayWidth(value) <= width) {
91
+ return value;
92
+ }
93
+ if (width <= 0) {
94
+ return "";
95
+ }
96
+ const targetWidth = width <= 1 ? 0 : width - displayWidth(ellipsis);
97
+ let output = "";
98
+ let currentWidth = 0;
99
+ let index = 0;
100
+ let sawAnsi = false;
101
+ while (index < value.length) {
102
+ if (isAnsiSequence(value, index)) {
103
+ const ansi = readAnsiSequence(value, index);
104
+ sawAnsi = true;
105
+ output += ansi.sequence;
106
+ index = ansi.nextIndex;
107
+ continue;
108
+ }
109
+ const cluster = readPrintableCluster(value, index);
110
+ const width = clusterWidth(cluster);
111
+ if (currentWidth + width > targetWidth) {
112
+ break;
113
+ }
114
+ output += cluster;
115
+ currentWidth += width;
116
+ index += cluster.length;
117
+ }
118
+ return `${output}${ellipsis}${sawAnsi ? reset : ""}`;
119
+ }
120
+ function padCell(value, width, alignment) {
121
+ const visibleWidth = displayWidth(value);
122
+ const padding = Math.max(0, width - visibleWidth);
123
+ if (alignment === "right") {
124
+ return `${" ".repeat(padding)}${value}`;
125
+ }
126
+ if (alignment === "center") {
127
+ const left = Math.floor(padding / 2);
128
+ const right = padding - left;
129
+ return `${" ".repeat(left)}${value}${" ".repeat(right)}`;
130
+ }
131
+ return `${value}${" ".repeat(padding)}`;
132
+ }
133
+ function getAlignment(column) {
134
+ const alignment = column.alignment;
135
+ return alignment === "right" || alignment === "center" ? alignment : "left";
136
+ }
137
+ function getColumnWidth(column) {
138
+ const configuredMin = column.minLen;
139
+ const minWidth = Math.max(1, configuredMin ?? 1);
140
+ return Math.max(minWidth, column.maxLen);
141
+ }
142
+ function computeColumns(columns) {
143
+ return columns.map((column) => ({
144
+ name: column.name,
145
+ title: column.title,
146
+ alignment: getAlignment(column),
147
+ width: getColumnWidth(column)
148
+ }));
149
+ }
150
+ function renderBorder(columns, theme, parts) {
151
+ const horizontal = theme.muted("─");
152
+ const segments = columns.map((column) => horizontal.repeat(column.width + 2));
153
+ return [
154
+ theme.muted(parts.left),
155
+ segments.join(theme.muted(parts.mid)),
156
+ theme.muted(parts.right)
157
+ ].join("");
158
+ }
159
+ function renderTerminalRow(values, columns, theme) {
160
+ const vertical = theme.muted("│");
161
+ const cells = values.map((value, index) => {
162
+ const column = columns[index];
163
+ const truncated = truncateToWidth(value, column.width);
164
+ return ` ${padCell(truncated, column.width, column.alignment)} `;
165
+ });
166
+ return `${vertical}${cells.join(vertical)}${vertical}`;
167
+ }
4
168
  function renderTableTerminal(options) {
5
169
  const { theme, columns, rows } = options;
6
- const table = new Table({
7
- style: {
8
- headerTop: {
9
- left: theme.muted("┌"),
10
- mid: theme.muted("┬"),
11
- right: theme.muted(""),
12
- other: theme.muted("")
13
- },
14
- headerBottom: {
15
- left: theme.muted("├"),
16
- mid: theme.muted("┼"),
17
- right: theme.muted("┤"),
18
- other: theme.muted("")
19
- },
20
- tableBottom: {
21
- left: theme.muted("└"),
22
- mid: theme.muted("┴"),
23
- right: theme.muted("┘"),
24
- other: theme.muted("─")
25
- },
26
- vertical: theme.muted("│"),
27
- rowSeparator: {
28
- left: theme.muted("├"),
29
- mid: theme.muted("┼"),
30
- right: theme.muted("┤"),
31
- other: theme.muted("─")
32
- }
33
- },
34
- columns: columns.map((col) => ({
35
- name: col.name,
36
- title: theme.header(col.title),
37
- alignment: col.alignment,
38
- maxLen: col.maxLen
39
- }))
40
- });
41
- for (const row of rows) {
42
- table.addRow(row);
170
+ const computedColumns = computeColumns(columns);
171
+ const separatorOptions = options;
172
+ const includeRowSeparators = separatorOptions.rowSeparator === true || separatorOptions.rowSeparators === true;
173
+ const top = renderBorder(computedColumns, theme, { left: "┌", mid: "┬", right: "┐" });
174
+ const header = renderTerminalRow(computedColumns.map((column) => theme.header(column.title)), computedColumns, theme);
175
+ const headerBottom = renderBorder(computedColumns, theme, { left: "├", mid: "┼", right: "" });
176
+ const bottom = renderBorder(computedColumns, theme, { left: "", mid: "┴", right: "┘" });
177
+ const renderedRows = [];
178
+ for (const [index, row] of rows.entries()) {
179
+ if (includeRowSeparators && index > 0) {
180
+ renderedRows.push(headerBottom);
181
+ }
182
+ renderedRows.push(renderTerminalRow(computedColumns.map((column) => row[column.name] ?? ""), computedColumns, theme));
43
183
  }
44
- return table.render();
184
+ return [top, header, headerBottom, ...renderedRows, bottom].join("\n");
45
185
  }
46
186
  function renderTableMarkdown(options) {
47
187
  const { columns, rows } = options;
48
188
  const header = `| ${columns.map((c) => c.title).join(" | ")} |`;
49
- const separator = `| ${columns.map((c) => (c.alignment === "right" ? "---:" : ":---")).join(" | ")} |`;
189
+ const separator = `| ${columns
190
+ .map((c) => {
191
+ const alignment = getAlignment(c);
192
+ if (alignment === "right") {
193
+ return "---:";
194
+ }
195
+ if (alignment === "center") {
196
+ return ":---:";
197
+ }
198
+ return ":---";
199
+ })
200
+ .join(" | ")} |`;
50
201
  const dataRows = rows.map((row) => `| ${columns.map((c) => stripAnsi(row[c.name] ?? "").replace(/\|/g, "\\|")).join(" | ")} |`);
51
202
  return [header, separator, ...dataRows].join("\n");
52
203
  }
@@ -0,0 +1,6 @@
1
+ export type TemplateEscape = "html" | "none";
2
+ export interface RenderTemplateOptions {
3
+ escape?: TemplateEscape;
4
+ yield?: string;
5
+ }
6
+ export declare function renderTemplate(template: string, view: Record<string, unknown>, options?: RenderTemplateOptions): string;