toolcraft 0.0.44 → 0.0.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/node_modules/toolcraft-design/dist/components/catalog.js +3 -2
- package/node_modules/toolcraft-design/dist/components/detail-card.js +10 -34
- package/node_modules/toolcraft-design/dist/components/text.js +2 -1
- package/node_modules/toolcraft-design/dist/internal/strip-ansi.js +48 -1
- package/node_modules/toolcraft-design/dist/static/spinner.js +1 -1
- package/node_modules/toolcraft-design/dist/terminal-markdown/parser/inline.js +41 -17
- package/node_modules/toolcraft-design/dist/terminal-markdown/renderer.js +52 -26
- package/package.json +2 -2
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { resolveOutputFormat } from "../internal/output-format.js";
|
|
2
2
|
import { stripAnsi } from "../internal/strip-ansi.js";
|
|
3
|
+
import { text } from "./text.js";
|
|
3
4
|
function applyTone(theme, value, tone) {
|
|
4
5
|
return tone === undefined ? value : theme[tone](value);
|
|
5
6
|
}
|
|
@@ -38,7 +39,7 @@ function renderTerminal(options) {
|
|
|
38
39
|
return blocks.join("\n\n");
|
|
39
40
|
}
|
|
40
41
|
function escapeMarkdown(value) {
|
|
41
|
-
return stripAnsi(value)
|
|
42
|
+
return stripAnsi(value);
|
|
42
43
|
}
|
|
43
44
|
function renderMarkdown(options) {
|
|
44
45
|
const blocks = [`# ${escapeMarkdown(options.title)}`];
|
|
@@ -55,7 +56,7 @@ function renderMarkdown(options) {
|
|
|
55
56
|
}
|
|
56
57
|
const items = group.items.map((item) => {
|
|
57
58
|
const detail = item.detail === undefined ? "" : ` — ${escapeMarkdown(item.detail)}`;
|
|
58
|
-
return `-
|
|
59
|
+
return `- ${text.command(escapeMarkdown(item.label))} ${text.command(escapeMarkdown(item.value))}${detail}`;
|
|
59
60
|
});
|
|
60
61
|
blocks.push(`${header.join("\n\n")}\n\n${items.join("\n")}`);
|
|
61
62
|
}
|
|
@@ -1,44 +1,20 @@
|
|
|
1
|
+
import stringWidth from "fast-string-width";
|
|
2
|
+
import { wrapAnsi } from "fast-wrap-ansi";
|
|
1
3
|
import { widths } from "../tokens/widths.js";
|
|
2
4
|
function wrap(value, width) {
|
|
3
|
-
|
|
4
|
-
for (const paragraph of value.split("\n")) {
|
|
5
|
-
let line = "";
|
|
6
|
-
for (const rawWord of paragraph.split(" ")) {
|
|
7
|
-
const words = [];
|
|
8
|
-
let word = rawWord;
|
|
9
|
-
while (word.length > width) {
|
|
10
|
-
words.push(word.slice(0, width));
|
|
11
|
-
word = word.slice(width);
|
|
12
|
-
}
|
|
13
|
-
words.push(word);
|
|
14
|
-
for (const word of words) {
|
|
15
|
-
if (line.length === 0) {
|
|
16
|
-
line = word;
|
|
17
|
-
continue;
|
|
18
|
-
}
|
|
19
|
-
if (`${line} ${word}`.length <= width) {
|
|
20
|
-
line = `${line} ${word}`;
|
|
21
|
-
continue;
|
|
22
|
-
}
|
|
23
|
-
lines.push(line);
|
|
24
|
-
line = word;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
lines.push(line);
|
|
28
|
-
}
|
|
29
|
-
return lines;
|
|
5
|
+
return wrapAnsi(value, Math.max(1, width), { hard: true, trim: true }).split("\n");
|
|
30
6
|
}
|
|
31
7
|
function renderRows(rows, theme, width) {
|
|
32
8
|
if (rows.length === 0)
|
|
33
9
|
return [];
|
|
34
|
-
const labelWidth = Math.max(...rows.map((row) => row.label
|
|
10
|
+
const labelWidth = Math.max(...rows.map((row) => stringWidth(row.label)));
|
|
35
11
|
const valueWidth = Math.max(20, width - labelWidth - 2);
|
|
36
12
|
const continuation = " ".repeat(labelWidth + 2);
|
|
37
13
|
return rows.flatMap((row) => {
|
|
38
14
|
const values = wrap(row.value, valueWidth);
|
|
39
15
|
return [
|
|
40
16
|
`${theme.muted(row.label.padEnd(labelWidth))} ${values[0] ?? ""}`,
|
|
41
|
-
...values.slice(1).map((value) => `${continuation}${value}`)
|
|
17
|
+
...values.slice(1).map((value) => `${continuation}${value}`)
|
|
42
18
|
];
|
|
43
19
|
});
|
|
44
20
|
}
|
|
@@ -46,8 +22,10 @@ export function renderDetailCard(options) {
|
|
|
46
22
|
const width = options.width ?? widths.maxLine;
|
|
47
23
|
const identity = [
|
|
48
24
|
options.theme.header(options.title),
|
|
49
|
-
options.subtitle ? options.theme.muted(options.subtitle) : undefined
|
|
50
|
-
]
|
|
25
|
+
options.subtitle ? options.theme.muted(options.subtitle) : undefined
|
|
26
|
+
]
|
|
27
|
+
.filter((value) => value !== undefined)
|
|
28
|
+
.join(" ");
|
|
51
29
|
const hero = options.badges?.length
|
|
52
30
|
? `${identity}\n${options.theme.muted(options.badges.map((badge) => badge[0] + badge.slice(1).toLowerCase()).join(" · "))}`
|
|
53
31
|
: identity;
|
|
@@ -61,9 +39,7 @@ export function renderDetailCard(options) {
|
|
|
61
39
|
if (section.rows.length === 0)
|
|
62
40
|
continue;
|
|
63
41
|
const rows = renderRows(section.rows, options.theme, width);
|
|
64
|
-
blocks.push(section.title
|
|
65
|
-
? [options.theme.header(section.title), ...rows].join("\n")
|
|
66
|
-
: rows.join("\n"));
|
|
42
|
+
blocks.push(section.title ? [options.theme.header(section.title), ...rows].join("\n") : rows.join("\n"));
|
|
67
43
|
}
|
|
68
44
|
return blocks.join("\n\n");
|
|
69
45
|
}
|
|
@@ -18,7 +18,8 @@ function renderMarkdownCode(content) {
|
|
|
18
18
|
currentRun = 0;
|
|
19
19
|
}
|
|
20
20
|
const delimiter = "`".repeat(longestRun + 1);
|
|
21
|
-
|
|
21
|
+
const paddedValue = value.startsWith("`") || value.endsWith("`") ? ` ${value} ` : value;
|
|
22
|
+
return `${delimiter}${paddedValue}${delimiter}`;
|
|
22
23
|
}
|
|
23
24
|
function renderMarkdownLink(content) {
|
|
24
25
|
const value = renderMarkdownInline(content);
|
|
@@ -1,3 +1,50 @@
|
|
|
1
1
|
export function stripAnsi(value) {
|
|
2
|
-
|
|
2
|
+
let output = "";
|
|
3
|
+
let index = 0;
|
|
4
|
+
while (index < value.length) {
|
|
5
|
+
const char = value[index];
|
|
6
|
+
if (char === "\u001b") {
|
|
7
|
+
index = skipEscapeSequence(value, index);
|
|
8
|
+
continue;
|
|
9
|
+
}
|
|
10
|
+
if (char === "\u009b") {
|
|
11
|
+
index = skipCsiSequence(value, index + 1);
|
|
12
|
+
continue;
|
|
13
|
+
}
|
|
14
|
+
output += char;
|
|
15
|
+
index += char.length;
|
|
16
|
+
}
|
|
17
|
+
return output;
|
|
18
|
+
}
|
|
19
|
+
function skipEscapeSequence(value, index) {
|
|
20
|
+
const next = value[index + 1];
|
|
21
|
+
if (next === "[") {
|
|
22
|
+
return skipCsiSequence(value, index + 2);
|
|
23
|
+
}
|
|
24
|
+
if (next === "]") {
|
|
25
|
+
return skipOscSequence(value, index + 2);
|
|
26
|
+
}
|
|
27
|
+
return Math.min(value.length, index + 2);
|
|
28
|
+
}
|
|
29
|
+
function skipCsiSequence(value, index) {
|
|
30
|
+
while (index < value.length) {
|
|
31
|
+
const codePoint = value.charCodeAt(index);
|
|
32
|
+
index += 1;
|
|
33
|
+
if (codePoint >= 0x40 && codePoint <= 0x7e) {
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return index;
|
|
38
|
+
}
|
|
39
|
+
function skipOscSequence(value, index) {
|
|
40
|
+
while (index < value.length) {
|
|
41
|
+
if (value[index] === "\u0007") {
|
|
42
|
+
return index + 1;
|
|
43
|
+
}
|
|
44
|
+
if (value[index] === "\u001b" && value[index + 1] === "\\") {
|
|
45
|
+
return index + 2;
|
|
46
|
+
}
|
|
47
|
+
index += 1;
|
|
48
|
+
}
|
|
49
|
+
return index;
|
|
3
50
|
}
|
|
@@ -5,7 +5,7 @@ export const SPINNER_FRAMES = Object.freeze(["◒", "◐", "◓", "◑"]);
|
|
|
5
5
|
export function renderSpinnerFrame(options) {
|
|
6
6
|
const format = resolveOutputFormat();
|
|
7
7
|
if (format === "markdown") {
|
|
8
|
-
return `- ${options.message}${options.timer ? ` [${options.timer}]` : ""}...\n`;
|
|
8
|
+
return `- ${renderMarkdownInline(options.message)}${options.timer ? ` [${renderMarkdownInline(options.timer)}]` : ""}...\n`;
|
|
9
9
|
}
|
|
10
10
|
if (format === "json") {
|
|
11
11
|
return `${JSON.stringify({
|
|
@@ -500,15 +500,16 @@ function parseInlineCode(input, start, offsets) {
|
|
|
500
500
|
}
|
|
501
501
|
const closingFenceLength = readRunLength(input, index, "`");
|
|
502
502
|
if (closingFenceLength === fenceLength) {
|
|
503
|
+
const value = normalizeInlineCodeValue(input.slice(start + fenceLength, index));
|
|
503
504
|
return {
|
|
504
505
|
node: offsets === undefined
|
|
505
506
|
? {
|
|
506
507
|
type: "inlineCode",
|
|
507
|
-
value
|
|
508
|
+
value
|
|
508
509
|
}
|
|
509
510
|
: withRange({
|
|
510
511
|
type: "inlineCode",
|
|
511
|
-
value
|
|
512
|
+
value
|
|
512
513
|
}, createRange(offsets, start, index + fenceLength)),
|
|
513
514
|
end: index + fenceLength
|
|
514
515
|
};
|
|
@@ -517,6 +518,16 @@ function parseInlineCode(input, start, offsets) {
|
|
|
517
518
|
}
|
|
518
519
|
return null;
|
|
519
520
|
}
|
|
521
|
+
function normalizeInlineCodeValue(value) {
|
|
522
|
+
if (value.length >= 2 &&
|
|
523
|
+
value.startsWith(" ") &&
|
|
524
|
+
value.endsWith(" ") &&
|
|
525
|
+
(value[1] === "`" || value[value.length - 2] === "`") &&
|
|
526
|
+
value.trim().length > 0) {
|
|
527
|
+
return value.slice(1, -1);
|
|
528
|
+
}
|
|
529
|
+
return value;
|
|
530
|
+
}
|
|
520
531
|
function parseLink(input, start, footnoteLabels, offsets) {
|
|
521
532
|
const label = parseBracketedLabel(input, start);
|
|
522
533
|
if (label === null || label.end >= input.length || input[label.end] !== "(") {
|
|
@@ -538,7 +549,9 @@ function parseLink(input, start, footnoteLabels, offsets) {
|
|
|
538
549
|
? {}
|
|
539
550
|
: { offsets: sliceOffsetMap(offsets, label.contentStart, label.end - 1) })
|
|
540
551
|
})
|
|
541
|
-
}, offsets === undefined
|
|
552
|
+
}, offsets === undefined
|
|
553
|
+
? { start, end: destination.end }
|
|
554
|
+
: createRange(offsets, start, destination.end)),
|
|
542
555
|
end: destination.end
|
|
543
556
|
};
|
|
544
557
|
}
|
|
@@ -557,7 +570,9 @@ function parseImage(input, start, offsets) {
|
|
|
557
570
|
url: destination.url,
|
|
558
571
|
alt: decodeEscapes(label.value),
|
|
559
572
|
...(destination.title === undefined ? {} : { title: destination.title })
|
|
560
|
-
}, offsets === undefined
|
|
573
|
+
}, offsets === undefined
|
|
574
|
+
? { start, end: destination.end }
|
|
575
|
+
: createRange(offsets, start, destination.end)),
|
|
561
576
|
end: destination.end
|
|
562
577
|
};
|
|
563
578
|
}
|
|
@@ -620,7 +635,7 @@ function parseLinkDestination(input, openParenIndex) {
|
|
|
620
635
|
index += 2;
|
|
621
636
|
continue;
|
|
622
637
|
}
|
|
623
|
-
if (char === "
|
|
638
|
+
if (char === '"' || char === "'") {
|
|
624
639
|
quote = char;
|
|
625
640
|
index += 1;
|
|
626
641
|
continue;
|
|
@@ -651,7 +666,7 @@ function parseLinkDestinationContent(content) {
|
|
|
651
666
|
return { url: "" };
|
|
652
667
|
}
|
|
653
668
|
const quote = content[trimmedEnd - 1];
|
|
654
|
-
if (quote === "
|
|
669
|
+
if (quote === '"' || quote === "'") {
|
|
655
670
|
const titleStart = findTrailingQuotedSegmentStart(content, trimmedEnd, quote);
|
|
656
671
|
if (titleStart !== -1) {
|
|
657
672
|
let separatorStart = titleStart;
|
|
@@ -699,7 +714,9 @@ function parseAutolink(input, start, offsets) {
|
|
|
699
714
|
type: "link",
|
|
700
715
|
url,
|
|
701
716
|
children: [
|
|
702
|
-
createTextNode(url, offsets === undefined
|
|
717
|
+
createTextNode(url, offsets === undefined
|
|
718
|
+
? { start: start + 1, end: index }
|
|
719
|
+
: createRange(offsets, start + 1, index))
|
|
703
720
|
]
|
|
704
721
|
}, offsets === undefined ? { start, end: index + 1 } : createRange(offsets, start, index + 1)),
|
|
705
722
|
end: index + 1
|
|
@@ -727,7 +744,9 @@ function parseFootnoteReference(input, start, footnoteLabels, offsets) {
|
|
|
727
744
|
return null;
|
|
728
745
|
}
|
|
729
746
|
return {
|
|
730
|
-
node: withRange({ type: "footnoteReference", label }, offsets === undefined
|
|
747
|
+
node: withRange({ type: "footnoteReference", label }, offsets === undefined
|
|
748
|
+
? { start, end: labelEnd + 1 }
|
|
749
|
+
: createRange(offsets, start, labelEnd + 1)),
|
|
731
750
|
end: labelEnd + 1
|
|
732
751
|
};
|
|
733
752
|
}
|
|
@@ -754,7 +773,9 @@ function createLiteralAutolinkNode(text, url, start, end, offsets) {
|
|
|
754
773
|
node: withRange({
|
|
755
774
|
type: "link",
|
|
756
775
|
url,
|
|
757
|
-
children: [
|
|
776
|
+
children: [
|
|
777
|
+
createTextNode(text, offsets === undefined ? { start, end } : createRange(offsets, start, end))
|
|
778
|
+
]
|
|
758
779
|
}, offsets === undefined ? { start, end } : createRange(offsets, start, end)),
|
|
759
780
|
end
|
|
760
781
|
};
|
|
@@ -865,7 +886,7 @@ function parseInlineHtmlTag(input, start, offsets) {
|
|
|
865
886
|
return null;
|
|
866
887
|
}
|
|
867
888
|
const quote = input[index];
|
|
868
|
-
if (quote === "
|
|
889
|
+
if (quote === '"' || quote === "'") {
|
|
869
890
|
index += 1;
|
|
870
891
|
while (index < input.length && input[index] !== quote) {
|
|
871
892
|
index += 1;
|
|
@@ -878,7 +899,7 @@ function parseInlineHtmlTag(input, start, offsets) {
|
|
|
878
899
|
}
|
|
879
900
|
while (index < input.length && !isHtmlWhitespace(input[index]) && input[index] !== ">") {
|
|
880
901
|
const char = input[index];
|
|
881
|
-
if (char === "
|
|
902
|
+
if (char === '"' || char === "'" || char === "<" || char === "=" || char === "`") {
|
|
882
903
|
return null;
|
|
883
904
|
}
|
|
884
905
|
index += 1;
|
|
@@ -1065,7 +1086,7 @@ function skipHtmlWhitespace(value, start) {
|
|
|
1065
1086
|
}
|
|
1066
1087
|
function isEscapable(value) {
|
|
1067
1088
|
return (value === "!" ||
|
|
1068
|
-
value === "
|
|
1089
|
+
value === '"' ||
|
|
1069
1090
|
value === "#" ||
|
|
1070
1091
|
value === "$" ||
|
|
1071
1092
|
value === "%" ||
|
|
@@ -1116,7 +1137,13 @@ function isDigit(value) {
|
|
|
1116
1137
|
return value >= "0" && value <= "9";
|
|
1117
1138
|
}
|
|
1118
1139
|
function isEmailLocalPartChar(value) {
|
|
1119
|
-
return isAsciiLetter(value) ||
|
|
1140
|
+
return (isAsciiLetter(value) ||
|
|
1141
|
+
isDigit(value) ||
|
|
1142
|
+
value === "." ||
|
|
1143
|
+
value === "_" ||
|
|
1144
|
+
value === "%" ||
|
|
1145
|
+
value === "+" ||
|
|
1146
|
+
value === "-");
|
|
1120
1147
|
}
|
|
1121
1148
|
function isEmailDomainChar(value) {
|
|
1122
1149
|
return isAsciiLetter(value) || isDigit(value) || value === "." || value === "-";
|
|
@@ -1131,10 +1158,7 @@ function isHtmlAttributeNameStartChar(value) {
|
|
|
1131
1158
|
return isAsciiLetter(value) || value === ":" || value === "_";
|
|
1132
1159
|
}
|
|
1133
1160
|
function isHtmlAttributeNameChar(value) {
|
|
1134
|
-
return
|
|
1135
|
-
isDigit(value) ||
|
|
1136
|
-
value === "-" ||
|
|
1137
|
-
value === ".");
|
|
1161
|
+
return isHtmlAttributeNameStartChar(value) || isDigit(value) || value === "-" || value === ".";
|
|
1138
1162
|
}
|
|
1139
1163
|
function createRange(offsets, start, end) {
|
|
1140
1164
|
return {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { symbols } from "../components/symbols.js";
|
|
2
|
+
import { displayWidth, graphemes } from "../dashboard/terminal-width.js";
|
|
2
3
|
import { getTheme } from "../internal/theme-detect.js";
|
|
3
4
|
import { stripAnsi } from "../internal/strip-ansi.js";
|
|
4
5
|
import { spacing } from "../tokens/spacing.js";
|
|
@@ -81,7 +82,7 @@ function renderHeading(node, context) {
|
|
|
81
82
|
}
|
|
82
83
|
const styledLines = lines.map((line) => styleHeading(line, node.depth, context));
|
|
83
84
|
if (node.depth === 1) {
|
|
84
|
-
const underlineWidth = Math.max(...lines.map((line) =>
|
|
85
|
+
const underlineWidth = Math.max(...lines.map((line) => visibleWidth(line)));
|
|
85
86
|
return `${styledLines.join("\n")}\n${context.theme.header(lineChar.repeat(underlineWidth))}\n\n`;
|
|
86
87
|
}
|
|
87
88
|
return `${styledLines.join("\n")}\n\n`;
|
|
@@ -111,8 +112,8 @@ function renderAlert(node, context) {
|
|
|
111
112
|
}
|
|
112
113
|
function renderCodeBlock(node, context) {
|
|
113
114
|
const indent = " ".repeat(spacing.sm);
|
|
114
|
-
const lines = node.value.split("\n");
|
|
115
|
-
const longestLine = lines.reduce((max, line) => Math.max(max, line
|
|
115
|
+
const lines = node.value.split("\n").map((line) => stripAnsi(line));
|
|
116
|
+
const longestLine = lines.reduce((max, line) => Math.max(max, visibleWidth(line)), 0);
|
|
116
117
|
const borderWidth = Math.max(3, Math.min(context.width - indent.length, longestLine));
|
|
117
118
|
const border = context.theme.muted(`${indent}${lineChar.repeat(borderWidth)}`);
|
|
118
119
|
const content = lines.map((line) => `${indent}${line}`).join("\n");
|
|
@@ -145,7 +146,7 @@ function renderTable(node, context) {
|
|
|
145
146
|
const cell = row.children[columnIndex];
|
|
146
147
|
return cell?.type === "tableCell" ? renderTableCell(cell, context) : "";
|
|
147
148
|
}));
|
|
148
|
-
const columnWidths = Array.from({ length: columnCount }, (_, columnIndex) => Math.max(...renderedRows.map((row) =>
|
|
149
|
+
const columnWidths = Array.from({ length: columnCount }, (_, columnIndex) => Math.max(...renderedRows.map((row) => visibleWidth(row[columnIndex] ?? "")), 0));
|
|
149
150
|
if (getRenderedTableWidth(columnWidths) > context.width) {
|
|
150
151
|
return renderStackedTable(rows, columnCount, context);
|
|
151
152
|
}
|
|
@@ -157,9 +158,7 @@ function renderTable(node, context) {
|
|
|
157
158
|
if (rowIndex !== 0 || lines.length === 1) {
|
|
158
159
|
return line;
|
|
159
160
|
}
|
|
160
|
-
const divider = context.theme.muted(`├${columnWidths
|
|
161
|
-
.map((width) => lineChar.repeat(width + spacing.sm * 2))
|
|
162
|
-
.join("┼")}┤`);
|
|
161
|
+
const divider = context.theme.muted(`├${columnWidths.map((width) => lineChar.repeat(width + spacing.sm * 2)).join("┼")}┤`);
|
|
163
162
|
return `${line}\n${divider}`;
|
|
164
163
|
});
|
|
165
164
|
return `${outputLines.join("\n")}\n\n`;
|
|
@@ -171,7 +170,9 @@ function renderStackedTable(rows, columnCount, context) {
|
|
|
171
170
|
}
|
|
172
171
|
const dataRows = rows.slice(1);
|
|
173
172
|
if (dataRows.length === 0) {
|
|
174
|
-
const headerLines = Array.from({ length: columnCount }, (_, columnIndex) => tokenizeText(getStackedTableLabel(headerRow.children[columnIndex], columnIndex, context), [
|
|
173
|
+
const headerLines = Array.from({ length: columnCount }, (_, columnIndex) => tokenizeText(getStackedTableLabel(headerRow.children[columnIndex], columnIndex, context), [
|
|
174
|
+
typography.bold
|
|
175
|
+
])).flatMap((tokens) => wrapTokens(tokens, context.width));
|
|
175
176
|
return headerLines.length === 0 ? "" : `${headerLines.join("\n")}\n\n`;
|
|
176
177
|
}
|
|
177
178
|
const blocks = dataRows
|
|
@@ -235,7 +236,7 @@ function formatFrontmatterValue(value) {
|
|
|
235
236
|
});
|
|
236
237
|
}
|
|
237
238
|
function renderHtml(node, context) {
|
|
238
|
-
const value = stripHtmlTags(node.value).trim();
|
|
239
|
+
const value = stripAnsi(stripHtmlTags(node.value)).trim();
|
|
239
240
|
if (value.length === 0) {
|
|
240
241
|
return "";
|
|
241
242
|
}
|
|
@@ -286,7 +287,7 @@ function renderReferencedFootnotes(context) {
|
|
|
286
287
|
function renderFootnoteDefinition(node, number, context) {
|
|
287
288
|
const marker = typography.dim(`[${number}]`);
|
|
288
289
|
const firstPrefix = `${" ".repeat(spacing.sm)}${marker} `;
|
|
289
|
-
const continuationPrefix = `${" ".repeat(spacing.sm +
|
|
290
|
+
const continuationPrefix = `${" ".repeat(spacing.sm + visibleWidth(`[${number}] `))}`;
|
|
290
291
|
const body = renderBlockChildren(node.children, reduceWidth(context, firstPrefix));
|
|
291
292
|
if (body.length === 0) {
|
|
292
293
|
return firstPrefix.trimEnd();
|
|
@@ -317,7 +318,7 @@ function prefixBlock(rendered, firstPrefix, restPrefix) {
|
|
|
317
318
|
function reduceWidth(context, prefix) {
|
|
318
319
|
return {
|
|
319
320
|
...context,
|
|
320
|
-
width: Math.max(1, context.width -
|
|
321
|
+
width: Math.max(1, context.width - visibleWidth(prefix))
|
|
321
322
|
};
|
|
322
323
|
}
|
|
323
324
|
function renderInline(nodes, context) {
|
|
@@ -334,7 +335,7 @@ function tokenizeInline(nodes, context) {
|
|
|
334
335
|
function collectInlineTokens(node, formatters, context, tokens) {
|
|
335
336
|
switch (node.type) {
|
|
336
337
|
case "text":
|
|
337
|
-
tokens.push(...tokenizeText(node.value, formatters));
|
|
338
|
+
tokens.push(...tokenizeText(stripAnsi(node.value), formatters));
|
|
338
339
|
return;
|
|
339
340
|
case "strong":
|
|
340
341
|
collectChildren(node.children, [...formatters, typography.bold], context, tokens);
|
|
@@ -346,13 +347,16 @@ function collectInlineTokens(node, formatters, context, tokens) {
|
|
|
346
347
|
collectChildren(node.children, [...formatters, typography.strikethrough], context, tokens);
|
|
347
348
|
return;
|
|
348
349
|
case "inlineCode":
|
|
349
|
-
tokens.push(...tokenizeText(node.value, [...formatters, context.theme.accent]));
|
|
350
|
+
tokens.push(...tokenizeText(stripAnsi(node.value), [...formatters, context.theme.accent]));
|
|
350
351
|
return;
|
|
351
352
|
case "link":
|
|
352
353
|
collectLinkTokens(node, formatters, context, tokens);
|
|
353
354
|
return;
|
|
354
355
|
case "image":
|
|
355
|
-
tokens.push(createWordToken(formatImagePlaceholder(node.alt), [
|
|
356
|
+
tokens.push(createWordToken(formatImagePlaceholder(stripAnsi(node.alt)), [
|
|
357
|
+
...formatters,
|
|
358
|
+
context.theme.muted
|
|
359
|
+
]));
|
|
356
360
|
return;
|
|
357
361
|
case "footnoteReference": {
|
|
358
362
|
const footnoteNumber = resolveFootnoteNumber(node.label, context);
|
|
@@ -362,7 +366,7 @@ function collectInlineTokens(node, formatters, context, tokens) {
|
|
|
362
366
|
return;
|
|
363
367
|
}
|
|
364
368
|
case "html": {
|
|
365
|
-
const value = stripHtmlTags(node.value);
|
|
369
|
+
const value = stripAnsi(stripHtmlTags(node.value));
|
|
366
370
|
if (value.length > 0) {
|
|
367
371
|
tokens.push(...tokenizeText(value, formatters));
|
|
368
372
|
}
|
|
@@ -384,7 +388,7 @@ function collectChildren(children, formatters, context, tokens) {
|
|
|
384
388
|
}
|
|
385
389
|
function collectLinkTokens(node, formatters, context, tokens) {
|
|
386
390
|
if (isAutolink(node)) {
|
|
387
|
-
tokens.push(createWordToken(node.url, [...formatters, context.theme.accent]));
|
|
391
|
+
tokens.push(createWordToken(stripAnsi(node.url), [...formatters, context.theme.accent]));
|
|
388
392
|
return;
|
|
389
393
|
}
|
|
390
394
|
const childTokens = [];
|
|
@@ -394,7 +398,7 @@ function collectLinkTokens(node, formatters, context, tokens) {
|
|
|
394
398
|
if (trimmedChildTokens.some((token) => token.type === "word")) {
|
|
395
399
|
tokens.push({ type: "space", value: " " });
|
|
396
400
|
}
|
|
397
|
-
tokens.push(createWordToken(`(${node.url})`, [...formatters, context.theme.accent]));
|
|
401
|
+
tokens.push(createWordToken(`(${stripAnsi(node.url)})`, [...formatters, context.theme.accent]));
|
|
398
402
|
}
|
|
399
403
|
function isAutolink(node) {
|
|
400
404
|
if (node.children.length !== 1 || node.children[0]?.type !== "text") {
|
|
@@ -424,7 +428,9 @@ function tokenizeText(value, formatters) {
|
|
|
424
428
|
const pieces = line
|
|
425
429
|
.split(/([ \t]+)/)
|
|
426
430
|
.filter((piece) => piece.length > 0)
|
|
427
|
-
.map((piece) => /^[ \t]+$/.test(piece)
|
|
431
|
+
.map((piece) => /^[ \t]+$/.test(piece)
|
|
432
|
+
? { type: "space", value: piece }
|
|
433
|
+
: { type: "word", value: piece, formatters });
|
|
428
434
|
return lineIndex < lines.length - 1 ? [...pieces, { type: "break" }] : pieces;
|
|
429
435
|
});
|
|
430
436
|
}
|
|
@@ -454,8 +460,9 @@ function wrapTokens(tokens, width) {
|
|
|
454
460
|
for (let index = 0; index < chunks.length; index++) {
|
|
455
461
|
const chunk = chunks[index];
|
|
456
462
|
const gap = index === 0 ? pendingSpace : "";
|
|
457
|
-
const
|
|
458
|
-
|
|
463
|
+
const chunkWidth = visibleWidth(chunk);
|
|
464
|
+
const gapWidth = visibleWidth(gap);
|
|
465
|
+
if (currentWidth > 0 && currentWidth + chunkWidth + gapWidth > width) {
|
|
459
466
|
flushLine();
|
|
460
467
|
}
|
|
461
468
|
if (currentWidth > 0 && gapWidth > 0) {
|
|
@@ -463,7 +470,7 @@ function wrapTokens(tokens, width) {
|
|
|
463
470
|
currentWidth += gapWidth;
|
|
464
471
|
}
|
|
465
472
|
currentLine += applyFormatters(chunk, token.formatters);
|
|
466
|
-
currentWidth +=
|
|
473
|
+
currentWidth += chunkWidth;
|
|
467
474
|
pendingSpace = "";
|
|
468
475
|
if (index < chunks.length - 1) {
|
|
469
476
|
flushLine();
|
|
@@ -476,12 +483,29 @@ function wrapTokens(tokens, width) {
|
|
|
476
483
|
return lines;
|
|
477
484
|
}
|
|
478
485
|
function splitWord(value, width) {
|
|
479
|
-
if (value
|
|
486
|
+
if (visibleWidth(value) <= width) {
|
|
480
487
|
return [value];
|
|
481
488
|
}
|
|
482
489
|
const chunks = [];
|
|
483
|
-
|
|
484
|
-
|
|
490
|
+
let chunk = "";
|
|
491
|
+
let chunkWidth = 0;
|
|
492
|
+
for (const grapheme of graphemes(value)) {
|
|
493
|
+
const graphemeWidth = visibleWidth(grapheme);
|
|
494
|
+
if (chunk.length > 0 && chunkWidth + graphemeWidth > width) {
|
|
495
|
+
chunks.push(chunk);
|
|
496
|
+
chunk = "";
|
|
497
|
+
chunkWidth = 0;
|
|
498
|
+
}
|
|
499
|
+
chunk += grapheme;
|
|
500
|
+
chunkWidth += graphemeWidth;
|
|
501
|
+
if (chunkWidth >= width) {
|
|
502
|
+
chunks.push(chunk);
|
|
503
|
+
chunk = "";
|
|
504
|
+
chunkWidth = 0;
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
if (chunk.length > 0) {
|
|
508
|
+
chunks.push(chunk);
|
|
485
509
|
}
|
|
486
510
|
return chunks;
|
|
487
511
|
}
|
|
@@ -557,8 +581,7 @@ function getRenderedTableWidth(columnWidths) {
|
|
|
557
581
|
return columnWidths.reduce((totalWidth, width) => totalWidth + width + spacing.sm * 2, columnWidths.length + 1);
|
|
558
582
|
}
|
|
559
583
|
function alignTableCell(value, width, align) {
|
|
560
|
-
const
|
|
561
|
-
const extraSpace = Math.max(0, width - visibleWidth);
|
|
584
|
+
const extraSpace = Math.max(0, width - visibleWidth(value));
|
|
562
585
|
if (align === "right") {
|
|
563
586
|
return `${" ".repeat(extraSpace)}${value}`;
|
|
564
587
|
}
|
|
@@ -587,3 +610,6 @@ function stripHtmlTags(value) {
|
|
|
587
610
|
}
|
|
588
611
|
return output;
|
|
589
612
|
}
|
|
613
|
+
function visibleWidth(value) {
|
|
614
|
+
return displayWidth(stripAnsi(value));
|
|
615
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "toolcraft",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.46",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"postpack": "node ../../scripts/manage-bundled-workspace-deps.mjs cleanup . toolcraft-design @poe-code/frontmatter @poe-code/agent-mcp-config @poe-code/agent-human-in-loop @poe-code/task-list @poe-code/agent-defs @poe-code/config-mutations @poe-code/process-runner tiny-mcp-client mcp-oauth auth-store"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"toolcraft-schema": "0.0.
|
|
50
|
+
"toolcraft-schema": "0.0.46",
|
|
51
51
|
"commander": "^14.0.3",
|
|
52
52
|
"fast-string-width": "^3.0.2",
|
|
53
53
|
"fast-wrap-ansi": "^0.2.0",
|