@jskit-ai/jskit-cli 0.2.39 → 0.2.41
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/package.json +3 -3
- package/src/server/cliRuntime/mutations/fileMutations.js +4 -3
- package/src/server/cliRuntime/packageInstallFlow.js +7 -2
- package/src/server/cliRuntime/packageOptions.js +160 -7
- package/src/server/cliRuntime/packageTemplateResolution.js +23 -2
- package/src/server/commandHandlers/packageCommands/add.js +7 -2
- package/src/server/commandHandlers/packageCommands/discoverabilityHelp.js +253 -99
- package/src/server/commandHandlers/packageCommands/generate.js +253 -49
- package/src/server/commandHandlers/shared.js +39 -0
- package/src/server/core/argParser.js +29 -10
- package/src/server/core/buildCommandDeps.js +2 -0
- package/src/server/core/commandCatalog.js +551 -32
- package/src/server/core/createCliRunner.js +11 -1
- package/src/server/core/dispatchCli.js +31 -69
- package/src/server/core/usageHelp.js +79 -335
- package/src/server/shared/cliError.js +2 -1
- package/src/server/shared/outputFormatting.js +164 -0
|
@@ -7,6 +7,7 @@ const ANSI_CYAN = "\u001b[36m";
|
|
|
7
7
|
const ANSI_GREEN = "\u001b[32m";
|
|
8
8
|
const ANSI_YELLOW = "\u001b[33m";
|
|
9
9
|
const ANSI_WHITE = "\u001b[97m";
|
|
10
|
+
const ANSI_ESCAPE_PATTERN = new RegExp(String.raw`\u001b\[[0-9;]*m`, "gu");
|
|
10
11
|
|
|
11
12
|
function createColorFormatter(stream) {
|
|
12
13
|
const noColor = Object.prototype.hasOwnProperty.call(process.env, "NO_COLOR");
|
|
@@ -55,6 +56,148 @@ function resolveWrapWidth(stream, fallbackWidth = 80) {
|
|
|
55
56
|
return Math.floor(columns);
|
|
56
57
|
}
|
|
57
58
|
|
|
59
|
+
function measureVisibleLength(text = "") {
|
|
60
|
+
return String(text || "").replace(ANSI_ESCAPE_PATTERN, "").length;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function resolveLeadingWhitespace(text = "") {
|
|
64
|
+
const match = String(text || "").match(/^\s*/u);
|
|
65
|
+
return match?.[0] || "";
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function buildContinuationIndent({ prefix = "", fallbackPrefix = "" } = {}) {
|
|
69
|
+
const prefixLength = measureVisibleLength(prefix);
|
|
70
|
+
const fallbackLength = measureVisibleLength(fallbackPrefix);
|
|
71
|
+
const continuationLength = prefixLength > fallbackLength + 24
|
|
72
|
+
? fallbackLength
|
|
73
|
+
: prefixLength;
|
|
74
|
+
return " ".repeat(Math.max(0, continuationLength));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function resolveWrapPrefixes(line = "") {
|
|
78
|
+
const normalizedLine = String(line || "").replace(/[ \t]+$/u, "");
|
|
79
|
+
const prefixedPatterns = [
|
|
80
|
+
{
|
|
81
|
+
pattern: /^(\s+\S+)(\s{2,})(\S.*)$/u,
|
|
82
|
+
create(match) {
|
|
83
|
+
const prefix = `${match[1]}${match[2]}`;
|
|
84
|
+
return Object.freeze({
|
|
85
|
+
prefix,
|
|
86
|
+
continuationPrefix: buildContinuationIndent({
|
|
87
|
+
prefix,
|
|
88
|
+
fallbackPrefix: resolveLeadingWhitespace(match[1])
|
|
89
|
+
}),
|
|
90
|
+
text: match[3]
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
pattern: /^(\s*[-*]\s+)(.+)$/u,
|
|
96
|
+
create(match) {
|
|
97
|
+
return Object.freeze({
|
|
98
|
+
prefix: match[1],
|
|
99
|
+
continuationPrefix: buildContinuationIndent({
|
|
100
|
+
prefix: match[1],
|
|
101
|
+
fallbackPrefix: resolveLeadingWhitespace(match[1])
|
|
102
|
+
}),
|
|
103
|
+
text: match[2]
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
pattern: /^(\s*\d+[.)]\s+)(.+)$/u,
|
|
109
|
+
create(match) {
|
|
110
|
+
return Object.freeze({
|
|
111
|
+
prefix: match[1],
|
|
112
|
+
continuationPrefix: buildContinuationIndent({
|
|
113
|
+
prefix: match[1],
|
|
114
|
+
fallbackPrefix: resolveLeadingWhitespace(match[1])
|
|
115
|
+
}),
|
|
116
|
+
text: match[2]
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
pattern: /^(\s*[A-Za-z][A-Za-z0-9 ()/_-]*:\s+)(.+)$/u,
|
|
122
|
+
create(match) {
|
|
123
|
+
return Object.freeze({
|
|
124
|
+
prefix: match[1],
|
|
125
|
+
continuationPrefix: buildContinuationIndent({
|
|
126
|
+
prefix: match[1],
|
|
127
|
+
fallbackPrefix: resolveLeadingWhitespace(match[1])
|
|
128
|
+
}),
|
|
129
|
+
text: match[2]
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
];
|
|
134
|
+
|
|
135
|
+
for (const entry of prefixedPatterns) {
|
|
136
|
+
const pattern = entry.pattern;
|
|
137
|
+
const match = normalizedLine.match(pattern);
|
|
138
|
+
if (!match) {
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
return entry.create(match);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const leadingWhitespaceMatch = normalizedLine.match(/^(\s*)(.*)$/u);
|
|
145
|
+
const prefix = leadingWhitespaceMatch?.[1] || "";
|
|
146
|
+
const text = leadingWhitespaceMatch?.[2] || "";
|
|
147
|
+
return Object.freeze({
|
|
148
|
+
prefix,
|
|
149
|
+
continuationPrefix: prefix,
|
|
150
|
+
text
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function wrapOutputLine(line = "", { wrapWidth = 80 } = {}) {
|
|
155
|
+
const normalizedLine = String(line || "").replace(/[ \t]+$/u, "");
|
|
156
|
+
if (!normalizedLine.trim()) {
|
|
157
|
+
return [""];
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const width = Math.max(20, Number(wrapWidth) || 80);
|
|
161
|
+
const { prefix, continuationPrefix, text } = resolveWrapPrefixes(normalizedLine);
|
|
162
|
+
const words = String(text || "").trim().split(/\s+/u).filter(Boolean);
|
|
163
|
+
if (words.length < 1) {
|
|
164
|
+
return [normalizedLine];
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const lines = [];
|
|
168
|
+
let currentPrefix = prefix;
|
|
169
|
+
let currentLine = currentPrefix;
|
|
170
|
+
let currentLength = measureVisibleLength(currentPrefix);
|
|
171
|
+
|
|
172
|
+
for (const word of words) {
|
|
173
|
+
const separator = currentLength > measureVisibleLength(currentPrefix) ? " " : "";
|
|
174
|
+
const nextLength = currentLength + measureVisibleLength(separator) + measureVisibleLength(word);
|
|
175
|
+
if (currentLength > measureVisibleLength(currentPrefix) && nextLength > width) {
|
|
176
|
+
lines.push(currentLine);
|
|
177
|
+
currentPrefix = continuationPrefix;
|
|
178
|
+
currentLine = `${currentPrefix}${word}`;
|
|
179
|
+
currentLength = measureVisibleLength(currentPrefix) + measureVisibleLength(word);
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
currentLine = `${currentLine}${separator}${word}`;
|
|
184
|
+
currentLength = nextLength;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
lines.push(currentLine);
|
|
188
|
+
return lines;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function writeWrappedLines({ stdout, lines, wrapWidth } = {}) {
|
|
192
|
+
const output = stdout || process.stdout;
|
|
193
|
+
const width = resolveWrapWidth(output, wrapWidth ?? 100);
|
|
194
|
+
for (const line of ensureArray(lines)) {
|
|
195
|
+
for (const wrappedLine of wrapOutputLine(line, { wrapWidth: width })) {
|
|
196
|
+
output.write(`${wrappedLine}\n`);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
58
201
|
function writeWrappedItems({ stdout, heading, items, lineIndent = " ", wrapWidth = 80 }) {
|
|
59
202
|
const records = ensureArray(items)
|
|
60
203
|
.map((entry) => {
|
|
@@ -96,8 +239,29 @@ function writeWrappedItems({ stdout, heading, items, lineIndent = " ", wrapWidt
|
|
|
96
239
|
}
|
|
97
240
|
}
|
|
98
241
|
|
|
242
|
+
function renderInlineCodeSpans(text = "", color = null) {
|
|
243
|
+
const sourceText = String(text || "");
|
|
244
|
+
if (!sourceText.includes("`")) {
|
|
245
|
+
return sourceText;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
return sourceText.replace(/`([^`]+)`/g, (_match, codeText) => {
|
|
249
|
+
const normalizedCodeText = String(codeText || "");
|
|
250
|
+
if (!normalizedCodeText) {
|
|
251
|
+
return "``";
|
|
252
|
+
}
|
|
253
|
+
if (!color || typeof color.item !== "function") {
|
|
254
|
+
return `\`${normalizedCodeText}\``;
|
|
255
|
+
}
|
|
256
|
+
const rendered = String(color.item(normalizedCodeText));
|
|
257
|
+
return rendered === normalizedCodeText ? `\`${normalizedCodeText}\`` : rendered;
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
|
|
99
261
|
export {
|
|
100
262
|
createColorFormatter,
|
|
263
|
+
renderInlineCodeSpans,
|
|
101
264
|
resolveWrapWidth,
|
|
265
|
+
writeWrappedLines,
|
|
102
266
|
writeWrappedItems
|
|
103
267
|
};
|