toolcraft 0.0.18 → 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.
- package/node_modules/@poe-code/config-mutations/dist/execution/apply-mutation.js +3 -3
- package/node_modules/@poe-code/config-mutations/dist/mutations/template-mutation.d.ts +3 -3
- package/node_modules/@poe-code/config-mutations/dist/template/render.d.ts +0 -1
- package/node_modules/@poe-code/config-mutations/dist/template/render.js +2 -22
- package/node_modules/@poe-code/config-mutations/package.json +1 -4
- package/node_modules/@poe-code/design-system/dist/acp/components.js +15 -13
- package/node_modules/@poe-code/design-system/dist/components/color.d.ts +31 -0
- package/node_modules/@poe-code/design-system/dist/components/color.js +101 -0
- package/node_modules/@poe-code/design-system/dist/components/index.d.ts +4 -0
- package/node_modules/@poe-code/design-system/dist/components/index.js +2 -0
- package/node_modules/@poe-code/design-system/dist/components/logger.js +2 -2
- package/node_modules/@poe-code/design-system/dist/components/symbols.js +3 -3
- package/node_modules/@poe-code/design-system/dist/components/table.js +191 -40
- package/node_modules/@poe-code/design-system/dist/components/template.d.ts +6 -0
- package/node_modules/@poe-code/design-system/dist/components/template.js +271 -0
- package/node_modules/@poe-code/design-system/dist/components/text.js +3 -3
- package/node_modules/@poe-code/design-system/dist/dashboard/buffer.js +12 -12
- package/node_modules/@poe-code/design-system/dist/index.d.ts +4 -0
- package/node_modules/@poe-code/design-system/dist/index.js +2 -0
- package/node_modules/@poe-code/design-system/dist/internal/color-support.d.ts +9 -0
- package/node_modules/@poe-code/design-system/dist/internal/color-support.js +12 -0
- package/node_modules/@poe-code/design-system/dist/prompts/index.js +2 -2
- package/node_modules/@poe-code/design-system/dist/prompts/primitives/cancel.js +2 -2
- package/node_modules/@poe-code/design-system/dist/prompts/primitives/intro.js +2 -2
- package/node_modules/@poe-code/design-system/dist/prompts/primitives/log.js +4 -4
- package/node_modules/@poe-code/design-system/dist/prompts/primitives/note.js +5 -5
- package/node_modules/@poe-code/design-system/dist/prompts/primitives/outro.js +2 -2
- package/node_modules/@poe-code/design-system/dist/prompts/primitives/spinner.js +3 -3
- package/node_modules/@poe-code/design-system/dist/static/menu.js +5 -5
- package/node_modules/@poe-code/design-system/dist/static/spinner.js +8 -8
- package/node_modules/@poe-code/design-system/dist/tokens/colors.js +29 -29
- package/node_modules/@poe-code/design-system/dist/tokens/typography.js +6 -6
- package/node_modules/@poe-code/design-system/package.json +5 -3
- package/package.json +2 -5
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
const HTML_ESCAPE = {
|
|
2
|
+
"&": "&",
|
|
3
|
+
"<": "<",
|
|
4
|
+
">": ">",
|
|
5
|
+
'"': """,
|
|
6
|
+
"'": "'",
|
|
7
|
+
"/": "/",
|
|
8
|
+
"`": "`",
|
|
9
|
+
"=": "="
|
|
10
|
+
};
|
|
11
|
+
export function renderTemplate(template, view, options = {}) {
|
|
12
|
+
const prepared = options.yield === undefined
|
|
13
|
+
? template
|
|
14
|
+
: template.split("{{yield}}").join(options.yield);
|
|
15
|
+
const tokens = parseTemplate(prepared);
|
|
16
|
+
const escape = options.escape === "none" ? String : escapeHtml;
|
|
17
|
+
const preserveMissing = options.yield !== undefined && options.escape === "none";
|
|
18
|
+
return renderTokens(tokens, { view }, prepared, escape, preserveMissing);
|
|
19
|
+
}
|
|
20
|
+
function renderTemplateInContext(template, context, escape, preserveMissing) {
|
|
21
|
+
return renderTokens(parseTemplate(template), context, template, escape, preserveMissing);
|
|
22
|
+
}
|
|
23
|
+
function parseTemplate(template) {
|
|
24
|
+
const root = [];
|
|
25
|
+
const stack = [];
|
|
26
|
+
let tokens = root;
|
|
27
|
+
let index = 0;
|
|
28
|
+
while (index < template.length) {
|
|
29
|
+
const open = template.indexOf("{{", index);
|
|
30
|
+
if (open === -1) {
|
|
31
|
+
appendText(tokens, template.slice(index), index);
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
appendText(tokens, template.slice(index, open), index);
|
|
35
|
+
const parsed = parseTag(template, open);
|
|
36
|
+
const standalone = getStandalone(template, open, parsed.end, parsed.kind);
|
|
37
|
+
if (standalone !== undefined) {
|
|
38
|
+
trimTextAfter(tokens, standalone.lineStart);
|
|
39
|
+
}
|
|
40
|
+
if (parsed.kind === "comment") {
|
|
41
|
+
index = standalone?.nextIndex ?? parsed.end;
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
if (parsed.kind === "partial") {
|
|
45
|
+
throw new Error(`Partials are not supported: "${parsed.name}"`);
|
|
46
|
+
}
|
|
47
|
+
if (parsed.kind === "delimiter") {
|
|
48
|
+
throw new Error("Custom delimiters are not supported");
|
|
49
|
+
}
|
|
50
|
+
if (parsed.kind === "section" || parsed.kind === "inverted") {
|
|
51
|
+
const token = {
|
|
52
|
+
type: parsed.kind,
|
|
53
|
+
name: parsed.name,
|
|
54
|
+
children: [],
|
|
55
|
+
rawStart: parsed.end,
|
|
56
|
+
rawEnd: standalone?.lineStart ?? open
|
|
57
|
+
};
|
|
58
|
+
tokens.push(token);
|
|
59
|
+
stack.push({ token, parent: tokens });
|
|
60
|
+
tokens = token.children;
|
|
61
|
+
index = standalone?.nextIndex ?? parsed.end;
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
if (parsed.kind === "close") {
|
|
65
|
+
const frame = stack.pop();
|
|
66
|
+
if (frame === undefined) {
|
|
67
|
+
throw new Error(`Closing unopened section "${parsed.name}"`);
|
|
68
|
+
}
|
|
69
|
+
if (frame.token.name !== parsed.name) {
|
|
70
|
+
throw new Error(`Unclosed section "${frame.token.name}" before closing "${parsed.name}"`);
|
|
71
|
+
}
|
|
72
|
+
frame.token.rawEnd = open;
|
|
73
|
+
tokens = frame.parent;
|
|
74
|
+
index = standalone?.nextIndex ?? parsed.end;
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
tokens.push({ type: parsed.kind, name: parsed.name, raw: template.slice(open, parsed.end) });
|
|
78
|
+
index = parsed.end;
|
|
79
|
+
}
|
|
80
|
+
const frame = stack.pop();
|
|
81
|
+
if (frame !== undefined) {
|
|
82
|
+
throw new Error(`Unclosed section "${frame.token.name}"`);
|
|
83
|
+
}
|
|
84
|
+
return root;
|
|
85
|
+
}
|
|
86
|
+
function parseTag(template, open) {
|
|
87
|
+
if (template.startsWith("{{{", open)) {
|
|
88
|
+
const close = template.indexOf("}}}", open + 3);
|
|
89
|
+
if (close === -1) {
|
|
90
|
+
throw new Error("Unclosed unescaped tag");
|
|
91
|
+
}
|
|
92
|
+
return { kind: "unescaped", name: template.slice(open + 3, close).trim(), end: close + 3 };
|
|
93
|
+
}
|
|
94
|
+
const close = template.indexOf("}}", open + 2);
|
|
95
|
+
if (close === -1) {
|
|
96
|
+
throw new Error("Unclosed tag");
|
|
97
|
+
}
|
|
98
|
+
const raw = template.slice(open + 2, close).trim();
|
|
99
|
+
const sigil = raw[0];
|
|
100
|
+
const name = sigil === undefined ? "" : raw.slice(1).trim();
|
|
101
|
+
const end = close + 2;
|
|
102
|
+
if (sigil === "#")
|
|
103
|
+
return { kind: "section", name, end };
|
|
104
|
+
if (sigil === "^")
|
|
105
|
+
return { kind: "inverted", name, end };
|
|
106
|
+
if (sigil === "/")
|
|
107
|
+
return { kind: "close", name, end };
|
|
108
|
+
if (sigil === "!")
|
|
109
|
+
return { kind: "comment", name, end };
|
|
110
|
+
if (sigil === "&")
|
|
111
|
+
return { kind: "unescaped", name, end };
|
|
112
|
+
if (sigil === ">")
|
|
113
|
+
return { kind: "partial", name, end };
|
|
114
|
+
if (sigil === "=" && raw.endsWith("="))
|
|
115
|
+
return { kind: "delimiter", name, end };
|
|
116
|
+
return { kind: "name", name: raw, end };
|
|
117
|
+
}
|
|
118
|
+
function getStandalone(template, tagStart, tagEnd, kind) {
|
|
119
|
+
if (!["section", "inverted", "close", "comment", "partial", "delimiter"].includes(kind)) {
|
|
120
|
+
return undefined;
|
|
121
|
+
}
|
|
122
|
+
const lineStart = template.lastIndexOf("\n", tagStart - 1) + 1;
|
|
123
|
+
if (!isWhitespace(template.slice(lineStart, tagStart))) {
|
|
124
|
+
return undefined;
|
|
125
|
+
}
|
|
126
|
+
let cursor = tagEnd;
|
|
127
|
+
while (cursor < template.length && (template[cursor] === " " || template[cursor] === "\t")) {
|
|
128
|
+
cursor += 1;
|
|
129
|
+
}
|
|
130
|
+
if (template.startsWith("\r\n", cursor)) {
|
|
131
|
+
return { lineStart, nextIndex: cursor + 2 };
|
|
132
|
+
}
|
|
133
|
+
if (template[cursor] === "\n") {
|
|
134
|
+
return { lineStart, nextIndex: cursor + 1 };
|
|
135
|
+
}
|
|
136
|
+
if (cursor === template.length) {
|
|
137
|
+
return { lineStart, nextIndex: cursor };
|
|
138
|
+
}
|
|
139
|
+
return undefined;
|
|
140
|
+
}
|
|
141
|
+
function renderTokens(tokens, context, template, escape, preserveMissing) {
|
|
142
|
+
let output = "";
|
|
143
|
+
for (const token of tokens) {
|
|
144
|
+
switch (token.type) {
|
|
145
|
+
case "text":
|
|
146
|
+
output += token.value;
|
|
147
|
+
continue;
|
|
148
|
+
case "name":
|
|
149
|
+
case "unescaped": {
|
|
150
|
+
const value = lookup(context, token.name);
|
|
151
|
+
if (value == null) {
|
|
152
|
+
if (preserveMissing) {
|
|
153
|
+
output += token.raw;
|
|
154
|
+
}
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
const rendered = String(value);
|
|
158
|
+
output += token.type === "name" ? escape(rendered) : rendered;
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
case "inverted": {
|
|
162
|
+
const value = lookup(context, token.name);
|
|
163
|
+
if (!value || (Array.isArray(value) && value.length === 0)) {
|
|
164
|
+
output += renderTokens(token.children, context, template, escape, preserveMissing);
|
|
165
|
+
}
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
case "section": {
|
|
169
|
+
const value = lookup(context, token.name);
|
|
170
|
+
if (!value) {
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
if (Array.isArray(value)) {
|
|
174
|
+
for (const item of value) {
|
|
175
|
+
output += renderTokens(token.children, pushContext(context, item), template, escape, preserveMissing);
|
|
176
|
+
}
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
if (typeof value === "function") {
|
|
180
|
+
const raw = template.slice(token.rawStart, token.rawEnd);
|
|
181
|
+
const rendered = value.call(context.view, raw, (nextTemplate) => renderTemplateInContext(nextTemplate, context, escape, preserveMissing));
|
|
182
|
+
if (rendered != null) {
|
|
183
|
+
output += String(rendered);
|
|
184
|
+
}
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
if (typeof value === "object" || typeof value === "string" || typeof value === "number") {
|
|
188
|
+
output += renderTokens(token.children, pushContext(context, value), template, escape, preserveMissing);
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
output += renderTokens(token.children, context, template, escape, preserveMissing);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return output;
|
|
196
|
+
}
|
|
197
|
+
function lookup(context, name) {
|
|
198
|
+
if (name === ".") {
|
|
199
|
+
return callLambda(context.view, context.view);
|
|
200
|
+
}
|
|
201
|
+
let cursor = context;
|
|
202
|
+
while (cursor !== undefined) {
|
|
203
|
+
const result = name.includes(".")
|
|
204
|
+
? lookupDotted(cursor.view, name)
|
|
205
|
+
: lookupName(cursor.view, name);
|
|
206
|
+
if (result.hit) {
|
|
207
|
+
return callLambda(result.value, cursor.view);
|
|
208
|
+
}
|
|
209
|
+
cursor = cursor.parent;
|
|
210
|
+
}
|
|
211
|
+
return undefined;
|
|
212
|
+
}
|
|
213
|
+
function lookupName(view, name) {
|
|
214
|
+
if (!isPropertyContainer(view) || !hasProperty(view, name)) {
|
|
215
|
+
return { hit: false, value: undefined };
|
|
216
|
+
}
|
|
217
|
+
return { hit: true, value: view[name] };
|
|
218
|
+
}
|
|
219
|
+
function lookupDotted(view, name) {
|
|
220
|
+
const parts = name.split(".");
|
|
221
|
+
let value = view;
|
|
222
|
+
let hit = false;
|
|
223
|
+
for (let index = 0; value != null && index < parts.length; index += 1) {
|
|
224
|
+
const part = parts[index] ?? "";
|
|
225
|
+
if (index === parts.length - 1) {
|
|
226
|
+
hit = hasProperty(Object(value), part);
|
|
227
|
+
}
|
|
228
|
+
value = Object(value)[part];
|
|
229
|
+
}
|
|
230
|
+
return { hit, value };
|
|
231
|
+
}
|
|
232
|
+
function callLambda(value, view) {
|
|
233
|
+
return typeof value === "function" ? value.call(view) : value;
|
|
234
|
+
}
|
|
235
|
+
function pushContext(parent, view) {
|
|
236
|
+
return { view, parent };
|
|
237
|
+
}
|
|
238
|
+
function appendText(tokens, value, start) {
|
|
239
|
+
if (value === "") {
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
const previous = tokens[tokens.length - 1];
|
|
243
|
+
if (previous?.type === "text") {
|
|
244
|
+
previous.value += value;
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
tokens.push({ type: "text", value, start });
|
|
248
|
+
}
|
|
249
|
+
function trimTextAfter(tokens, lineStart) {
|
|
250
|
+
const previous = tokens[tokens.length - 1];
|
|
251
|
+
if (previous?.type !== "text") {
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
const keep = Math.max(0, lineStart - previous.start);
|
|
255
|
+
previous.value = previous.value.slice(0, keep);
|
|
256
|
+
if (previous.value === "") {
|
|
257
|
+
tokens.pop();
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
function escapeHtml(value) {
|
|
261
|
+
return value.replace(/[&<>"'`=/]/g, (char) => HTML_ESCAPE[char] ?? char);
|
|
262
|
+
}
|
|
263
|
+
function isWhitespace(value) {
|
|
264
|
+
return value.trim() === "";
|
|
265
|
+
}
|
|
266
|
+
function isPropertyContainer(value) {
|
|
267
|
+
return (typeof value === "object" && value !== null) || typeof value === "function";
|
|
268
|
+
}
|
|
269
|
+
function hasProperty(value, key) {
|
|
270
|
+
return key in value;
|
|
271
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
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
|
import { typography } from "../tokens/typography.js";
|
|
@@ -57,7 +57,7 @@ export const text = {
|
|
|
57
57
|
return content;
|
|
58
58
|
if (format === "markdown")
|
|
59
59
|
return `\`${content}\``;
|
|
60
|
-
return
|
|
60
|
+
return color.yellow(content);
|
|
61
61
|
},
|
|
62
62
|
example(content) {
|
|
63
63
|
const format = resolveOutputFormat();
|
|
@@ -73,7 +73,7 @@ export const text = {
|
|
|
73
73
|
return content;
|
|
74
74
|
if (format === "markdown")
|
|
75
75
|
return `\`${content}\``;
|
|
76
|
-
return
|
|
76
|
+
return color.green(content);
|
|
77
77
|
},
|
|
78
78
|
link(content) {
|
|
79
79
|
const format = resolveOutputFormat();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { color } from "../components/color.js";
|
|
2
2
|
const EMPTY_CELL = { ch: " ", style: {} };
|
|
3
3
|
export class ScreenBuffer {
|
|
4
4
|
_width;
|
|
@@ -119,7 +119,7 @@ export function diff(prev, next) {
|
|
|
119
119
|
}
|
|
120
120
|
export function cellToAnsi(cell) {
|
|
121
121
|
const style = cell.style ?? {};
|
|
122
|
-
let painter =
|
|
122
|
+
let painter = color;
|
|
123
123
|
if (style.bold) {
|
|
124
124
|
painter = painter.bold;
|
|
125
125
|
}
|
|
@@ -177,20 +177,20 @@ function cellsEqual(left, right) {
|
|
|
177
177
|
&& left.style.dim === right.style.dim
|
|
178
178
|
&& left.style.underline === right.style.underline;
|
|
179
179
|
}
|
|
180
|
-
function applyForegroundColor(instance,
|
|
181
|
-
if (
|
|
182
|
-
return instance.hex(
|
|
180
|
+
function applyForegroundColor(instance, ansiColor) {
|
|
181
|
+
if (ansiColor.startsWith("#")) {
|
|
182
|
+
return instance.hex(ansiColor);
|
|
183
183
|
}
|
|
184
|
-
const painter = instance[
|
|
184
|
+
const painter = instance[ansiColor];
|
|
185
185
|
return typeof painter === "function" ? painter : instance;
|
|
186
186
|
}
|
|
187
|
-
function applyBackgroundColor(instance,
|
|
188
|
-
if (
|
|
189
|
-
return instance.bgHex(
|
|
187
|
+
function applyBackgroundColor(instance, ansiColor) {
|
|
188
|
+
if (ansiColor.startsWith("#")) {
|
|
189
|
+
return instance.bgHex(ansiColor);
|
|
190
190
|
}
|
|
191
|
-
const methodName =
|
|
192
|
-
?
|
|
193
|
-
: `bg${
|
|
191
|
+
const methodName = ansiColor.startsWith("bg")
|
|
192
|
+
? ansiColor
|
|
193
|
+
: `bg${ansiColor.charAt(0).toUpperCase()}${ansiColor.slice(1)}`;
|
|
194
194
|
const painter = instance[methodName];
|
|
195
195
|
return typeof painter === "function" ? painter : instance;
|
|
196
196
|
}
|
|
@@ -5,6 +5,8 @@ export { spacing } from "./tokens/spacing.js";
|
|
|
5
5
|
export { typography } from "./tokens/typography.js";
|
|
6
6
|
export { widths } from "./tokens/widths.js";
|
|
7
7
|
export { text } from "./components/text.js";
|
|
8
|
+
export { color } from "./components/color.js";
|
|
9
|
+
export type { Color } from "./components/color.js";
|
|
8
10
|
export { symbols } from "./components/symbols.js";
|
|
9
11
|
export { createLogger, logger } from "./components/logger.js";
|
|
10
12
|
export type { LoggerOutput } from "./components/logger.js";
|
|
@@ -15,6 +17,8 @@ export { formatCommandNotFound } from "./components/command-errors.js";
|
|
|
15
17
|
export { formatCommandNotFoundPanel } from "./components/command-errors.js";
|
|
16
18
|
export { renderTable } from "./components/table.js";
|
|
17
19
|
export type { TableColumn, RenderTableOptions } from "./components/table.js";
|
|
20
|
+
export { renderTemplate } from "./components/template.js";
|
|
21
|
+
export type { RenderTemplateOptions, TemplateEscape } from "./components/template.js";
|
|
18
22
|
export * as acp from "./acp/index.js";
|
|
19
23
|
export * as dashboard from "./dashboard/index.js";
|
|
20
24
|
export { createDashboard, shouldUseInteractiveDashboard } from "./dashboard/index.js";
|
|
@@ -6,6 +6,7 @@ export { typography } from "./tokens/typography.js";
|
|
|
6
6
|
export { widths } from "./tokens/widths.js";
|
|
7
7
|
// Components
|
|
8
8
|
export { text } from "./components/text.js";
|
|
9
|
+
export { color } from "./components/color.js";
|
|
9
10
|
export { symbols } from "./components/symbols.js";
|
|
10
11
|
export { createLogger, logger } from "./components/logger.js";
|
|
11
12
|
export { helpFormatter, formatColumns, formatCommand, formatUsage, formatOption, formatCommandList, formatOptionList } from "./components/help-formatter.js";
|
|
@@ -13,6 +14,7 @@ export * as helpFormatterPlain from "./components/help-formatter-plain.js";
|
|
|
13
14
|
export { formatCommandNotFound } from "./components/command-errors.js";
|
|
14
15
|
export { formatCommandNotFoundPanel } from "./components/command-errors.js";
|
|
15
16
|
export { renderTable } from "./components/table.js";
|
|
17
|
+
export { renderTemplate } from "./components/template.js";
|
|
16
18
|
// ACP rendering
|
|
17
19
|
export * as acp from "./acp/index.js";
|
|
18
20
|
// Dashboard
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface ColorSupportEnv {
|
|
2
|
+
NO_COLOR?: string;
|
|
3
|
+
FORCE_COLOR?: string;
|
|
4
|
+
TERM?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface ColorSupportStream {
|
|
7
|
+
isTTY?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare function supportsColor(env?: ColorSupportEnv, stream?: ColorSupportStream): boolean;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function supportsColor(env = process.env, stream = process.stdout) {
|
|
2
|
+
if (env.FORCE_COLOR !== undefined && env.FORCE_COLOR !== "0") {
|
|
3
|
+
return true;
|
|
4
|
+
}
|
|
5
|
+
if (env.NO_COLOR !== undefined) {
|
|
6
|
+
return false;
|
|
7
|
+
}
|
|
8
|
+
if (stream.isTTY !== true) {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
return typeof env.TERM === "string" && env.TERM.length > 0 && env.TERM !== "dumb";
|
|
12
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { color } from "../components/color.js";
|
|
2
2
|
import * as clack from "@clack/prompts";
|
|
3
3
|
import { resolveOutputFormat } from "../internal/output-format.js";
|
|
4
4
|
import { stripAnsi } from "../internal/strip-ansi.js";
|
|
@@ -19,7 +19,7 @@ export function introPlain(title) {
|
|
|
19
19
|
if (format === "json") {
|
|
20
20
|
return;
|
|
21
21
|
}
|
|
22
|
-
process.stdout.write(`${
|
|
22
|
+
process.stdout.write(`${color.gray("┌")} ${title}\n`);
|
|
23
23
|
}
|
|
24
24
|
export async function select(opts) {
|
|
25
25
|
return clack.select(opts);
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { color } from "../../components/color.js";
|
|
2
2
|
export { isCancel } from "@clack/prompts";
|
|
3
3
|
import { resolveOutputFormat } from "../../internal/output-format.js";
|
|
4
4
|
export function cancel(msg = "") {
|
|
5
5
|
if (resolveOutputFormat() !== "terminal") {
|
|
6
6
|
return;
|
|
7
7
|
}
|
|
8
|
-
process.stdout.write(`${
|
|
8
|
+
process.stdout.write(`${color.gray("└")} ${color.red(msg)}\n\n`);
|
|
9
9
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { color } from "../../components/color.js";
|
|
2
2
|
import { text } from "../../components/text.js";
|
|
3
3
|
import { resolveOutputFormat } from "../../internal/output-format.js";
|
|
4
4
|
import { stripAnsi } from "../../internal/strip-ansi.js";
|
|
@@ -11,5 +11,5 @@ export function intro(title) {
|
|
|
11
11
|
process.stdout.write(`# ${stripAnsi(title)}\n\n`);
|
|
12
12
|
return;
|
|
13
13
|
}
|
|
14
|
-
process.stdout.write(`${
|
|
14
|
+
process.stdout.write(`${color.gray("┌")} ${text.intro(title)}\n`);
|
|
15
15
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { color } from "../../components/color.js";
|
|
2
2
|
import { symbols } from "../../components/symbols.js";
|
|
3
3
|
import { resolveOutputFormat } from "../../internal/output-format.js";
|
|
4
4
|
import { stripAnsi } from "../../internal/strip-ansi.js";
|
|
5
|
-
function writeTerminalMessage(msg, { symbol =
|
|
5
|
+
function writeTerminalMessage(msg, { symbol = color.gray("│"), secondarySymbol = color.gray("│"), spacing = 1, withGuide = true } = {}) {
|
|
6
6
|
const lines = [];
|
|
7
7
|
const showGuide = withGuide !== false;
|
|
8
8
|
const contentLines = msg.split("\n");
|
|
@@ -78,7 +78,7 @@ export function warn(msg) {
|
|
|
78
78
|
process.stdout.write(`${JSON.stringify({ level: "warn", message: stripAnsi(msg) })}\n`);
|
|
79
79
|
return;
|
|
80
80
|
}
|
|
81
|
-
message(msg, { symbol:
|
|
81
|
+
message(msg, { symbol: color.yellow("▲") });
|
|
82
82
|
}
|
|
83
83
|
export function error(msg) {
|
|
84
84
|
const format = resolveOutputFormat();
|
|
@@ -90,7 +90,7 @@ export function error(msg) {
|
|
|
90
90
|
process.stdout.write(`${JSON.stringify({ level: "error", message: stripAnsi(msg) })}\n`);
|
|
91
91
|
return;
|
|
92
92
|
}
|
|
93
|
-
message(msg, { symbol:
|
|
93
|
+
message(msg, { symbol: color.red("■") });
|
|
94
94
|
}
|
|
95
95
|
export const log = {
|
|
96
96
|
info,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { color } from "../../components/color.js";
|
|
2
2
|
import { resolveOutputFormat } from "../../internal/output-format.js";
|
|
3
3
|
import { stripAnsi } from "../../internal/strip-ansi.js";
|
|
4
4
|
function getVisibleWidth(value) {
|
|
@@ -8,13 +8,13 @@ function renderTerminalNote(message, title) {
|
|
|
8
8
|
const contentLines = ["", ...message.split("\n"), ""];
|
|
9
9
|
const visibleTitle = stripAnsi(title ?? "");
|
|
10
10
|
const contentWidth = Math.max(visibleTitle.length, ...contentLines.map((line) => getVisibleWidth(line))) + 2;
|
|
11
|
-
const titleLine = `${
|
|
11
|
+
const titleLine = `${color.green("◇")} ${color.reset(title ?? "")} ${color.gray(`${"─".repeat(Math.max(contentWidth - visibleTitle.length - 1, 1))}╮`)}`;
|
|
12
12
|
const content = contentLines.map((line) => {
|
|
13
13
|
const padding = " ".repeat(contentWidth - getVisibleWidth(line));
|
|
14
|
-
return `${
|
|
14
|
+
return `${color.gray("│")} ${line}${padding}${color.gray("│")}`;
|
|
15
15
|
});
|
|
16
|
-
const bottom =
|
|
17
|
-
return [
|
|
16
|
+
const bottom = color.gray(`├${"─".repeat(contentWidth + 2)}╯`);
|
|
17
|
+
return [color.gray("│"), titleLine, ...content, bottom].join("\n");
|
|
18
18
|
}
|
|
19
19
|
export function note(message, title) {
|
|
20
20
|
const format = resolveOutputFormat();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { color } from "../../components/color.js";
|
|
2
2
|
import { resolveOutputFormat } from "../../internal/output-format.js";
|
|
3
3
|
import { stripAnsi } from "../../internal/strip-ansi.js";
|
|
4
4
|
export function outro(message) {
|
|
@@ -12,5 +12,5 @@ export function outro(message) {
|
|
|
12
12
|
process.stdout.write(`${JSON.stringify({ type: "outro", message: stripped })}\n`);
|
|
13
13
|
return;
|
|
14
14
|
}
|
|
15
|
-
process.stdout.write(`${
|
|
15
|
+
process.stdout.write(`${color.gray("│")}\n${color.gray("└")} ${message}\n\n`);
|
|
16
16
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { color } from "../../components/color.js";
|
|
2
2
|
import { resolveOutputFormat } from "../../internal/output-format.js";
|
|
3
3
|
import { stripAnsi } from "../../internal/strip-ansi.js";
|
|
4
4
|
import { SPINNER_FRAMES } from "../../static/spinner.js";
|
|
@@ -62,8 +62,8 @@ export function spinner() {
|
|
|
62
62
|
}
|
|
63
63
|
clearTimer();
|
|
64
64
|
const symbol = code === undefined || code === 0
|
|
65
|
-
?
|
|
66
|
-
:
|
|
65
|
+
? color.green("◆")
|
|
66
|
+
: color.red("■");
|
|
67
67
|
if (fallback) {
|
|
68
68
|
process.stdout.write(`${symbol} ${currentMessage}\n`);
|
|
69
69
|
return;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { color } from "../components/color.js";
|
|
2
2
|
import { symbols } from "../components/symbols.js";
|
|
3
3
|
import { resolveOutputFormat } from "../internal/output-format.js";
|
|
4
4
|
import { getTheme } from "../internal/theme-detect.js";
|
|
@@ -20,15 +20,15 @@ export function renderMenu(opts) {
|
|
|
20
20
|
});
|
|
21
21
|
}
|
|
22
22
|
const theme = getTheme();
|
|
23
|
-
const bar =
|
|
23
|
+
const bar = color.gray(symbols.bar);
|
|
24
24
|
const lines = [];
|
|
25
|
-
lines.push(`${
|
|
25
|
+
lines.push(`${color.cyan(symbols.active)} ${opts.message}`);
|
|
26
26
|
lines.push(bar);
|
|
27
27
|
opts.options.forEach((option, index) => {
|
|
28
28
|
const isSelected = index === selectedIndex;
|
|
29
|
-
const prefix = isSelected ?
|
|
29
|
+
const prefix = isSelected ? color.cyan(symbols.active) : color.gray(symbols.inactive);
|
|
30
30
|
const label = isSelected ? theme.accent(option.label) : option.label;
|
|
31
|
-
const hint = option.hint ?
|
|
31
|
+
const hint = option.hint ? color.dim(` (${option.hint})`) : "";
|
|
32
32
|
lines.push(`${bar} ${prefix} ${label}${hint}`);
|
|
33
33
|
});
|
|
34
34
|
lines.push(`${bar}`);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { color } from "../components/color.js";
|
|
2
2
|
import { symbols } from "../components/symbols.js";
|
|
3
3
|
import { resolveOutputFormat } from "../internal/output-format.js";
|
|
4
4
|
export const SPINNER_FRAMES = ["◒", "◐", "◓", "◑"];
|
|
@@ -16,9 +16,9 @@ export function renderSpinnerFrame(options) {
|
|
|
16
16
|
})}\n`;
|
|
17
17
|
}
|
|
18
18
|
const frame = options.frame ?? 0;
|
|
19
|
-
const spinnerChar =
|
|
20
|
-
const timerSuffix = options.timer ?
|
|
21
|
-
const bar =
|
|
19
|
+
const spinnerChar = color.magenta(SPINNER_FRAMES[frame % SPINNER_FRAMES.length]);
|
|
20
|
+
const timerSuffix = options.timer ? color.dim(` [${options.timer}]`) : "";
|
|
21
|
+
const bar = color.gray(symbols.bar);
|
|
22
22
|
return `${spinnerChar} ${options.message}${timerSuffix}\n${bar}`;
|
|
23
23
|
}
|
|
24
24
|
export function renderSpinnerStopped(options) {
|
|
@@ -35,12 +35,12 @@ export function renderSpinnerStopped(options) {
|
|
|
35
35
|
})}\n`;
|
|
36
36
|
}
|
|
37
37
|
const code = options.code ?? 0;
|
|
38
|
-
const symbol = code === 0 ?
|
|
39
|
-
const timerSuffix = options.timer ?
|
|
40
|
-
const bar =
|
|
38
|
+
const symbol = code === 0 ? color.green("◆") : color.red("■");
|
|
39
|
+
const timerSuffix = options.timer ? color.dim(` [${options.timer}]`) : "";
|
|
40
|
+
const bar = color.gray(symbols.bar);
|
|
41
41
|
let output = `${symbol} ${options.message}${timerSuffix}`;
|
|
42
42
|
if (options.subtext) {
|
|
43
|
-
output += `\n${bar} ${
|
|
43
|
+
output += `\n${bar} ${color.dim(options.subtext)}`;
|
|
44
44
|
}
|
|
45
45
|
return output;
|
|
46
46
|
}
|
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { color } from "../components/color.js";
|
|
2
2
|
export const brand = "#a200ff";
|
|
3
3
|
export const dark = {
|
|
4
|
-
header: (text) =>
|
|
5
|
-
divider: (text) =>
|
|
6
|
-
prompt: (text) =>
|
|
7
|
-
number: (text) =>
|
|
8
|
-
intro: (text) =>
|
|
9
|
-
resolvedSymbol:
|
|
10
|
-
errorSymbol:
|
|
11
|
-
accent: (text) =>
|
|
12
|
-
muted: (text) =>
|
|
13
|
-
success: (text) =>
|
|
14
|
-
warning: (text) =>
|
|
15
|
-
error: (text) =>
|
|
16
|
-
info: (text) =>
|
|
17
|
-
badge: (text) =>
|
|
4
|
+
header: (text) => color.magentaBright.bold(text),
|
|
5
|
+
divider: (text) => color.dim(text),
|
|
6
|
+
prompt: (text) => color.cyan(text),
|
|
7
|
+
number: (text) => color.cyanBright(text),
|
|
8
|
+
intro: (text) => color.bgMagenta.white(` Poe - ${text} `),
|
|
9
|
+
resolvedSymbol: color.magenta("◇"),
|
|
10
|
+
errorSymbol: color.red("■"),
|
|
11
|
+
accent: (text) => color.cyan(text),
|
|
12
|
+
muted: (text) => color.dim(text),
|
|
13
|
+
success: (text) => color.green(text),
|
|
14
|
+
warning: (text) => color.yellow(text),
|
|
15
|
+
error: (text) => color.red(text),
|
|
16
|
+
info: (text) => color.magenta(text),
|
|
17
|
+
badge: (text) => color.bgYellow.black(` ${text} `)
|
|
18
18
|
};
|
|
19
19
|
export const light = {
|
|
20
|
-
header: (text) =>
|
|
21
|
-
divider: (text) =>
|
|
22
|
-
prompt: (text) =>
|
|
23
|
-
number: (text) =>
|
|
24
|
-
intro: (text) =>
|
|
25
|
-
resolvedSymbol:
|
|
26
|
-
errorSymbol:
|
|
27
|
-
accent: (text) =>
|
|
28
|
-
muted: (text) =>
|
|
29
|
-
success: (text) =>
|
|
30
|
-
warning: (text) =>
|
|
31
|
-
error: (text) =>
|
|
32
|
-
info: (text) =>
|
|
33
|
-
badge: (text) =>
|
|
20
|
+
header: (text) => color.hex("#a200ff").bold(text),
|
|
21
|
+
divider: (text) => color.hex("#666666")(text),
|
|
22
|
+
prompt: (text) => color.hex("#006699").bold(text),
|
|
23
|
+
number: (text) => color.hex("#0077cc").bold(text),
|
|
24
|
+
intro: (text) => color.bgHex("#a200ff").white(` Poe - ${text} `),
|
|
25
|
+
resolvedSymbol: color.hex("#a200ff")("◇"),
|
|
26
|
+
errorSymbol: color.hex("#cc0000")("■"),
|
|
27
|
+
accent: (text) => color.hex("#006699").bold(text),
|
|
28
|
+
muted: (text) => color.hex("#666666")(text),
|
|
29
|
+
success: (text) => color.hex("#008800")(text),
|
|
30
|
+
warning: (text) => color.hex("#cc6600")(text),
|
|
31
|
+
error: (text) => color.hex("#cc0000")(text),
|
|
32
|
+
info: (text) => color.hex("#a200ff")(text),
|
|
33
|
+
badge: (text) => color.bgHex("#cc6600").white(` ${text} `)
|
|
34
34
|
};
|