burgee 0.6.0 → 0.7.0
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/README.md +37 -2
- package/dist/cli.js +2 -0
- package/dist/commander/command.d.ts +6 -6
- package/dist/commander/command.js +43 -32
- package/dist/completions.d.ts +8 -0
- package/dist/completions.js +5 -1
- package/dist/definition.d.ts +45 -0
- package/dist/definition.js +57 -0
- package/dist/execute.d.ts +12 -3
- package/dist/execute.js +57 -37
- package/dist/help.d.ts +6 -1
- package/dist/help.js +35 -17
- package/dist/index.d.ts +5 -3
- package/dist/index.js +5 -3
- package/dist/manifest.d.ts +95 -13
- package/dist/manifest.js +16 -5
- package/dist/mcp.d.ts +11 -1
- package/dist/mcp.js +2 -1
- package/dist/names.d.ts +6 -0
- package/dist/names.js +3 -0
- package/dist/plugin.d.ts +48 -0
- package/dist/plugin.js +82 -0
- package/dist/runtime.d.ts +57 -1
- package/dist/runtime.js +80 -11
- package/dist/schema.d.ts +19 -3
- package/dist/schema.js +9 -3
- package/dist/schema.json +1 -0
- package/dist/shutdown.d.ts +70 -0
- package/dist/shutdown.js +27 -0
- package/dist/testing-helpers.js +8 -7
- package/dist/unknown-option.d.ts +1 -0
- package/dist/unknown-option.js +1 -0
- package/dist/validate.d.ts +5 -8
- package/dist/validate.js +2 -25
- package/dist/yargs/burgee.d.ts +2 -2
- package/dist/yargs/cliui.d.ts +6 -10
- package/dist/yargs/cliui.js +103 -247
- package/dist/yargs/factory.d.ts +2 -2
- package/dist/yargs/factory.js +7 -2
- package/dist/yargs/shim.js +18 -11
- package/dist/yargs/utils.js +5 -4
- package/dist/yargs-parser.js +3 -3
- package/package.json +16 -4
package/dist/yargs/cliui.js
CHANGED
|
@@ -1,221 +1,37 @@
|
|
|
1
|
+
import { strip, width, wrap } from "linegauge";
|
|
2
|
+
import { host } from "../runtime.js";
|
|
1
3
|
/**
|
|
2
|
-
* cliui 9 — the column layout yargs' usage renders through — with the
|
|
3
|
-
*
|
|
4
|
+
* cliui 9 — the column layout yargs' usage renders through — with the wrap-ansi it depends
|
|
5
|
+
* on, ported for `burgee/yargs`. Width and escape-stripping come from linegauge. The wrapping
|
|
4
6
|
* arithmetic is byte-for-byte the upstream's: yargs' usage tests compare whole help
|
|
5
7
|
* screens.
|
|
6
8
|
*/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
(code >= 0x20000 && code <= 0x3fffd));
|
|
32
|
-
}
|
|
33
|
-
export function stringWidth(input) {
|
|
34
|
-
if (typeof input !== 'string' || input.length === 0)
|
|
35
|
-
return 0;
|
|
36
|
-
const string = stripAnsi(input);
|
|
37
|
-
if (string.length === 0)
|
|
38
|
-
return 0;
|
|
39
|
-
let width = 0;
|
|
40
|
-
for (const { segment } of segmenter.segment(string)) {
|
|
41
|
-
const code = segment.codePointAt(0);
|
|
42
|
-
if (code <= 0x1f || (code >= 0x7f && code <= 0x9f))
|
|
43
|
-
continue;
|
|
44
|
-
if ((code >= 0x200b && code <= 0x200f) || code === 0xfeff)
|
|
45
|
-
continue;
|
|
46
|
-
if (code >= 0x300 && code <= 0x36f)
|
|
47
|
-
continue;
|
|
48
|
-
if (EMOJI.test(segment)) {
|
|
49
|
-
width += 2;
|
|
50
|
-
continue;
|
|
51
|
-
}
|
|
52
|
-
width += isWide(code) ? 2 : 1;
|
|
53
|
-
}
|
|
54
|
-
return width;
|
|
55
|
-
}
|
|
56
|
-
/** ansi-styles' open→close map, the part wrap-ansi reads. */
|
|
57
|
-
function closeCode(code) {
|
|
58
|
-
if (code === 1 || code === 2)
|
|
59
|
-
return 22;
|
|
60
|
-
if (code === 3)
|
|
61
|
-
return 23;
|
|
62
|
-
if (code === 4)
|
|
63
|
-
return 24;
|
|
64
|
-
if (code === 7)
|
|
65
|
-
return 27;
|
|
66
|
-
if (code === 8)
|
|
67
|
-
return 28;
|
|
68
|
-
if (code === 9)
|
|
69
|
-
return 29;
|
|
70
|
-
if ((code >= 30 && code <= 37) || (code >= 90 && code <= 97))
|
|
71
|
-
return 39;
|
|
72
|
-
if ((code >= 40 && code <= 47) || (code >= 100 && code <= 107))
|
|
73
|
-
return 49;
|
|
74
|
-
return undefined;
|
|
75
|
-
}
|
|
76
|
-
const ESC = '\u001B';
|
|
77
|
-
const ESCAPES = new Set([ESC, '\u009B']);
|
|
78
|
-
const END_CODE = 39;
|
|
79
|
-
const ANSI_ESCAPE_BELL = '\u0007';
|
|
80
|
-
const ANSI_CSI = '[';
|
|
81
|
-
const ANSI_OSC = ']';
|
|
82
|
-
const ANSI_SGR_TERMINATOR = 'm';
|
|
83
|
-
const ANSI_ESCAPE_LINK = `${ANSI_OSC}8;;`;
|
|
84
|
-
const wrapAnsiCode = (code) => `${ESC}${ANSI_CSI}${code}${ANSI_SGR_TERMINATOR}`;
|
|
85
|
-
const wrapAnsiHyperlink = (uri) => `${ESC}${ANSI_ESCAPE_LINK}${uri}${ANSI_ESCAPE_BELL}`;
|
|
86
|
-
const wordLengths = (string) => string.split(' ').map((character) => stringWidth(character));
|
|
87
|
-
function wrapWord(rows, word, columns) {
|
|
88
|
-
const characters = [...word];
|
|
89
|
-
let isInsideEscape = false;
|
|
90
|
-
let isInsideLinkEscape = false;
|
|
91
|
-
let visible = stringWidth(stripAnsi(rows.at(-1)));
|
|
92
|
-
for (const [index, character] of characters.entries()) {
|
|
93
|
-
const characterLength = stringWidth(character);
|
|
94
|
-
if (visible + characterLength <= columns)
|
|
95
|
-
rows[rows.length - 1] += character;
|
|
96
|
-
else {
|
|
97
|
-
rows.push(character);
|
|
98
|
-
visible = 0;
|
|
99
|
-
}
|
|
100
|
-
if (ESCAPES.has(character)) {
|
|
101
|
-
isInsideEscape = true;
|
|
102
|
-
isInsideLinkEscape = characters.slice(index + 1).join('').startsWith(ANSI_ESCAPE_LINK);
|
|
103
|
-
}
|
|
104
|
-
if (isInsideEscape) {
|
|
105
|
-
if (isInsideLinkEscape) {
|
|
106
|
-
if (character === ANSI_ESCAPE_BELL) {
|
|
107
|
-
isInsideEscape = false;
|
|
108
|
-
isInsideLinkEscape = false;
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
else if (character === ANSI_SGR_TERMINATOR)
|
|
112
|
-
isInsideEscape = false;
|
|
113
|
-
continue;
|
|
114
|
-
}
|
|
115
|
-
visible += characterLength;
|
|
116
|
-
if (visible === columns && index < characters.length - 1) {
|
|
117
|
-
rows.push('');
|
|
118
|
-
visible = 0;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
if (!visible && rows.at(-1).length > 0 && rows.length > 1)
|
|
122
|
-
rows[rows.length - 2] += rows.pop();
|
|
123
|
-
}
|
|
124
|
-
function stringVisibleTrimSpacesRight(string) {
|
|
125
|
-
const words = string.split(' ');
|
|
126
|
-
let last = words.length;
|
|
127
|
-
while (last > 0) {
|
|
128
|
-
if (stringWidth(words[last - 1]) > 0)
|
|
129
|
-
break;
|
|
130
|
-
last--;
|
|
131
|
-
}
|
|
132
|
-
if (last === words.length)
|
|
133
|
-
return string;
|
|
134
|
-
return words.slice(0, last).join(' ') + words.slice(last).join('');
|
|
135
|
-
}
|
|
136
|
-
function execWrap(string, columns, options = {}) {
|
|
137
|
-
if (options.trim !== false && string.trim() === '')
|
|
138
|
-
return '';
|
|
139
|
-
let returnValue = '';
|
|
140
|
-
let escapeCode;
|
|
141
|
-
let escapeUrl;
|
|
142
|
-
const lengths = wordLengths(string);
|
|
143
|
-
let rows = [''];
|
|
144
|
-
for (const [index, word] of string.split(' ').entries()) {
|
|
145
|
-
if (options.trim !== false)
|
|
146
|
-
rows[rows.length - 1] = rows.at(-1).trimStart();
|
|
147
|
-
let rowLength = stringWidth(rows.at(-1));
|
|
148
|
-
if (index !== 0) {
|
|
149
|
-
if (rowLength >= columns && (options.wordWrap === false || options.trim === false)) {
|
|
150
|
-
rows.push('');
|
|
151
|
-
rowLength = 0;
|
|
152
|
-
}
|
|
153
|
-
if (rowLength > 0 || options.trim === false) {
|
|
154
|
-
rows[rows.length - 1] += ' ';
|
|
155
|
-
rowLength++;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
const length = lengths[index];
|
|
159
|
-
if (options.hard && length > columns) {
|
|
160
|
-
const remainingColumns = columns - rowLength;
|
|
161
|
-
const breaksStartingThisLine = 1 + Math.floor((length - remainingColumns - 1) / columns);
|
|
162
|
-
const breaksStartingNextLine = Math.floor((length - 1) / columns);
|
|
163
|
-
if (breaksStartingNextLine < breaksStartingThisLine)
|
|
164
|
-
rows.push('');
|
|
165
|
-
wrapWord(rows, word, columns);
|
|
166
|
-
continue;
|
|
167
|
-
}
|
|
168
|
-
if (rowLength + length > columns && rowLength > 0 && length > 0) {
|
|
169
|
-
if (options.wordWrap === false && rowLength < columns) {
|
|
170
|
-
wrapWord(rows, word, columns);
|
|
171
|
-
continue;
|
|
172
|
-
}
|
|
173
|
-
rows.push('');
|
|
174
|
-
}
|
|
175
|
-
if (rowLength + length > columns && options.wordWrap === false) {
|
|
176
|
-
wrapWord(rows, word, columns);
|
|
177
|
-
continue;
|
|
178
|
-
}
|
|
179
|
-
rows[rows.length - 1] += word;
|
|
180
|
-
}
|
|
181
|
-
if (options.trim !== false)
|
|
182
|
-
rows = rows.map(stringVisibleTrimSpacesRight);
|
|
183
|
-
const pre = [...rows.join('\n')];
|
|
184
|
-
for (const [index, character] of pre.entries()) {
|
|
185
|
-
returnValue += character;
|
|
186
|
-
if (ESCAPES.has(character)) {
|
|
187
|
-
const found = new RegExp(`(?:\\${ANSI_CSI}(?<code>\\d+)m|\\${ANSI_ESCAPE_LINK}(?<uri>.*)${ANSI_ESCAPE_BELL})`).exec(pre.slice(index).join(''));
|
|
188
|
-
const groups = found?.groups ?? {};
|
|
189
|
-
if (groups.code !== undefined) {
|
|
190
|
-
const code = Number.parseFloat(groups.code);
|
|
191
|
-
escapeCode = code === END_CODE ? undefined : code;
|
|
192
|
-
}
|
|
193
|
-
else if (groups.uri !== undefined)
|
|
194
|
-
escapeUrl = groups.uri.length === 0 ? undefined : groups.uri;
|
|
195
|
-
}
|
|
196
|
-
const code = closeCode(Number(escapeCode));
|
|
197
|
-
if (pre[index + 1] === '\n') {
|
|
198
|
-
if (escapeUrl)
|
|
199
|
-
returnValue += wrapAnsiHyperlink('');
|
|
200
|
-
if (escapeCode && code)
|
|
201
|
-
returnValue += wrapAnsiCode(code);
|
|
202
|
-
}
|
|
203
|
-
else if (character === '\n') {
|
|
204
|
-
if (escapeCode && code)
|
|
205
|
-
returnValue += wrapAnsiCode(escapeCode);
|
|
206
|
-
if (escapeUrl)
|
|
207
|
-
returnValue += wrapAnsiHyperlink(escapeUrl);
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
return returnValue;
|
|
211
|
-
}
|
|
9
|
+
/*
|
|
10
|
+
* `width` and `strip` are linegauge's — measuring text and removing escapes is the layer
|
|
11
|
+
* below this one, and this file had its own copies of both. They were not merely duplicated,
|
|
12
|
+
* they were wrong: the ITU T.416 sub-parameter form `ESC[38:2::255:0:0m`, which chalk emits
|
|
13
|
+
* for truecolor, left `:2::255:0:0m` behind and measured a 13-column string as 25. linegauge
|
|
14
|
+
* fixed that in its own `strip`; burgee inherited nothing because it was not asking.
|
|
15
|
+
*
|
|
16
|
+
* The names stay, because `usage.ts` and `shim.ts` import them and the upstream port reads
|
|
17
|
+
* the way cliui reads.
|
|
18
|
+
*/
|
|
19
|
+
export const stripAnsi = (str) => typeof str === "string" ? strip(str) : str;
|
|
20
|
+
export const stringWidth = (input) => typeof input === "string" ? width(input) : 0;
|
|
21
|
+
/*
|
|
22
|
+
* The wrap is linegauge's too. This file carried a wrap-ansi port — ansi-styles' open→close
|
|
23
|
+
* map, an escape-state machine over every character, hyperlink re-opening — to wrap a line
|
|
24
|
+
* without breaking the styling across it. That is the same job `linegauge/wrap` exists for
|
|
25
|
+
* and grades against wrap-ansi, so burgee kept a second implementation of a thing the layer
|
|
26
|
+
* below already owned.
|
|
27
|
+
*
|
|
28
|
+
* Checked before swapping, because yargs' usage tests compare whole help screens: the two
|
|
29
|
+
* agreed on all ten shapes probed — plain prose at several widths, an unbreakable word,
|
|
30
|
+
* SGR-coloured text, single characters, CJK, an embedded newline, leading and trailing
|
|
31
|
+
* spaces, empty, and a string exactly the column width.
|
|
32
|
+
*/
|
|
212
33
|
export function wrapAnsi(string, columns, options) {
|
|
213
|
-
return String(string)
|
|
214
|
-
.normalize()
|
|
215
|
-
.replace(/\r\n/g, '\n')
|
|
216
|
-
.split('\n')
|
|
217
|
-
.map((line) => execWrap(line, columns, options))
|
|
218
|
-
.join('\n');
|
|
34
|
+
return wrap(String(string).normalize().replace(/\r\n/g, "\n"), columns, options);
|
|
219
35
|
}
|
|
220
36
|
const align = { right: alignRight, center: alignCenter };
|
|
221
37
|
const top = 0;
|
|
@@ -240,21 +56,24 @@ export class UI {
|
|
|
240
56
|
}
|
|
241
57
|
div(...args) {
|
|
242
58
|
if (args.length === 0)
|
|
243
|
-
this.div(
|
|
244
|
-
if (this.wrap &&
|
|
59
|
+
this.div("");
|
|
60
|
+
if (this.wrap &&
|
|
61
|
+
this.shouldApplyLayoutDSL(...args) &&
|
|
62
|
+
typeof args[0] === "string")
|
|
245
63
|
return this.applyLayoutDSL(args[0]);
|
|
246
|
-
const cols = args.map((arg) =>
|
|
64
|
+
const cols = args.map((arg) => typeof arg === "string" ? this.colFromString(arg) : arg);
|
|
247
65
|
this.rows.push(cols);
|
|
248
66
|
return cols;
|
|
249
67
|
}
|
|
250
68
|
shouldApplyLayoutDSL(...args) {
|
|
251
|
-
return args.length === 1 && typeof args[0] ===
|
|
69
|
+
return (args.length === 1 && typeof args[0] === "string" && /[\t\n]/.test(args[0]));
|
|
252
70
|
}
|
|
253
71
|
applyLayoutDSL(str) {
|
|
254
|
-
const rows = str.split(
|
|
72
|
+
const rows = str.split("\n").map((row) => row.split("\t"));
|
|
255
73
|
let leftColumnWidth = 0;
|
|
256
74
|
rows.forEach((columns) => {
|
|
257
|
-
if (columns.length > 1 &&
|
|
75
|
+
if (columns.length > 1 &&
|
|
76
|
+
stringWidth(columns[0]) > leftColumnWidth) {
|
|
258
77
|
leftColumnWidth = Math.min(Math.floor(this.width * 0.5), stringWidth(columns[0]));
|
|
259
78
|
}
|
|
260
79
|
});
|
|
@@ -271,8 +90,20 @@ export class UI {
|
|
|
271
90
|
return { text, padding: this.measurePadding(text) };
|
|
272
91
|
}
|
|
273
92
|
measurePadding(str) {
|
|
93
|
+
// An unanchored `\s*$` was the upstream spelling, and it is quadratic: the engine
|
|
94
|
+
// retries at every position, so a cell of 50,000 spaces then an `x` costs 1,346 ms
|
|
95
|
+
// here — CodeQL alert 35, "polynomial regular expression used on uncontrolled data",
|
|
96
|
+
// raised once `stripAnsi` became library input. Spaces, not the tabs the alert names:
|
|
97
|
+
// a tab routes into `applyLayoutDSL`, which splits on it long before this runs.
|
|
98
|
+
// `trim{Start,End}` remove exactly the set `\s` matches (WhiteSpace + LineTerminator)
|
|
99
|
+
// and are linear, so this is the same measurement without the backtracking.
|
|
274
100
|
const noAnsi = stripAnsi(str);
|
|
275
|
-
return [
|
|
101
|
+
return [
|
|
102
|
+
0,
|
|
103
|
+
noAnsi.length - noAnsi.trimEnd().length,
|
|
104
|
+
0,
|
|
105
|
+
noAnsi.length - noAnsi.trimStart().length,
|
|
106
|
+
];
|
|
276
107
|
}
|
|
277
108
|
toString() {
|
|
278
109
|
const lines = [];
|
|
@@ -282,36 +113,36 @@ export class UI {
|
|
|
282
113
|
return lines
|
|
283
114
|
.filter((line) => !line.hidden)
|
|
284
115
|
.map((line) => line.text)
|
|
285
|
-
.join(
|
|
116
|
+
.join("\n");
|
|
286
117
|
}
|
|
287
118
|
rowToString(row, lines) {
|
|
288
119
|
this.rasterize(row).forEach((rrow, r) => {
|
|
289
|
-
let str =
|
|
120
|
+
let str = "";
|
|
290
121
|
rrow.forEach((col, c) => {
|
|
291
122
|
const column = row[c];
|
|
292
123
|
const { width } = column;
|
|
293
124
|
const wrapWidth = this.negatePadding(column);
|
|
294
125
|
let ts = col;
|
|
295
126
|
if (wrapWidth > stringWidth(col))
|
|
296
|
-
ts +=
|
|
297
|
-
if (column.align && column.align !==
|
|
127
|
+
ts += " ".repeat(wrapWidth - stringWidth(col));
|
|
128
|
+
if (column.align && column.align !== "left" && this.wrap) {
|
|
298
129
|
const fn = align[column.align];
|
|
299
130
|
ts = fn(ts, wrapWidth);
|
|
300
131
|
if (stringWidth(ts) < wrapWidth)
|
|
301
|
-
ts +=
|
|
132
|
+
ts += " ".repeat((width || 0) - stringWidth(ts) - 1);
|
|
302
133
|
}
|
|
303
134
|
const padding = column.padding || [0, 0, 0, 0];
|
|
304
135
|
if (padding[left])
|
|
305
|
-
str +=
|
|
306
|
-
str += addBorder(column, ts,
|
|
136
|
+
str += " ".repeat(padding[left]);
|
|
137
|
+
str += addBorder(column, ts, "| ");
|
|
307
138
|
str += ts;
|
|
308
|
-
str += addBorder(column, ts,
|
|
139
|
+
str += addBorder(column, ts, " |");
|
|
309
140
|
if (padding[right])
|
|
310
|
-
str +=
|
|
141
|
+
str += " ".repeat(padding[right]);
|
|
311
142
|
if (r === 0 && lines.length > 0)
|
|
312
143
|
str = this.renderInline(str, lines.at(-1));
|
|
313
144
|
});
|
|
314
|
-
lines.push({ text: str
|
|
145
|
+
lines.push({ text: trimTrailingSpaces(str), span: row.span });
|
|
315
146
|
});
|
|
316
147
|
return lines;
|
|
317
148
|
}
|
|
@@ -329,7 +160,9 @@ export class UI {
|
|
|
329
160
|
if (leadingWhitespace < targetTextWidth)
|
|
330
161
|
return source;
|
|
331
162
|
previousLine.hidden = true;
|
|
332
|
-
return target.trimEnd() +
|
|
163
|
+
return (target.trimEnd() +
|
|
164
|
+
" ".repeat(leadingWhitespace - targetTextWidth) +
|
|
165
|
+
source.trimStart());
|
|
333
166
|
}
|
|
334
167
|
rasterize(row) {
|
|
335
168
|
const rrows = [];
|
|
@@ -338,16 +171,18 @@ export class UI {
|
|
|
338
171
|
row.forEach((col, c) => {
|
|
339
172
|
col.width = widths[c];
|
|
340
173
|
if (this.wrap)
|
|
341
|
-
wrapped = wrapAnsi(col.text, this.negatePadding(col), {
|
|
174
|
+
wrapped = wrapAnsi(col.text, this.negatePadding(col), {
|
|
175
|
+
hard: true,
|
|
176
|
+
}).split("\n");
|
|
342
177
|
else
|
|
343
|
-
wrapped = col.text.split(
|
|
178
|
+
wrapped = col.text.split("\n");
|
|
344
179
|
if (col.border) {
|
|
345
|
-
wrapped.unshift(`.${
|
|
346
|
-
wrapped.push(`'${
|
|
180
|
+
wrapped.unshift(`.${"-".repeat(this.negatePadding(col) + 2)}.`);
|
|
181
|
+
wrapped.push(`'${"-".repeat(this.negatePadding(col) + 2)}'`);
|
|
347
182
|
}
|
|
348
183
|
if (col.padding) {
|
|
349
|
-
wrapped.unshift(...new Array(col.padding[top] || 0).fill(
|
|
350
|
-
wrapped.push(...new Array(col.padding[bottom] || 0).fill(
|
|
184
|
+
wrapped.unshift(...new Array(col.padding[top] || 0).fill(""));
|
|
185
|
+
wrapped.push(...new Array(col.padding[bottom] || 0).fill(""));
|
|
351
186
|
}
|
|
352
187
|
wrapped.forEach((str, r) => {
|
|
353
188
|
if (!rrows[r])
|
|
@@ -355,7 +190,7 @@ export class UI {
|
|
|
355
190
|
const rrow = rrows[r];
|
|
356
191
|
for (let i = 0; i < c; i++) {
|
|
357
192
|
if (rrow[i] === undefined)
|
|
358
|
-
rrow.push(
|
|
193
|
+
rrow.push("");
|
|
359
194
|
}
|
|
360
195
|
rrow.push(str);
|
|
361
196
|
});
|
|
@@ -384,18 +219,39 @@ export class UI {
|
|
|
384
219
|
return undefined;
|
|
385
220
|
});
|
|
386
221
|
const unsetWidth = unset ? Math.floor(remainingWidth / unset) : 0;
|
|
387
|
-
return widths.map((w, i) =>
|
|
222
|
+
return widths.map((w, i) => w === undefined ? Math.max(unsetWidth, minWidth(row[i])) : w);
|
|
388
223
|
}
|
|
389
224
|
}
|
|
225
|
+
/*
|
|
226
|
+
* `str.replace(/ +$/, "")` was the upstream spelling, and it is the same quadratic shape
|
|
227
|
+
* `measurePadding` had: the start is unanchored, so the engine retries the match at every
|
|
228
|
+
* position in the run of spaces and each attempt walks to the end before failing on the
|
|
229
|
+
* character that is not the end. A row built from a cell of 50,000 spaces then an `x` is
|
|
230
|
+
* 100,001 characters of which the first 50,000 are the left padding, and trimming it cost
|
|
231
|
+
* 1,049 ms of `toString()`'s 1,223 ms. Doubling the cell quadrupled it.
|
|
232
|
+
*
|
|
233
|
+
* `trimEnd()` is linear but not the same function — it also removes tabs, newlines and the
|
|
234
|
+
* rest of `\s`. A trailing tab does reach here: with `wrap: false`, `rasterize` only splits
|
|
235
|
+
* the cell on newlines, so nothing expands the tab and nothing routes the string through
|
|
236
|
+
* `applyLayoutDSL` (that check is behind `this.wrap`). `cliui({ wrap: false }).div('a\t')`
|
|
237
|
+
* renders `'a\t'` today and would render `'a'` under `trimEnd`, and the yargs usage tests
|
|
238
|
+
* compare whole help screens. This removes exactly U+0020, exactly as the regex did.
|
|
239
|
+
*/
|
|
240
|
+
function trimTrailingSpaces(str) {
|
|
241
|
+
let end = str.length;
|
|
242
|
+
while (end > 0 && str[end - 1] === " ")
|
|
243
|
+
end--;
|
|
244
|
+
return end === str.length ? str : str.slice(0, end);
|
|
245
|
+
}
|
|
390
246
|
function addBorder(col, ts, style) {
|
|
391
247
|
if (col.border) {
|
|
392
248
|
if (/[.']-+[.']/.test(ts))
|
|
393
|
-
return
|
|
249
|
+
return "";
|
|
394
250
|
if (ts.trim().length !== 0)
|
|
395
251
|
return style;
|
|
396
|
-
return
|
|
252
|
+
return " ";
|
|
397
253
|
}
|
|
398
|
-
return
|
|
254
|
+
return "";
|
|
399
255
|
}
|
|
400
256
|
function minWidth(col) {
|
|
401
257
|
const padding = col.padding || [];
|
|
@@ -405,15 +261,15 @@ function minWidth(col) {
|
|
|
405
261
|
return min;
|
|
406
262
|
}
|
|
407
263
|
function getWindowWidth() {
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
return 80;
|
|
264
|
+
// `host.columns` carries the upstream's guard on the process global itself, so a bundle
|
|
265
|
+
// that has no process at all still falls back to 80 rather than throwing.
|
|
266
|
+
return host.columns || 80;
|
|
411
267
|
}
|
|
412
268
|
function alignRight(str, width) {
|
|
413
269
|
str = str.trim();
|
|
414
270
|
const strWidth = stringWidth(str);
|
|
415
271
|
if (strWidth < width)
|
|
416
|
-
return
|
|
272
|
+
return " ".repeat(width - strWidth) + str;
|
|
417
273
|
return str;
|
|
418
274
|
}
|
|
419
275
|
function alignCenter(str, width) {
|
|
@@ -421,7 +277,7 @@ function alignCenter(str, width) {
|
|
|
421
277
|
const strWidth = stringWidth(str);
|
|
422
278
|
if (strWidth >= width)
|
|
423
279
|
return str;
|
|
424
|
-
return
|
|
280
|
+
return " ".repeat((width - strWidth) >> 1) + str;
|
|
425
281
|
}
|
|
426
282
|
export function cliui(opts) {
|
|
427
283
|
return new UI({ width: opts?.width || getWindowWidth(), wrap: opts?.wrap });
|
package/dist/yargs/factory.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* `getInternalMethods()` seam are the upstream's — that is what makes a user's
|
|
6
6
|
* existing program run unchanged (J2).
|
|
7
7
|
*/
|
|
8
|
-
import { type
|
|
8
|
+
import { type DeclaredEffects, Manifest, type Plugin } from '../manifest.js';
|
|
9
9
|
import { type CommandInstance } from './command.js';
|
|
10
10
|
import { type CompletionFunction } from './completion.js';
|
|
11
11
|
import { type Middleware } from './middleware.js';
|
|
@@ -179,7 +179,7 @@ export declare class YargsInstance {
|
|
|
179
179
|
*/
|
|
180
180
|
get manifest(): Manifest;
|
|
181
181
|
/** burgee: declare what the command does to the world (N6); what exposes it as an MCP tool (N2). */
|
|
182
|
-
effects(value:
|
|
182
|
+
effects(value: DeclaredEffects): this;
|
|
183
183
|
/** Additive: plugins yargs never had. `preRun`/`postRun` fire around every handler. */
|
|
184
184
|
use(plugin: Plugin): this;
|
|
185
185
|
/**
|
package/dist/yargs/factory.js
CHANGED
|
@@ -9,7 +9,7 @@ var _a;
|
|
|
9
9
|
import { ExitCode } from '../exit-code.js';
|
|
10
10
|
import { Manifest } from '../manifest.js';
|
|
11
11
|
import { serveMcp } from '../mcp.js';
|
|
12
|
-
import { schemaOf } from '../schema.js';
|
|
12
|
+
import { machineJson, schemaOf } from '../schema.js';
|
|
13
13
|
import { tokenizeArgString } from '../yargs-parser.js';
|
|
14
14
|
import { projectManifest, render } from './burgee.js';
|
|
15
15
|
import { command as Command, isCommandBuilderCallback } from './command.js';
|
|
@@ -1315,7 +1315,12 @@ export class YargsInstance {
|
|
|
1315
1315
|
});
|
|
1316
1316
|
}
|
|
1317
1317
|
if (head.includes('--schema') && !this.#declares('schema')) {
|
|
1318
|
-
|
|
1318
|
+
// R1, through the same seam the engine and the commander façade use. Hand-rolling
|
|
1319
|
+
// `JSON.stringify(…, null, 2)` here made this façade the one front-end that could not
|
|
1320
|
+
// see `--format=json-pretty`, and emitted a different document from the other two for
|
|
1321
|
+
// the same CLI. `--schema` is burgee's surface, not yargs', so it answers to burgee's
|
|
1322
|
+
// byte discipline.
|
|
1323
|
+
this.#logger.log(machineJson(schemaOf(this.manifest), head));
|
|
1319
1324
|
this.exit(0);
|
|
1320
1325
|
return true;
|
|
1321
1326
|
}
|
package/dist/yargs/shim.js
CHANGED
|
@@ -9,6 +9,7 @@ import { createRequire } from 'node:module';
|
|
|
9
9
|
import { basename, dirname, extname, join, relative, resolve } from 'node:path';
|
|
10
10
|
import { fileURLToPath } from 'node:url';
|
|
11
11
|
import { inspect } from 'node:util';
|
|
12
|
+
import { host } from '../runtime.js';
|
|
12
13
|
import { Parser } from '../yargs-parser.js';
|
|
13
14
|
import { cliui, stringWidth } from './cliui.js';
|
|
14
15
|
import { getProcessArgvBin } from './utils.js';
|
|
@@ -71,24 +72,30 @@ export const shim = {
|
|
|
71
72
|
assert: { notStrictEqual, strictEqual },
|
|
72
73
|
cliui,
|
|
73
74
|
findUp,
|
|
74
|
-
getEnv: (key) =>
|
|
75
|
+
getEnv: (key) => host.env[key],
|
|
75
76
|
inspect,
|
|
76
77
|
getProcessArgvBin,
|
|
77
|
-
mainFilename: mainFilename ||
|
|
78
|
+
mainFilename: mainFilename || host.cwd(),
|
|
78
79
|
Parser,
|
|
79
80
|
path: { basename, dirname, extname, relative, resolve, join },
|
|
80
81
|
process: {
|
|
81
|
-
argv: () =>
|
|
82
|
-
cwd:
|
|
83
|
-
emitWarning: (warning, type) =>
|
|
84
|
-
|
|
82
|
+
argv: () => host.argv,
|
|
83
|
+
cwd: () => host.cwd(),
|
|
84
|
+
emitWarning: (warning, type) => {
|
|
85
|
+
host.emitWarning(warning, type);
|
|
86
|
+
},
|
|
87
|
+
execPath: () => host.execPath,
|
|
85
88
|
exit: (code) => {
|
|
86
|
-
|
|
89
|
+
host.exit(code);
|
|
90
|
+
},
|
|
91
|
+
nextTick: (fn, ...args) => {
|
|
92
|
+
host.nextTick(fn, ...args);
|
|
87
93
|
},
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
94
|
+
// Captured, as it was before the seam: `stdColumns` is a value in `PlatformShim`, not
|
|
95
|
+
// a thunk, so yargs reads whatever this object was built with. Unchanged on purpose.
|
|
96
|
+
stdColumns: typeof host.stdout.columns !== 'undefined' ? host.stdout.columns : null,
|
|
97
|
+
stdin: () => host.stdin,
|
|
98
|
+
stdout: () => host.stdout,
|
|
92
99
|
},
|
|
93
100
|
readFileSync,
|
|
94
101
|
readdirSync,
|
package/dist/yargs/utils.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import { readFileSync } from 'node:fs';
|
|
8
8
|
import { createRequire } from 'node:module';
|
|
9
9
|
import { dirname, resolve } from 'node:path';
|
|
10
|
+
import { host } from '../runtime.js';
|
|
10
11
|
export class YError extends Error {
|
|
11
12
|
constructor(msg) {
|
|
12
13
|
super(msg || 'yargs error');
|
|
@@ -139,7 +140,7 @@ export function maybeAsyncResult(getResult, resultHandler, errorHandler = (err)
|
|
|
139
140
|
export function setBlocking(blocking) {
|
|
140
141
|
if (typeof process === 'undefined')
|
|
141
142
|
return;
|
|
142
|
-
[
|
|
143
|
+
[host.stdout, host.stderr].forEach((_stream) => {
|
|
143
144
|
const stream = _stream;
|
|
144
145
|
if (stream._handle && stream.isTTY && typeof stream._handle.setBlocking === 'function')
|
|
145
146
|
stream._handle.setBlocking(blocking);
|
|
@@ -151,16 +152,16 @@ function getProcessArgvBinIndex() {
|
|
|
151
152
|
return 1;
|
|
152
153
|
}
|
|
153
154
|
function isBundledElectronApp() {
|
|
154
|
-
return isElectronApp() && !
|
|
155
|
+
return isElectronApp() && !host.defaultApp;
|
|
155
156
|
}
|
|
156
157
|
function isElectronApp() {
|
|
157
|
-
return !!
|
|
158
|
+
return !!host.versions['electron'];
|
|
158
159
|
}
|
|
159
160
|
export function hideBin(argv) {
|
|
160
161
|
return argv.slice(getProcessArgvBinIndex() + 1);
|
|
161
162
|
}
|
|
162
163
|
export function getProcessArgvBin() {
|
|
163
|
-
return
|
|
164
|
+
return host.argv[getProcessArgvBinIndex()];
|
|
164
165
|
}
|
|
165
166
|
const nodeRequire = createRequire(import.meta.url);
|
|
166
167
|
let previouslyVisitedConfigs = [];
|
package/dist/yargs-parser.js
CHANGED
|
@@ -2,6 +2,7 @@ import { readFileSync } from 'node:fs';
|
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
3
|
import { normalize, resolve } from 'node:path';
|
|
4
4
|
import { format } from 'node:util';
|
|
5
|
+
import { host } from './runtime.js';
|
|
5
6
|
export function camelCase(str) {
|
|
6
7
|
const isCamelCase = str !== str.toLowerCase() && str !== str.toUpperCase();
|
|
7
8
|
if (!isCamelCase)
|
|
@@ -902,11 +903,10 @@ function sanitizeKey(key) {
|
|
|
902
903
|
function stripQuotes(val) {
|
|
903
904
|
return typeof val === 'string' && (val[0] === "'" || val[0] === '"') && val.at(-1) === val[0] ? val.substring(1, val.length - 1) : val;
|
|
904
905
|
}
|
|
905
|
-
const env = process.env;
|
|
906
906
|
const nodeRequire = createRequire(import.meta.url);
|
|
907
907
|
const parser = new YargsParser({
|
|
908
|
-
cwd:
|
|
909
|
-
env: () => env,
|
|
908
|
+
cwd: () => host.cwd(),
|
|
909
|
+
env: () => host.env,
|
|
910
910
|
format,
|
|
911
911
|
normalize,
|
|
912
912
|
resolve,
|