toolcraft 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/README.md +91 -0
  2. package/dist/cli.compile-check.d.ts +1 -0
  3. package/dist/cli.compile-check.js +26 -0
  4. package/dist/cli.d.ts +12 -0
  5. package/dist/cli.js +1312 -0
  6. package/dist/index.compile-check.d.ts +1 -0
  7. package/dist/index.compile-check.js +50 -0
  8. package/dist/index.d.ts +164 -0
  9. package/dist/index.js +366 -0
  10. package/dist/mcp.compile-check.d.ts +1 -0
  11. package/dist/mcp.compile-check.js +26 -0
  12. package/dist/mcp.d.ts +31 -0
  13. package/dist/mcp.js +354 -0
  14. package/dist/number-schema.d.ts +3 -0
  15. package/dist/number-schema.js +8 -0
  16. package/dist/renderer.d.ts +5 -0
  17. package/dist/renderer.js +148 -0
  18. package/dist/schema-scope.d.ts +4 -0
  19. package/dist/schema-scope.js +34 -0
  20. package/dist/sdk.compile-check.d.ts +1 -0
  21. package/dist/sdk.compile-check.js +79 -0
  22. package/dist/sdk.d.ts +63 -0
  23. package/dist/sdk.js +218 -0
  24. package/node_modules/@poe-code/design-system/dist/acp/components.d.ts +11 -0
  25. package/node_modules/@poe-code/design-system/dist/acp/components.js +121 -0
  26. package/node_modules/@poe-code/design-system/dist/acp/index.d.ts +3 -0
  27. package/node_modules/@poe-code/design-system/dist/acp/index.js +2 -0
  28. package/node_modules/@poe-code/design-system/dist/acp/writer.d.ts +13 -0
  29. package/node_modules/@poe-code/design-system/dist/acp/writer.js +21 -0
  30. package/node_modules/@poe-code/design-system/dist/components/command-errors.d.ts +16 -0
  31. package/node_modules/@poe-code/design-system/dist/components/command-errors.js +22 -0
  32. package/node_modules/@poe-code/design-system/dist/components/help-formatter.d.ts +20 -0
  33. package/node_modules/@poe-code/design-system/dist/components/help-formatter.js +27 -0
  34. package/node_modules/@poe-code/design-system/dist/components/index.d.ts +10 -0
  35. package/node_modules/@poe-code/design-system/dist/components/index.js +7 -0
  36. package/node_modules/@poe-code/design-system/dist/components/logger.d.ts +11 -0
  37. package/node_modules/@poe-code/design-system/dist/components/logger.js +60 -0
  38. package/node_modules/@poe-code/design-system/dist/components/symbols.d.ts +12 -0
  39. package/node_modules/@poe-code/design-system/dist/components/symbols.js +71 -0
  40. package/node_modules/@poe-code/design-system/dist/components/table.d.ts +13 -0
  41. package/node_modules/@poe-code/design-system/dist/components/table.js +74 -0
  42. package/node_modules/@poe-code/design-system/dist/components/text.d.ts +14 -0
  43. package/node_modules/@poe-code/design-system/dist/components/text.js +104 -0
  44. package/node_modules/@poe-code/design-system/dist/dashboard/ansi.d.ts +18 -0
  45. package/node_modules/@poe-code/design-system/dist/dashboard/ansi.js +298 -0
  46. package/node_modules/@poe-code/design-system/dist/dashboard/buffer.d.ts +25 -0
  47. package/node_modules/@poe-code/design-system/dist/dashboard/buffer.js +189 -0
  48. package/node_modules/@poe-code/design-system/dist/dashboard/components/border.d.ts +9 -0
  49. package/node_modules/@poe-code/design-system/dist/dashboard/components/border.js +123 -0
  50. package/node_modules/@poe-code/design-system/dist/dashboard/components/footer.d.ts +8 -0
  51. package/node_modules/@poe-code/design-system/dist/dashboard/components/footer.js +57 -0
  52. package/node_modules/@poe-code/design-system/dist/dashboard/components/output-pane.d.ts +12 -0
  53. package/node_modules/@poe-code/design-system/dist/dashboard/components/output-pane.js +254 -0
  54. package/node_modules/@poe-code/design-system/dist/dashboard/components/stats-pane.d.ts +7 -0
  55. package/node_modules/@poe-code/design-system/dist/dashboard/components/stats-pane.js +121 -0
  56. package/node_modules/@poe-code/design-system/dist/dashboard/dashboard.d.ts +20 -0
  57. package/node_modules/@poe-code/design-system/dist/dashboard/dashboard.js +167 -0
  58. package/node_modules/@poe-code/design-system/dist/dashboard/demo.d.ts +13 -0
  59. package/node_modules/@poe-code/design-system/dist/dashboard/demo.js +145 -0
  60. package/node_modules/@poe-code/design-system/dist/dashboard/index.d.ts +8 -0
  61. package/node_modules/@poe-code/design-system/dist/dashboard/index.js +4 -0
  62. package/node_modules/@poe-code/design-system/dist/dashboard/keymap.d.ts +3 -0
  63. package/node_modules/@poe-code/design-system/dist/dashboard/keymap.js +99 -0
  64. package/node_modules/@poe-code/design-system/dist/dashboard/layout.d.ts +25 -0
  65. package/node_modules/@poe-code/design-system/dist/dashboard/layout.js +79 -0
  66. package/node_modules/@poe-code/design-system/dist/dashboard/should-use-dashboard.d.ts +10 -0
  67. package/node_modules/@poe-code/design-system/dist/dashboard/should-use-dashboard.js +7 -0
  68. package/node_modules/@poe-code/design-system/dist/dashboard/snapshot.d.ts +10 -0
  69. package/node_modules/@poe-code/design-system/dist/dashboard/snapshot.js +68 -0
  70. package/node_modules/@poe-code/design-system/dist/dashboard/store.d.ts +8 -0
  71. package/node_modules/@poe-code/design-system/dist/dashboard/store.js +51 -0
  72. package/node_modules/@poe-code/design-system/dist/dashboard/terminal.d.ts +37 -0
  73. package/node_modules/@poe-code/design-system/dist/dashboard/terminal.js +233 -0
  74. package/node_modules/@poe-code/design-system/dist/dashboard/types.d.ts +36 -0
  75. package/node_modules/@poe-code/design-system/dist/dashboard/types.js +1 -0
  76. package/node_modules/@poe-code/design-system/dist/index.d.ts +33 -0
  77. package/node_modules/@poe-code/design-system/dist/index.js +31 -0
  78. package/node_modules/@poe-code/design-system/dist/internal/output-format.d.ts +6 -0
  79. package/node_modules/@poe-code/design-system/dist/internal/output-format.js +22 -0
  80. package/node_modules/@poe-code/design-system/dist/internal/strip-ansi.d.ts +1 -0
  81. package/node_modules/@poe-code/design-system/dist/internal/strip-ansi.js +3 -0
  82. package/node_modules/@poe-code/design-system/dist/internal/theme-detect.d.ts +11 -0
  83. package/node_modules/@poe-code/design-system/dist/internal/theme-detect.js +49 -0
  84. package/node_modules/@poe-code/design-system/dist/prompts/index.d.ts +66 -0
  85. package/node_modules/@poe-code/design-system/dist/prompts/index.js +132 -0
  86. package/node_modules/@poe-code/design-system/dist/prompts/primitives/cancel.d.ts +2 -0
  87. package/node_modules/@poe-code/design-system/dist/prompts/primitives/cancel.js +9 -0
  88. package/node_modules/@poe-code/design-system/dist/prompts/primitives/intro.d.ts +1 -0
  89. package/node_modules/@poe-code/design-system/dist/prompts/primitives/intro.js +15 -0
  90. package/node_modules/@poe-code/design-system/dist/prompts/primitives/log.d.ts +18 -0
  91. package/node_modules/@poe-code/design-system/dist/prompts/primitives/log.js +101 -0
  92. package/node_modules/@poe-code/design-system/dist/prompts/primitives/note.d.ts +1 -0
  93. package/node_modules/@poe-code/design-system/dist/prompts/primitives/note.js +39 -0
  94. package/node_modules/@poe-code/design-system/dist/prompts/primitives/outro.d.ts +1 -0
  95. package/node_modules/@poe-code/design-system/dist/prompts/primitives/outro.js +16 -0
  96. package/node_modules/@poe-code/design-system/dist/prompts/primitives/spinner.d.ts +6 -0
  97. package/node_modules/@poe-code/design-system/dist/prompts/primitives/spinner.js +74 -0
  98. package/node_modules/@poe-code/design-system/dist/prompts/theme.d.ts +11 -0
  99. package/node_modules/@poe-code/design-system/dist/prompts/theme.js +12 -0
  100. package/node_modules/@poe-code/design-system/dist/static/index.d.ts +4 -0
  101. package/node_modules/@poe-code/design-system/dist/static/index.js +2 -0
  102. package/node_modules/@poe-code/design-system/dist/static/menu.d.ts +11 -0
  103. package/node_modules/@poe-code/design-system/dist/static/menu.js +36 -0
  104. package/node_modules/@poe-code/design-system/dist/static/spinner.d.ts +14 -0
  105. package/node_modules/@poe-code/design-system/dist/static/spinner.js +46 -0
  106. package/node_modules/@poe-code/design-system/dist/terminal-markdown/ast.d.ts +92 -0
  107. package/node_modules/@poe-code/design-system/dist/terminal-markdown/ast.js +1 -0
  108. package/node_modules/@poe-code/design-system/dist/terminal-markdown/demo-content.d.ts +2 -0
  109. package/node_modules/@poe-code/design-system/dist/terminal-markdown/demo-content.js +139 -0
  110. package/node_modules/@poe-code/design-system/dist/terminal-markdown/index.d.ts +6 -0
  111. package/node_modules/@poe-code/design-system/dist/terminal-markdown/index.js +8 -0
  112. package/node_modules/@poe-code/design-system/dist/terminal-markdown/parser/block.d.ts +7 -0
  113. package/node_modules/@poe-code/design-system/dist/terminal-markdown/parser/block.js +1495 -0
  114. package/node_modules/@poe-code/design-system/dist/terminal-markdown/parser/frontmatter.d.ts +8 -0
  115. package/node_modules/@poe-code/design-system/dist/terminal-markdown/parser/frontmatter.js +412 -0
  116. package/node_modules/@poe-code/design-system/dist/terminal-markdown/parser/inline.d.ts +10 -0
  117. package/node_modules/@poe-code/design-system/dist/terminal-markdown/parser/inline.js +1166 -0
  118. package/node_modules/@poe-code/design-system/dist/terminal-markdown/parser.d.ts +5 -0
  119. package/node_modules/@poe-code/design-system/dist/terminal-markdown/parser.js +42 -0
  120. package/node_modules/@poe-code/design-system/dist/terminal-markdown/renderer.d.ts +6 -0
  121. package/node_modules/@poe-code/design-system/dist/terminal-markdown/renderer.js +572 -0
  122. package/node_modules/@poe-code/design-system/dist/terminal-markdown/testing/theme-render-fixture.d.ts +1 -0
  123. package/node_modules/@poe-code/design-system/dist/terminal-markdown/testing/theme-render-fixture.js +27 -0
  124. package/node_modules/@poe-code/design-system/dist/tokens/colors.d.ts +35 -0
  125. package/node_modules/@poe-code/design-system/dist/tokens/colors.js +34 -0
  126. package/node_modules/@poe-code/design-system/dist/tokens/index.d.ts +4 -0
  127. package/node_modules/@poe-code/design-system/dist/tokens/index.js +4 -0
  128. package/node_modules/@poe-code/design-system/dist/tokens/spacing.d.ts +6 -0
  129. package/node_modules/@poe-code/design-system/dist/tokens/spacing.js +6 -0
  130. package/node_modules/@poe-code/design-system/dist/tokens/typography.d.ts +7 -0
  131. package/node_modules/@poe-code/design-system/dist/tokens/typography.js +8 -0
  132. package/node_modules/@poe-code/design-system/dist/tokens/widths.d.ts +5 -0
  133. package/node_modules/@poe-code/design-system/dist/tokens/widths.js +5 -0
  134. package/node_modules/@poe-code/design-system/package.json +25 -0
  135. package/package.json +57 -0
@@ -0,0 +1,71 @@
1
+ import chalk from "chalk";
2
+ import { resolveOutputFormat } from "../internal/output-format.js";
3
+ import { getTheme } from "../internal/theme-detect.js";
4
+ export const symbols = {
5
+ get info() {
6
+ const format = resolveOutputFormat();
7
+ if (format === "json")
8
+ return "info";
9
+ if (format === "markdown")
10
+ return "(i)";
11
+ return chalk.magenta("●");
12
+ },
13
+ get success() {
14
+ const format = resolveOutputFormat();
15
+ if (format === "json")
16
+ return "success";
17
+ if (format === "markdown")
18
+ return "[ok]";
19
+ return chalk.magenta("◆");
20
+ },
21
+ get resolved() {
22
+ const format = resolveOutputFormat();
23
+ if (format === "json")
24
+ return "resolved";
25
+ if (format === "markdown")
26
+ return ">";
27
+ return getTheme().resolvedSymbol;
28
+ },
29
+ get errorResolved() {
30
+ const format = resolveOutputFormat();
31
+ if (format === "json")
32
+ return "error";
33
+ if (format === "markdown")
34
+ return "[!]";
35
+ return getTheme().errorSymbol;
36
+ },
37
+ get bar() {
38
+ const format = resolveOutputFormat();
39
+ if (format === "json")
40
+ return "";
41
+ if (format === "markdown")
42
+ return "|";
43
+ return "│";
44
+ },
45
+ cornerTopRight: "╮",
46
+ cornerBottomRight: "╯",
47
+ get warning() {
48
+ const format = resolveOutputFormat();
49
+ if (format === "json")
50
+ return "warning";
51
+ if (format === "markdown")
52
+ return "[!]";
53
+ return "▲";
54
+ },
55
+ get active() {
56
+ const format = resolveOutputFormat();
57
+ if (format === "json")
58
+ return "active";
59
+ if (format === "markdown")
60
+ return "[x]";
61
+ return "◆";
62
+ },
63
+ get inactive() {
64
+ const format = resolveOutputFormat();
65
+ if (format === "json")
66
+ return "inactive";
67
+ if (format === "markdown")
68
+ return "[ ]";
69
+ return "○";
70
+ }
71
+ };
@@ -0,0 +1,13 @@
1
+ import type { ThemePalette } from "../tokens/colors.js";
2
+ export interface TableColumn {
3
+ name: string;
4
+ title: string;
5
+ alignment: "left" | "right";
6
+ maxLen: number;
7
+ }
8
+ export interface RenderTableOptions {
9
+ theme: ThemePalette;
10
+ columns: TableColumn[];
11
+ rows: Record<string, string>[];
12
+ }
13
+ export declare function renderTable(options: RenderTableOptions): string;
@@ -0,0 +1,74 @@
1
+ import { Table } from "console-table-printer";
2
+ import { resolveOutputFormat } from "../internal/output-format.js";
3
+ import { stripAnsi } from "../internal/strip-ansi.js";
4
+ function renderTableTerminal(options) {
5
+ 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);
43
+ }
44
+ return table.render();
45
+ }
46
+ function renderTableMarkdown(options) {
47
+ const { columns, rows } = options;
48
+ const header = `| ${columns.map((c) => c.title).join(" | ")} |`;
49
+ const separator = `| ${columns.map((c) => (c.alignment === "right" ? "---:" : ":---")).join(" | ")} |`;
50
+ const dataRows = rows.map((row) => `| ${columns.map((c) => stripAnsi(row[c.name] ?? "").replace(/\|/g, "\\|")).join(" | ")} |`);
51
+ return [header, separator, ...dataRows].join("\n");
52
+ }
53
+ function renderTableJson(options) {
54
+ const { columns, rows } = options;
55
+ const cleaned = rows.map((row) => {
56
+ const obj = {};
57
+ for (const col of columns) {
58
+ obj[col.name] = stripAnsi(row[col.name] ?? "");
59
+ }
60
+ return obj;
61
+ });
62
+ return JSON.stringify(cleaned, null, 2);
63
+ }
64
+ export function renderTable(options) {
65
+ const format = resolveOutputFormat();
66
+ switch (format) {
67
+ case "markdown":
68
+ return renderTableMarkdown(options);
69
+ case "json":
70
+ return renderTableJson(options);
71
+ default:
72
+ return renderTableTerminal(options);
73
+ }
74
+ }
@@ -0,0 +1,14 @@
1
+ export declare const text: {
2
+ readonly intro: (content: string) => string;
3
+ readonly heading: (content: string) => string;
4
+ readonly section: (content: string) => string;
5
+ readonly command: (content: string) => string;
6
+ readonly argument: (content: string) => string;
7
+ readonly option: (content: string) => string;
8
+ readonly example: (content: string) => string;
9
+ readonly usageCommand: (content: string) => string;
10
+ readonly link: (content: string) => string;
11
+ readonly muted: (content: string) => string;
12
+ readonly badge: (content: string) => string;
13
+ readonly selectLabel: (label: string, detail?: string) => string;
14
+ };
@@ -0,0 +1,104 @@
1
+ import chalk from "chalk";
2
+ import { resolveOutputFormat } from "../internal/output-format.js";
3
+ import { getTheme } from "../internal/theme-detect.js";
4
+ import { typography } from "../tokens/typography.js";
5
+ export const text = {
6
+ intro(content) {
7
+ const format = resolveOutputFormat();
8
+ if (format === "json")
9
+ return content;
10
+ if (format === "markdown")
11
+ return `**${content}**`;
12
+ return getTheme().intro(content);
13
+ },
14
+ heading(content) {
15
+ const format = resolveOutputFormat();
16
+ if (format === "json")
17
+ return content;
18
+ if (format === "markdown")
19
+ return `## ${content}`;
20
+ return getTheme().header(content);
21
+ },
22
+ section(content) {
23
+ const format = resolveOutputFormat();
24
+ if (format === "json")
25
+ return content;
26
+ if (format === "markdown")
27
+ return `**${content}**`;
28
+ return typography.bold(content);
29
+ },
30
+ command(content) {
31
+ const format = resolveOutputFormat();
32
+ if (format === "json")
33
+ return content;
34
+ if (format === "markdown")
35
+ return `\`${content}\``;
36
+ return getTheme().accent(content);
37
+ },
38
+ argument(content) {
39
+ const format = resolveOutputFormat();
40
+ if (format === "json")
41
+ return content;
42
+ if (format === "markdown")
43
+ return `<${content}>`;
44
+ return getTheme().muted(content);
45
+ },
46
+ option(content) {
47
+ const format = resolveOutputFormat();
48
+ if (format === "json")
49
+ return content;
50
+ if (format === "markdown")
51
+ return `\`${content}\``;
52
+ return chalk.yellow(content);
53
+ },
54
+ example(content) {
55
+ const format = resolveOutputFormat();
56
+ if (format === "json")
57
+ return content;
58
+ if (format === "markdown")
59
+ return `\`${content}\``;
60
+ return getTheme().muted(content);
61
+ },
62
+ usageCommand(content) {
63
+ const format = resolveOutputFormat();
64
+ if (format === "json")
65
+ return content;
66
+ if (format === "markdown")
67
+ return `\`${content}\``;
68
+ return chalk.green(content);
69
+ },
70
+ link(content) {
71
+ const format = resolveOutputFormat();
72
+ if (format === "json")
73
+ return content;
74
+ if (format === "markdown")
75
+ return `[${content}](${content})`;
76
+ return getTheme().accent(content);
77
+ },
78
+ muted(content) {
79
+ const format = resolveOutputFormat();
80
+ if (format === "json")
81
+ return content;
82
+ if (format === "markdown")
83
+ return `*${content}*`;
84
+ return getTheme().muted(content);
85
+ },
86
+ badge(content) {
87
+ const format = resolveOutputFormat();
88
+ if (format === "json")
89
+ return content;
90
+ if (format === "markdown")
91
+ return `[${content}]`;
92
+ return getTheme().badge(content);
93
+ },
94
+ selectLabel(label, detail) {
95
+ if (!detail) {
96
+ return label;
97
+ }
98
+ const format = resolveOutputFormat();
99
+ if (format !== "terminal") {
100
+ return `${label} — ${detail}`;
101
+ }
102
+ return `${label} ${typography.dim("—")} ${typography.dim(detail)}`;
103
+ }
104
+ };
@@ -0,0 +1,18 @@
1
+ import type { CellStyle } from "./types.js";
2
+ export interface StyledSegment {
3
+ text: string;
4
+ style: CellStyle;
5
+ }
6
+ export interface StyledLine {
7
+ segments: StyledSegment[];
8
+ }
9
+ export declare function hasAnsi(text: string): boolean;
10
+ /**
11
+ * Parse a block of text that may contain ANSI SGR escape codes into a sequence of
12
+ * logical lines split on "\n". Each line is a list of styled segments: contiguous
13
+ * printable runs of characters sharing the same style.
14
+ *
15
+ * Non-SGR CSI sequences and other control characters are discarded. `baseStyle` is
16
+ * used as the initial style and as the restore target for SGR reset / default color.
17
+ */
18
+ export declare function parseAnsi(text: string, baseStyle?: CellStyle): StyledLine[];
@@ -0,0 +1,298 @@
1
+ const ESC = "\u001b";
2
+ export function hasAnsi(text) {
3
+ return text.includes(ESC);
4
+ }
5
+ /**
6
+ * Parse a block of text that may contain ANSI SGR escape codes into a sequence of
7
+ * logical lines split on "\n". Each line is a list of styled segments: contiguous
8
+ * printable runs of characters sharing the same style.
9
+ *
10
+ * Non-SGR CSI sequences and other control characters are discarded. `baseStyle` is
11
+ * used as the initial style and as the restore target for SGR reset / default color.
12
+ */
13
+ export function parseAnsi(text, baseStyle) {
14
+ const base = normalizeStyle(baseStyle);
15
+ let style = { ...base };
16
+ const lines = [];
17
+ let segments = [];
18
+ let pending = "";
19
+ const flushSegment = () => {
20
+ if (pending.length === 0) {
21
+ return;
22
+ }
23
+ const last = segments[segments.length - 1];
24
+ if (last && stylesEqual(last.style, style)) {
25
+ last.text += pending;
26
+ }
27
+ else {
28
+ segments.push({ text: pending, style: { ...style } });
29
+ }
30
+ pending = "";
31
+ };
32
+ const finishLine = () => {
33
+ flushSegment();
34
+ lines.push({ segments });
35
+ segments = [];
36
+ };
37
+ let index = 0;
38
+ while (index < text.length) {
39
+ const ch = text[index];
40
+ if (ch === ESC && text[index + 1] === "[") {
41
+ flushSegment();
42
+ const paramsStart = index + 2;
43
+ let cursor = paramsStart;
44
+ while (cursor < text.length && !isCsiFinalByte(text[cursor])) {
45
+ cursor += 1;
46
+ }
47
+ if (cursor >= text.length) {
48
+ index = text.length;
49
+ break;
50
+ }
51
+ const params = text.slice(paramsStart, cursor);
52
+ const finalByte = text[cursor];
53
+ if (finalByte === "m") {
54
+ style = applySgr(style, parseParams(params), base);
55
+ }
56
+ index = cursor + 1;
57
+ continue;
58
+ }
59
+ if (ch === ESC) {
60
+ flushSegment();
61
+ const next = text[index + 1];
62
+ if (next === "]" || next === "P" || next === "X" || next === "^" || next === "_") {
63
+ index = skipStringTerminated(text, index + 2);
64
+ continue;
65
+ }
66
+ index += 2;
67
+ continue;
68
+ }
69
+ if (ch === "\r") {
70
+ index += 1;
71
+ continue;
72
+ }
73
+ if (ch === "\n") {
74
+ finishLine();
75
+ index += 1;
76
+ continue;
77
+ }
78
+ const code = ch.charCodeAt(0);
79
+ if (code < 0x20 && ch !== "\t") {
80
+ index += 1;
81
+ continue;
82
+ }
83
+ pending += ch;
84
+ index += 1;
85
+ }
86
+ finishLine();
87
+ return lines;
88
+ }
89
+ function isCsiFinalByte(ch) {
90
+ const code = ch.charCodeAt(0);
91
+ return code >= 0x40 && code <= 0x7e;
92
+ }
93
+ function skipStringTerminated(text, start) {
94
+ let index = start;
95
+ while (index < text.length) {
96
+ const ch = text[index];
97
+ if (ch === "\u0007") {
98
+ return index + 1;
99
+ }
100
+ if (ch === ESC && text[index + 1] === "\\") {
101
+ return index + 2;
102
+ }
103
+ index += 1;
104
+ }
105
+ return index;
106
+ }
107
+ function parseParams(params) {
108
+ if (params.length === 0) {
109
+ return [0];
110
+ }
111
+ return params.split(";").map((part) => {
112
+ if (part.length === 0) {
113
+ return 0;
114
+ }
115
+ const parsed = Number.parseInt(part, 10);
116
+ return Number.isFinite(parsed) ? parsed : 0;
117
+ });
118
+ }
119
+ const BASIC_COLORS = [
120
+ "black",
121
+ "red",
122
+ "green",
123
+ "yellow",
124
+ "blue",
125
+ "magenta",
126
+ "cyan",
127
+ "white"
128
+ ];
129
+ const BRIGHT_COLORS = [
130
+ "gray",
131
+ "redBright",
132
+ "greenBright",
133
+ "yellowBright",
134
+ "blueBright",
135
+ "magentaBright",
136
+ "cyanBright",
137
+ "whiteBright"
138
+ ];
139
+ function applySgr(style, params, base) {
140
+ let next = { ...style };
141
+ let index = 0;
142
+ while (index < params.length) {
143
+ const code = params[index];
144
+ if (code === 0) {
145
+ next = { ...base };
146
+ index += 1;
147
+ continue;
148
+ }
149
+ if (code === 1) {
150
+ next.bold = true;
151
+ index += 1;
152
+ continue;
153
+ }
154
+ if (code === 2) {
155
+ next.dim = true;
156
+ index += 1;
157
+ continue;
158
+ }
159
+ if (code === 22) {
160
+ delete next.bold;
161
+ delete next.dim;
162
+ index += 1;
163
+ continue;
164
+ }
165
+ if (code >= 30 && code <= 37) {
166
+ next.fg = BASIC_COLORS[code - 30];
167
+ index += 1;
168
+ continue;
169
+ }
170
+ if (code === 38) {
171
+ const mode = params[index + 1];
172
+ if (mode === 5) {
173
+ const palette = params[index + 2] ?? 0;
174
+ next.fg = convert256(palette);
175
+ index += 3;
176
+ continue;
177
+ }
178
+ if (mode === 2) {
179
+ const r = params[index + 2] ?? 0;
180
+ const g = params[index + 3] ?? 0;
181
+ const b = params[index + 4] ?? 0;
182
+ next.fg = rgbToHex(r, g, b);
183
+ index += 5;
184
+ continue;
185
+ }
186
+ index += 1;
187
+ continue;
188
+ }
189
+ if (code === 39) {
190
+ if (base.fg !== undefined) {
191
+ next.fg = base.fg;
192
+ }
193
+ else {
194
+ delete next.fg;
195
+ }
196
+ index += 1;
197
+ continue;
198
+ }
199
+ if (code >= 40 && code <= 47) {
200
+ next.bg = BASIC_COLORS[code - 40];
201
+ index += 1;
202
+ continue;
203
+ }
204
+ if (code === 48) {
205
+ const mode = params[index + 1];
206
+ if (mode === 5) {
207
+ const palette = params[index + 2] ?? 0;
208
+ next.bg = convert256(palette);
209
+ index += 3;
210
+ continue;
211
+ }
212
+ if (mode === 2) {
213
+ const r = params[index + 2] ?? 0;
214
+ const g = params[index + 3] ?? 0;
215
+ const b = params[index + 4] ?? 0;
216
+ next.bg = rgbToHex(r, g, b);
217
+ index += 5;
218
+ continue;
219
+ }
220
+ index += 1;
221
+ continue;
222
+ }
223
+ if (code === 49) {
224
+ if (base.bg !== undefined) {
225
+ next.bg = base.bg;
226
+ }
227
+ else {
228
+ delete next.bg;
229
+ }
230
+ index += 1;
231
+ continue;
232
+ }
233
+ if (code >= 90 && code <= 97) {
234
+ next.fg = BRIGHT_COLORS[code - 90];
235
+ index += 1;
236
+ continue;
237
+ }
238
+ if (code >= 100 && code <= 107) {
239
+ next.bg = BRIGHT_COLORS[code - 100];
240
+ index += 1;
241
+ continue;
242
+ }
243
+ index += 1;
244
+ }
245
+ return next;
246
+ }
247
+ function convert256(palette) {
248
+ if (palette < 0 || palette > 255) {
249
+ return "#000000";
250
+ }
251
+ if (palette < 8) {
252
+ return BASIC_COLORS[palette];
253
+ }
254
+ if (palette < 16) {
255
+ return BRIGHT_COLORS[palette - 8];
256
+ }
257
+ if (palette >= 232) {
258
+ const level = 8 + (palette - 232) * 10;
259
+ return rgbToHex(level, level, level);
260
+ }
261
+ const offset = palette - 16;
262
+ const r = Math.floor(offset / 36);
263
+ const g = Math.floor((offset % 36) / 6);
264
+ const b = offset % 6;
265
+ return rgbToHex(cubeLevel(r), cubeLevel(g), cubeLevel(b));
266
+ }
267
+ function cubeLevel(value) {
268
+ return value === 0 ? 0 : 55 + value * 40;
269
+ }
270
+ function rgbToHex(r, g, b) {
271
+ return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
272
+ }
273
+ function toHex(value) {
274
+ const clamped = Math.max(0, Math.min(255, Math.floor(value)));
275
+ return clamped.toString(16).padStart(2, "0");
276
+ }
277
+ function stylesEqual(left, right) {
278
+ return left.fg === right.fg
279
+ && left.bg === right.bg
280
+ && left.bold === right.bold
281
+ && left.dim === right.dim;
282
+ }
283
+ function normalizeStyle(style) {
284
+ const next = {};
285
+ if (style?.fg !== undefined) {
286
+ next.fg = style.fg;
287
+ }
288
+ if (style?.bg !== undefined) {
289
+ next.bg = style.bg;
290
+ }
291
+ if (style?.bold !== undefined) {
292
+ next.bold = style.bold;
293
+ }
294
+ if (style?.dim !== undefined) {
295
+ next.dim = style.dim;
296
+ }
297
+ return next;
298
+ }
@@ -0,0 +1,25 @@
1
+ import type { Cell, CellStyle, Rect } from "./types.js";
2
+ export declare class ScreenBuffer {
3
+ private _width;
4
+ private _height;
5
+ private _cells;
6
+ constructor(width: number, height: number);
7
+ get width(): number;
8
+ get height(): number;
9
+ put(x: number, y: number, text: string, style?: CellStyle): void;
10
+ get(x: number, y: number): Cell;
11
+ clear(style?: CellStyle): void;
12
+ clearRect(rect: Rect, style?: CellStyle): void;
13
+ resize(width: number, height: number): void;
14
+ putInRect(rect: Rect, row: number, text: string, style?: CellStyle): void;
15
+ private index;
16
+ private isInBounds;
17
+ private isInBoundsX;
18
+ private isInBoundsY;
19
+ }
20
+ export declare function diff(prev: ScreenBuffer, next: ScreenBuffer): Array<{
21
+ x: number;
22
+ y: number;
23
+ cell: Cell;
24
+ }>;
25
+ export declare function cellToAnsi(cell: Cell): string;