@rosh100yx/outlier 0.4.1 → 0.4.4
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 +16 -15
- package/bin/outlier.js +2344 -0
- package/bin/postinstall.js +17 -0
- package/package.json +7 -5
- package/src/cli.ts +43 -21
- package/bin/outlier +0 -0
package/bin/outlier.js
ADDED
|
@@ -0,0 +1,2344 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
|
+
var __defProp = Object.defineProperty;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
function __accessProp(key) {
|
|
9
|
+
return this[key];
|
|
10
|
+
}
|
|
11
|
+
var __toESMCache_node;
|
|
12
|
+
var __toESMCache_esm;
|
|
13
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
14
|
+
var canCache = mod != null && typeof mod === "object";
|
|
15
|
+
if (canCache) {
|
|
16
|
+
var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
|
|
17
|
+
var cached = cache.get(mod);
|
|
18
|
+
if (cached)
|
|
19
|
+
return cached;
|
|
20
|
+
}
|
|
21
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
22
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
23
|
+
for (let key of __getOwnPropNames(mod))
|
|
24
|
+
if (!__hasOwnProp.call(to, key))
|
|
25
|
+
__defProp(to, key, {
|
|
26
|
+
get: __accessProp.bind(mod, key),
|
|
27
|
+
enumerable: true
|
|
28
|
+
});
|
|
29
|
+
if (canCache)
|
|
30
|
+
cache.set(mod, to);
|
|
31
|
+
return to;
|
|
32
|
+
};
|
|
33
|
+
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
34
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
35
|
+
|
|
36
|
+
// node_modules/sisteransi/src/index.js
|
|
37
|
+
var require_src = __commonJS((exports, module) => {
|
|
38
|
+
var ESC2 = "\x1B";
|
|
39
|
+
var CSI2 = `${ESC2}[`;
|
|
40
|
+
var beep = "\x07";
|
|
41
|
+
var cursor = {
|
|
42
|
+
to(x, y) {
|
|
43
|
+
if (!y)
|
|
44
|
+
return `${CSI2}${x + 1}G`;
|
|
45
|
+
return `${CSI2}${y + 1};${x + 1}H`;
|
|
46
|
+
},
|
|
47
|
+
move(x, y) {
|
|
48
|
+
let ret = "";
|
|
49
|
+
if (x < 0)
|
|
50
|
+
ret += `${CSI2}${-x}D`;
|
|
51
|
+
else if (x > 0)
|
|
52
|
+
ret += `${CSI2}${x}C`;
|
|
53
|
+
if (y < 0)
|
|
54
|
+
ret += `${CSI2}${-y}A`;
|
|
55
|
+
else if (y > 0)
|
|
56
|
+
ret += `${CSI2}${y}B`;
|
|
57
|
+
return ret;
|
|
58
|
+
},
|
|
59
|
+
up: (count = 1) => `${CSI2}${count}A`,
|
|
60
|
+
down: (count = 1) => `${CSI2}${count}B`,
|
|
61
|
+
forward: (count = 1) => `${CSI2}${count}C`,
|
|
62
|
+
backward: (count = 1) => `${CSI2}${count}D`,
|
|
63
|
+
nextLine: (count = 1) => `${CSI2}E`.repeat(count),
|
|
64
|
+
prevLine: (count = 1) => `${CSI2}F`.repeat(count),
|
|
65
|
+
left: `${CSI2}G`,
|
|
66
|
+
hide: `${CSI2}?25l`,
|
|
67
|
+
show: `${CSI2}?25h`,
|
|
68
|
+
save: `${ESC2}7`,
|
|
69
|
+
restore: `${ESC2}8`
|
|
70
|
+
};
|
|
71
|
+
var scroll = {
|
|
72
|
+
up: (count = 1) => `${CSI2}S`.repeat(count),
|
|
73
|
+
down: (count = 1) => `${CSI2}T`.repeat(count)
|
|
74
|
+
};
|
|
75
|
+
var erase = {
|
|
76
|
+
screen: `${CSI2}2J`,
|
|
77
|
+
up: (count = 1) => `${CSI2}1J`.repeat(count),
|
|
78
|
+
down: (count = 1) => `${CSI2}J`.repeat(count),
|
|
79
|
+
line: `${CSI2}2K`,
|
|
80
|
+
lineEnd: `${CSI2}K`,
|
|
81
|
+
lineStart: `${CSI2}1K`,
|
|
82
|
+
lines(count) {
|
|
83
|
+
let clear = "";
|
|
84
|
+
for (let i = 0;i < count; i++)
|
|
85
|
+
clear += this.line + (i < count - 1 ? cursor.up() : "");
|
|
86
|
+
if (count)
|
|
87
|
+
clear += cursor.left;
|
|
88
|
+
return clear;
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
module.exports = { cursor, scroll, erase, beep };
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// node_modules/picocolors/picocolors.js
|
|
95
|
+
var require_picocolors = __commonJS((exports, module) => {
|
|
96
|
+
var p2 = process || {};
|
|
97
|
+
var argv = p2.argv || [];
|
|
98
|
+
var env = p2.env || {};
|
|
99
|
+
var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p2.platform === "win32" || (p2.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
|
|
100
|
+
var formatter = (open, close, replace = open) => (input) => {
|
|
101
|
+
let string = "" + input, index = string.indexOf(close, open.length);
|
|
102
|
+
return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
|
|
103
|
+
};
|
|
104
|
+
var replaceClose = (string, close, replace, index) => {
|
|
105
|
+
let result = "", cursor3 = 0;
|
|
106
|
+
do {
|
|
107
|
+
result += string.substring(cursor3, index) + replace;
|
|
108
|
+
cursor3 = index + close.length;
|
|
109
|
+
index = string.indexOf(close, cursor3);
|
|
110
|
+
} while (~index);
|
|
111
|
+
return result + string.substring(cursor3);
|
|
112
|
+
};
|
|
113
|
+
var createColors = (enabled = isColorSupported) => {
|
|
114
|
+
let f2 = enabled ? formatter : () => String;
|
|
115
|
+
return {
|
|
116
|
+
isColorSupported: enabled,
|
|
117
|
+
reset: f2("\x1B[0m", "\x1B[0m"),
|
|
118
|
+
bold: f2("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
|
|
119
|
+
dim: f2("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
|
|
120
|
+
italic: f2("\x1B[3m", "\x1B[23m"),
|
|
121
|
+
underline: f2("\x1B[4m", "\x1B[24m"),
|
|
122
|
+
inverse: f2("\x1B[7m", "\x1B[27m"),
|
|
123
|
+
hidden: f2("\x1B[8m", "\x1B[28m"),
|
|
124
|
+
strikethrough: f2("\x1B[9m", "\x1B[29m"),
|
|
125
|
+
black: f2("\x1B[30m", "\x1B[39m"),
|
|
126
|
+
red: f2("\x1B[31m", "\x1B[39m"),
|
|
127
|
+
green: f2("\x1B[32m", "\x1B[39m"),
|
|
128
|
+
yellow: f2("\x1B[33m", "\x1B[39m"),
|
|
129
|
+
blue: f2("\x1B[34m", "\x1B[39m"),
|
|
130
|
+
magenta: f2("\x1B[35m", "\x1B[39m"),
|
|
131
|
+
cyan: f2("\x1B[36m", "\x1B[39m"),
|
|
132
|
+
white: f2("\x1B[37m", "\x1B[39m"),
|
|
133
|
+
gray: f2("\x1B[90m", "\x1B[39m"),
|
|
134
|
+
bgBlack: f2("\x1B[40m", "\x1B[49m"),
|
|
135
|
+
bgRed: f2("\x1B[41m", "\x1B[49m"),
|
|
136
|
+
bgGreen: f2("\x1B[42m", "\x1B[49m"),
|
|
137
|
+
bgYellow: f2("\x1B[43m", "\x1B[49m"),
|
|
138
|
+
bgBlue: f2("\x1B[44m", "\x1B[49m"),
|
|
139
|
+
bgMagenta: f2("\x1B[45m", "\x1B[49m"),
|
|
140
|
+
bgCyan: f2("\x1B[46m", "\x1B[49m"),
|
|
141
|
+
bgWhite: f2("\x1B[47m", "\x1B[49m"),
|
|
142
|
+
blackBright: f2("\x1B[90m", "\x1B[39m"),
|
|
143
|
+
redBright: f2("\x1B[91m", "\x1B[39m"),
|
|
144
|
+
greenBright: f2("\x1B[92m", "\x1B[39m"),
|
|
145
|
+
yellowBright: f2("\x1B[93m", "\x1B[39m"),
|
|
146
|
+
blueBright: f2("\x1B[94m", "\x1B[39m"),
|
|
147
|
+
magentaBright: f2("\x1B[95m", "\x1B[39m"),
|
|
148
|
+
cyanBright: f2("\x1B[96m", "\x1B[39m"),
|
|
149
|
+
whiteBright: f2("\x1B[97m", "\x1B[39m"),
|
|
150
|
+
bgBlackBright: f2("\x1B[100m", "\x1B[49m"),
|
|
151
|
+
bgRedBright: f2("\x1B[101m", "\x1B[49m"),
|
|
152
|
+
bgGreenBright: f2("\x1B[102m", "\x1B[49m"),
|
|
153
|
+
bgYellowBright: f2("\x1B[103m", "\x1B[49m"),
|
|
154
|
+
bgBlueBright: f2("\x1B[104m", "\x1B[49m"),
|
|
155
|
+
bgMagentaBright: f2("\x1B[105m", "\x1B[49m"),
|
|
156
|
+
bgCyanBright: f2("\x1B[106m", "\x1B[49m"),
|
|
157
|
+
bgWhiteBright: f2("\x1B[107m", "\x1B[49m")
|
|
158
|
+
};
|
|
159
|
+
};
|
|
160
|
+
module.exports = createColors();
|
|
161
|
+
module.exports.createColors = createColors;
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
// node_modules/@clack/core/dist/index.mjs
|
|
165
|
+
import { styleText } from "node:util";
|
|
166
|
+
import { stdout, stdin } from "node:process";
|
|
167
|
+
import * as l from "node:readline";
|
|
168
|
+
import l__default from "node:readline";
|
|
169
|
+
|
|
170
|
+
// node_modules/fast-string-truncated-width/dist/utils.js
|
|
171
|
+
var getCodePointsLength = (() => {
|
|
172
|
+
const SURROGATE_PAIR_RE = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
|
|
173
|
+
return (input) => {
|
|
174
|
+
let surrogatePairsNr = 0;
|
|
175
|
+
SURROGATE_PAIR_RE.lastIndex = 0;
|
|
176
|
+
while (SURROGATE_PAIR_RE.test(input)) {
|
|
177
|
+
surrogatePairsNr += 1;
|
|
178
|
+
}
|
|
179
|
+
return input.length - surrogatePairsNr;
|
|
180
|
+
};
|
|
181
|
+
})();
|
|
182
|
+
var isFullWidth = (x) => {
|
|
183
|
+
return x === 12288 || x >= 65281 && x <= 65376 || x >= 65504 && x <= 65510;
|
|
184
|
+
};
|
|
185
|
+
var isWideNotCJKTNotEmoji = (x) => {
|
|
186
|
+
return x === 8987 || x === 9001 || x >= 12272 && x <= 12287 || x >= 12289 && x <= 12350 || x >= 12441 && x <= 12543 || x >= 12549 && x <= 12591 || x >= 12593 && x <= 12686 || x >= 12688 && x <= 12771 || x >= 12783 && x <= 12830 || x >= 12832 && x <= 12871 || x >= 12880 && x <= 19903 || x >= 65040 && x <= 65049 || x >= 65072 && x <= 65106 || x >= 65108 && x <= 65126 || x >= 65128 && x <= 65131 || x >= 127488 && x <= 127490 || x >= 127504 && x <= 127547 || x >= 127552 && x <= 127560 || x >= 131072 && x <= 196605 || x >= 196608 && x <= 262141;
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
// node_modules/fast-string-truncated-width/dist/index.js
|
|
190
|
+
var ANSI_RE = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]|\u001b\]8;[^;]*;.*?(?:\u0007|\u001b\u005c)/y;
|
|
191
|
+
var CONTROL_RE = /[\x00-\x08\x0A-\x1F\x7F-\x9F]{1,1000}/y;
|
|
192
|
+
var CJKT_WIDE_RE = /(?:(?![\uFF61-\uFF9F\uFF00-\uFFEF])[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}\p{Script=Tangut}]){1,1000}/yu;
|
|
193
|
+
var TAB_RE = /\t{1,1000}/y;
|
|
194
|
+
var EMOJI_RE = /[\u{1F1E6}-\u{1F1FF}]{2}|\u{1F3F4}[\u{E0061}-\u{E007A}]{2}[\u{E0030}-\u{E0039}\u{E0061}-\u{E007A}]{1,3}\u{E007F}|(?:\p{Emoji}\uFE0F\u20E3?|\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation})(?:\u200D(?:\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation}|\p{Emoji}\uFE0F\u20E3?))*/yu;
|
|
195
|
+
var LATIN_RE = /(?:[\x20-\x7E\xA0-\xFF](?!\uFE0F)){1,1000}/y;
|
|
196
|
+
var MODIFIER_RE = /\p{M}+/gu;
|
|
197
|
+
var NO_TRUNCATION = { limit: Infinity, ellipsis: "" };
|
|
198
|
+
var getStringTruncatedWidth = (input, truncationOptions = {}, widthOptions = {}) => {
|
|
199
|
+
const LIMIT = truncationOptions.limit ?? Infinity;
|
|
200
|
+
const ELLIPSIS = truncationOptions.ellipsis ?? "";
|
|
201
|
+
const ELLIPSIS_WIDTH = truncationOptions?.ellipsisWidth ?? (ELLIPSIS ? getStringTruncatedWidth(ELLIPSIS, NO_TRUNCATION, widthOptions).width : 0);
|
|
202
|
+
const ANSI_WIDTH = 0;
|
|
203
|
+
const CONTROL_WIDTH = widthOptions.controlWidth ?? 0;
|
|
204
|
+
const TAB_WIDTH = widthOptions.tabWidth ?? 8;
|
|
205
|
+
const EMOJI_WIDTH = widthOptions.emojiWidth ?? 2;
|
|
206
|
+
const FULL_WIDTH_WIDTH = 2;
|
|
207
|
+
const REGULAR_WIDTH = widthOptions.regularWidth ?? 1;
|
|
208
|
+
const WIDE_WIDTH = widthOptions.wideWidth ?? FULL_WIDTH_WIDTH;
|
|
209
|
+
const PARSE_BLOCKS = [
|
|
210
|
+
[LATIN_RE, REGULAR_WIDTH],
|
|
211
|
+
[ANSI_RE, ANSI_WIDTH],
|
|
212
|
+
[CONTROL_RE, CONTROL_WIDTH],
|
|
213
|
+
[TAB_RE, TAB_WIDTH],
|
|
214
|
+
[EMOJI_RE, EMOJI_WIDTH],
|
|
215
|
+
[CJKT_WIDE_RE, WIDE_WIDTH]
|
|
216
|
+
];
|
|
217
|
+
let indexPrev = 0;
|
|
218
|
+
let index = 0;
|
|
219
|
+
let length = input.length;
|
|
220
|
+
let lengthExtra = 0;
|
|
221
|
+
let truncationEnabled = false;
|
|
222
|
+
let truncationIndex = length;
|
|
223
|
+
let truncationLimit = Math.max(0, LIMIT - ELLIPSIS_WIDTH);
|
|
224
|
+
let unmatchedStart = 0;
|
|
225
|
+
let unmatchedEnd = 0;
|
|
226
|
+
let width = 0;
|
|
227
|
+
let widthExtra = 0;
|
|
228
|
+
outer:
|
|
229
|
+
while (true) {
|
|
230
|
+
if (unmatchedEnd > unmatchedStart || index >= length && index > indexPrev) {
|
|
231
|
+
const unmatched = input.slice(unmatchedStart, unmatchedEnd) || input.slice(indexPrev, index);
|
|
232
|
+
lengthExtra = 0;
|
|
233
|
+
for (const char of unmatched.replaceAll(MODIFIER_RE, "")) {
|
|
234
|
+
const codePoint = char.codePointAt(0) || 0;
|
|
235
|
+
if (isFullWidth(codePoint)) {
|
|
236
|
+
widthExtra = FULL_WIDTH_WIDTH;
|
|
237
|
+
} else if (isWideNotCJKTNotEmoji(codePoint)) {
|
|
238
|
+
widthExtra = WIDE_WIDTH;
|
|
239
|
+
} else {
|
|
240
|
+
widthExtra = REGULAR_WIDTH;
|
|
241
|
+
}
|
|
242
|
+
if (width + widthExtra > truncationLimit) {
|
|
243
|
+
truncationIndex = Math.min(truncationIndex, Math.max(unmatchedStart, indexPrev) + lengthExtra);
|
|
244
|
+
}
|
|
245
|
+
if (width + widthExtra > LIMIT) {
|
|
246
|
+
truncationEnabled = true;
|
|
247
|
+
break outer;
|
|
248
|
+
}
|
|
249
|
+
lengthExtra += char.length;
|
|
250
|
+
width += widthExtra;
|
|
251
|
+
}
|
|
252
|
+
unmatchedStart = unmatchedEnd = 0;
|
|
253
|
+
}
|
|
254
|
+
if (index >= length) {
|
|
255
|
+
break outer;
|
|
256
|
+
}
|
|
257
|
+
for (let i = 0, l = PARSE_BLOCKS.length;i < l; i++) {
|
|
258
|
+
const [BLOCK_RE, BLOCK_WIDTH] = PARSE_BLOCKS[i];
|
|
259
|
+
BLOCK_RE.lastIndex = index;
|
|
260
|
+
if (BLOCK_RE.test(input)) {
|
|
261
|
+
lengthExtra = BLOCK_RE === CJKT_WIDE_RE ? getCodePointsLength(input.slice(index, BLOCK_RE.lastIndex)) : BLOCK_RE === EMOJI_RE ? 1 : BLOCK_RE.lastIndex - index;
|
|
262
|
+
widthExtra = lengthExtra * BLOCK_WIDTH;
|
|
263
|
+
if (width + widthExtra > truncationLimit) {
|
|
264
|
+
truncationIndex = Math.min(truncationIndex, index + Math.floor((truncationLimit - width) / BLOCK_WIDTH));
|
|
265
|
+
}
|
|
266
|
+
if (width + widthExtra > LIMIT) {
|
|
267
|
+
truncationEnabled = true;
|
|
268
|
+
break outer;
|
|
269
|
+
}
|
|
270
|
+
width += widthExtra;
|
|
271
|
+
unmatchedStart = indexPrev;
|
|
272
|
+
unmatchedEnd = index;
|
|
273
|
+
index = indexPrev = BLOCK_RE.lastIndex;
|
|
274
|
+
continue outer;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
index += 1;
|
|
278
|
+
}
|
|
279
|
+
return {
|
|
280
|
+
width: truncationEnabled ? truncationLimit : width,
|
|
281
|
+
index: truncationEnabled ? truncationIndex : length,
|
|
282
|
+
truncated: truncationEnabled,
|
|
283
|
+
ellipsed: truncationEnabled && LIMIT >= ELLIPSIS_WIDTH
|
|
284
|
+
};
|
|
285
|
+
};
|
|
286
|
+
var dist_default = getStringTruncatedWidth;
|
|
287
|
+
|
|
288
|
+
// node_modules/fast-string-width/dist/index.js
|
|
289
|
+
var NO_TRUNCATION2 = {
|
|
290
|
+
limit: Infinity,
|
|
291
|
+
ellipsis: "",
|
|
292
|
+
ellipsisWidth: 0
|
|
293
|
+
};
|
|
294
|
+
var fastStringWidth = (input, options = {}) => {
|
|
295
|
+
return dist_default(input, NO_TRUNCATION2, options).width;
|
|
296
|
+
};
|
|
297
|
+
var dist_default2 = fastStringWidth;
|
|
298
|
+
|
|
299
|
+
// node_modules/fast-wrap-ansi/lib/main.js
|
|
300
|
+
var ESC = "\x1B";
|
|
301
|
+
var CSI = "";
|
|
302
|
+
var END_CODE = 39;
|
|
303
|
+
var ANSI_ESCAPE_BELL = "\x07";
|
|
304
|
+
var ANSI_CSI = "[";
|
|
305
|
+
var ANSI_OSC = "]";
|
|
306
|
+
var ANSI_SGR_TERMINATOR = "m";
|
|
307
|
+
var ANSI_ESCAPE_LINK = `${ANSI_OSC}8;;`;
|
|
308
|
+
var GROUP_REGEX = new RegExp(`(?:\\${ANSI_CSI}(?<code>\\d+)m|\\${ANSI_ESCAPE_LINK}(?<uri>.*)${ANSI_ESCAPE_BELL})`, "y");
|
|
309
|
+
var getClosingCode = (openingCode) => {
|
|
310
|
+
if (openingCode >= 30 && openingCode <= 37)
|
|
311
|
+
return 39;
|
|
312
|
+
if (openingCode >= 90 && openingCode <= 97)
|
|
313
|
+
return 39;
|
|
314
|
+
if (openingCode >= 40 && openingCode <= 47)
|
|
315
|
+
return 49;
|
|
316
|
+
if (openingCode >= 100 && openingCode <= 107)
|
|
317
|
+
return 49;
|
|
318
|
+
if (openingCode === 1 || openingCode === 2)
|
|
319
|
+
return 22;
|
|
320
|
+
if (openingCode === 3)
|
|
321
|
+
return 23;
|
|
322
|
+
if (openingCode === 4)
|
|
323
|
+
return 24;
|
|
324
|
+
if (openingCode === 7)
|
|
325
|
+
return 27;
|
|
326
|
+
if (openingCode === 8)
|
|
327
|
+
return 28;
|
|
328
|
+
if (openingCode === 9)
|
|
329
|
+
return 29;
|
|
330
|
+
if (openingCode === 0)
|
|
331
|
+
return 0;
|
|
332
|
+
return;
|
|
333
|
+
};
|
|
334
|
+
var wrapAnsiCode = (code) => `${ESC}${ANSI_CSI}${code}${ANSI_SGR_TERMINATOR}`;
|
|
335
|
+
var wrapAnsiHyperlink = (url) => `${ESC}${ANSI_ESCAPE_LINK}${url}${ANSI_ESCAPE_BELL}`;
|
|
336
|
+
var wrapWord = (rows, word, columns) => {
|
|
337
|
+
const characters = word[Symbol.iterator]();
|
|
338
|
+
let isInsideEscape = false;
|
|
339
|
+
let isInsideLinkEscape = false;
|
|
340
|
+
let lastRow = rows.at(-1);
|
|
341
|
+
let visible = lastRow === undefined ? 0 : dist_default2(lastRow);
|
|
342
|
+
let currentCharacter = characters.next();
|
|
343
|
+
let nextCharacter = characters.next();
|
|
344
|
+
let rawCharacterIndex = 0;
|
|
345
|
+
while (!currentCharacter.done) {
|
|
346
|
+
const character = currentCharacter.value;
|
|
347
|
+
const characterLength = dist_default2(character);
|
|
348
|
+
if (visible + characterLength <= columns) {
|
|
349
|
+
rows[rows.length - 1] += character;
|
|
350
|
+
} else {
|
|
351
|
+
rows.push(character);
|
|
352
|
+
visible = 0;
|
|
353
|
+
}
|
|
354
|
+
if (character === ESC || character === CSI) {
|
|
355
|
+
isInsideEscape = true;
|
|
356
|
+
isInsideLinkEscape = word.startsWith(ANSI_ESCAPE_LINK, rawCharacterIndex + 1);
|
|
357
|
+
}
|
|
358
|
+
if (isInsideEscape) {
|
|
359
|
+
if (isInsideLinkEscape) {
|
|
360
|
+
if (character === ANSI_ESCAPE_BELL) {
|
|
361
|
+
isInsideEscape = false;
|
|
362
|
+
isInsideLinkEscape = false;
|
|
363
|
+
}
|
|
364
|
+
} else if (character === ANSI_SGR_TERMINATOR) {
|
|
365
|
+
isInsideEscape = false;
|
|
366
|
+
}
|
|
367
|
+
} else {
|
|
368
|
+
visible += characterLength;
|
|
369
|
+
if (visible === columns && !nextCharacter.done) {
|
|
370
|
+
rows.push("");
|
|
371
|
+
visible = 0;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
currentCharacter = nextCharacter;
|
|
375
|
+
nextCharacter = characters.next();
|
|
376
|
+
rawCharacterIndex += character.length;
|
|
377
|
+
}
|
|
378
|
+
lastRow = rows.at(-1);
|
|
379
|
+
if (!visible && lastRow !== undefined && lastRow.length && rows.length > 1) {
|
|
380
|
+
rows[rows.length - 2] += rows.pop();
|
|
381
|
+
}
|
|
382
|
+
};
|
|
383
|
+
var stringVisibleTrimSpacesRight = (string) => {
|
|
384
|
+
const words = string.split(" ");
|
|
385
|
+
let last = words.length;
|
|
386
|
+
while (last) {
|
|
387
|
+
if (dist_default2(words[last - 1])) {
|
|
388
|
+
break;
|
|
389
|
+
}
|
|
390
|
+
last--;
|
|
391
|
+
}
|
|
392
|
+
if (last === words.length) {
|
|
393
|
+
return string;
|
|
394
|
+
}
|
|
395
|
+
return words.slice(0, last).join(" ") + words.slice(last).join("");
|
|
396
|
+
};
|
|
397
|
+
var exec = (string, columns, options = {}) => {
|
|
398
|
+
if (options.trim !== false && string.trim() === "") {
|
|
399
|
+
return "";
|
|
400
|
+
}
|
|
401
|
+
let returnValue = "";
|
|
402
|
+
let escapeCode;
|
|
403
|
+
let escapeUrl;
|
|
404
|
+
const words = string.split(" ");
|
|
405
|
+
let rows = [""];
|
|
406
|
+
let rowLength = 0;
|
|
407
|
+
for (let index = 0;index < words.length; index++) {
|
|
408
|
+
const word = words[index];
|
|
409
|
+
if (options.trim !== false) {
|
|
410
|
+
const row = rows.at(-1) ?? "";
|
|
411
|
+
const trimmed = row.trimStart();
|
|
412
|
+
if (row.length !== trimmed.length) {
|
|
413
|
+
rows[rows.length - 1] = trimmed;
|
|
414
|
+
rowLength = dist_default2(trimmed);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
if (index !== 0) {
|
|
418
|
+
if (rowLength >= columns && (options.wordWrap === false || options.trim === false)) {
|
|
419
|
+
rows.push("");
|
|
420
|
+
rowLength = 0;
|
|
421
|
+
}
|
|
422
|
+
if (rowLength || options.trim === false) {
|
|
423
|
+
rows[rows.length - 1] += " ";
|
|
424
|
+
rowLength++;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
const wordLength = dist_default2(word);
|
|
428
|
+
if (options.hard && wordLength > columns) {
|
|
429
|
+
const remainingColumns = columns - rowLength;
|
|
430
|
+
const breaksStartingThisLine = 1 + Math.floor((wordLength - remainingColumns - 1) / columns);
|
|
431
|
+
const breaksStartingNextLine = Math.floor((wordLength - 1) / columns);
|
|
432
|
+
if (breaksStartingNextLine < breaksStartingThisLine) {
|
|
433
|
+
rows.push("");
|
|
434
|
+
}
|
|
435
|
+
wrapWord(rows, word, columns);
|
|
436
|
+
rowLength = dist_default2(rows.at(-1) ?? "");
|
|
437
|
+
continue;
|
|
438
|
+
}
|
|
439
|
+
if (rowLength + wordLength > columns && rowLength && wordLength) {
|
|
440
|
+
if (options.wordWrap === false && rowLength < columns) {
|
|
441
|
+
wrapWord(rows, word, columns);
|
|
442
|
+
rowLength = dist_default2(rows.at(-1) ?? "");
|
|
443
|
+
continue;
|
|
444
|
+
}
|
|
445
|
+
rows.push("");
|
|
446
|
+
rowLength = 0;
|
|
447
|
+
}
|
|
448
|
+
if (rowLength + wordLength > columns && options.wordWrap === false) {
|
|
449
|
+
wrapWord(rows, word, columns);
|
|
450
|
+
rowLength = dist_default2(rows.at(-1) ?? "");
|
|
451
|
+
continue;
|
|
452
|
+
}
|
|
453
|
+
rows[rows.length - 1] += word;
|
|
454
|
+
rowLength += wordLength;
|
|
455
|
+
}
|
|
456
|
+
if (options.trim !== false) {
|
|
457
|
+
rows = rows.map((row) => stringVisibleTrimSpacesRight(row));
|
|
458
|
+
}
|
|
459
|
+
const preString = rows.join(`
|
|
460
|
+
`);
|
|
461
|
+
let inSurrogate = false;
|
|
462
|
+
for (let i = 0;i < preString.length; i++) {
|
|
463
|
+
const character = preString[i];
|
|
464
|
+
returnValue += character;
|
|
465
|
+
if (!inSurrogate) {
|
|
466
|
+
inSurrogate = character >= "\uD800" && character <= "\uDBFF";
|
|
467
|
+
if (inSurrogate) {
|
|
468
|
+
continue;
|
|
469
|
+
}
|
|
470
|
+
} else {
|
|
471
|
+
inSurrogate = false;
|
|
472
|
+
}
|
|
473
|
+
if (character === ESC || character === CSI) {
|
|
474
|
+
GROUP_REGEX.lastIndex = i + 1;
|
|
475
|
+
const groupsResult = GROUP_REGEX.exec(preString);
|
|
476
|
+
const groups = groupsResult?.groups;
|
|
477
|
+
if (groups?.code !== undefined) {
|
|
478
|
+
const code = Number.parseFloat(groups.code);
|
|
479
|
+
escapeCode = code === END_CODE ? undefined : code;
|
|
480
|
+
} else if (groups?.uri !== undefined) {
|
|
481
|
+
escapeUrl = groups.uri.length === 0 ? undefined : groups.uri;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
if (preString[i + 1] === `
|
|
485
|
+
`) {
|
|
486
|
+
if (escapeUrl) {
|
|
487
|
+
returnValue += wrapAnsiHyperlink("");
|
|
488
|
+
}
|
|
489
|
+
const closingCode = escapeCode ? getClosingCode(escapeCode) : undefined;
|
|
490
|
+
if (escapeCode && closingCode) {
|
|
491
|
+
returnValue += wrapAnsiCode(closingCode);
|
|
492
|
+
}
|
|
493
|
+
} else if (character === `
|
|
494
|
+
`) {
|
|
495
|
+
if (escapeCode && getClosingCode(escapeCode)) {
|
|
496
|
+
returnValue += wrapAnsiCode(escapeCode);
|
|
497
|
+
}
|
|
498
|
+
if (escapeUrl) {
|
|
499
|
+
returnValue += wrapAnsiHyperlink(escapeUrl);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
return returnValue;
|
|
504
|
+
};
|
|
505
|
+
var CRLF_OR_LF = /\r?\n/;
|
|
506
|
+
function wrapAnsi(string, columns, options) {
|
|
507
|
+
return String(string).normalize().split(CRLF_OR_LF).map((line) => exec(line, columns, options)).join(`
|
|
508
|
+
`);
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
// node_modules/@clack/core/dist/index.mjs
|
|
512
|
+
var import_sisteransi = __toESM(require_src(), 1);
|
|
513
|
+
import { ReadStream } from "node:tty";
|
|
514
|
+
function findCursor(s, o, l2) {
|
|
515
|
+
if (!l2.some((r) => !r.disabled))
|
|
516
|
+
return s;
|
|
517
|
+
const t = s + o, n = Math.max(l2.length - 1, 0), e = t < 0 ? n : t > n ? 0 : t;
|
|
518
|
+
return l2[e].disabled ? findCursor(e, o < 0 ? -1 : 1, l2) : e;
|
|
519
|
+
}
|
|
520
|
+
function findTextCursor(s, o, l2, i) {
|
|
521
|
+
const t = i.split(`
|
|
522
|
+
`);
|
|
523
|
+
let n = 0, e = s;
|
|
524
|
+
for (const r of t) {
|
|
525
|
+
if (e <= r.length)
|
|
526
|
+
break;
|
|
527
|
+
e -= r.length + 1, n++;
|
|
528
|
+
}
|
|
529
|
+
for (n = Math.max(0, Math.min(t.length - 1, n + l2)), e = Math.min(e, t[n].length) + o;e < 0 && n > 0; )
|
|
530
|
+
n--, e += t[n].length + 1;
|
|
531
|
+
for (;e > t[n].length && n < t.length - 1; )
|
|
532
|
+
e -= t[n].length + 1, n++;
|
|
533
|
+
e = Math.max(0, Math.min(t[n].length, e));
|
|
534
|
+
let h = 0;
|
|
535
|
+
for (let r = 0;r < n; r++)
|
|
536
|
+
h += t[r].length + 1;
|
|
537
|
+
return h + e;
|
|
538
|
+
}
|
|
539
|
+
var a$2 = ["up", "down", "left", "right", "space", "enter", "cancel"];
|
|
540
|
+
var t = [
|
|
541
|
+
"January",
|
|
542
|
+
"February",
|
|
543
|
+
"March",
|
|
544
|
+
"April",
|
|
545
|
+
"May",
|
|
546
|
+
"June",
|
|
547
|
+
"July",
|
|
548
|
+
"August",
|
|
549
|
+
"September",
|
|
550
|
+
"October",
|
|
551
|
+
"November",
|
|
552
|
+
"December"
|
|
553
|
+
];
|
|
554
|
+
var settings = {
|
|
555
|
+
actions: new Set(a$2),
|
|
556
|
+
aliases: /* @__PURE__ */ new Map([
|
|
557
|
+
["k", "up"],
|
|
558
|
+
["j", "down"],
|
|
559
|
+
["h", "left"],
|
|
560
|
+
["l", "right"],
|
|
561
|
+
["\x03", "cancel"],
|
|
562
|
+
["escape", "cancel"]
|
|
563
|
+
]),
|
|
564
|
+
messages: {
|
|
565
|
+
cancel: "Canceled",
|
|
566
|
+
error: "Something went wrong"
|
|
567
|
+
},
|
|
568
|
+
withGuide: true,
|
|
569
|
+
date: {
|
|
570
|
+
monthNames: [...t],
|
|
571
|
+
messages: {
|
|
572
|
+
required: "Please enter a valid date",
|
|
573
|
+
invalidMonth: "There are only 12 months in a year",
|
|
574
|
+
invalidDay: (n, e) => `There are only ${n} days in ${e}`,
|
|
575
|
+
afterMin: (n) => `Date must be on or after ${n.toISOString().slice(0, 10)}`,
|
|
576
|
+
beforeMax: (n) => `Date must be on or before ${n.toISOString().slice(0, 10)}`
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
};
|
|
580
|
+
function isActionKey(n, e) {
|
|
581
|
+
if (typeof n == "string")
|
|
582
|
+
return settings.aliases.get(n) === e;
|
|
583
|
+
for (const s of n)
|
|
584
|
+
if (s !== undefined && isActionKey(s, e))
|
|
585
|
+
return true;
|
|
586
|
+
return false;
|
|
587
|
+
}
|
|
588
|
+
function diffLines(i, s) {
|
|
589
|
+
if (i === s)
|
|
590
|
+
return;
|
|
591
|
+
const e = i.split(`
|
|
592
|
+
`), t2 = s.split(`
|
|
593
|
+
`), r = Math.max(e.length, t2.length), f = [];
|
|
594
|
+
for (let n = 0;n < r; n++)
|
|
595
|
+
e[n] !== t2[n] && f.push(n);
|
|
596
|
+
return {
|
|
597
|
+
lines: f,
|
|
598
|
+
numLinesBefore: e.length,
|
|
599
|
+
numLinesAfter: t2.length,
|
|
600
|
+
numLines: r
|
|
601
|
+
};
|
|
602
|
+
}
|
|
603
|
+
var R = globalThis.process.platform.startsWith("win");
|
|
604
|
+
var CANCEL_SYMBOL = Symbol("clack:cancel");
|
|
605
|
+
function isCancel(e) {
|
|
606
|
+
return e === CANCEL_SYMBOL;
|
|
607
|
+
}
|
|
608
|
+
function setRawMode(e, r) {
|
|
609
|
+
const o = e;
|
|
610
|
+
o.isTTY && o.setRawMode(r);
|
|
611
|
+
}
|
|
612
|
+
function block({
|
|
613
|
+
input: e = stdin,
|
|
614
|
+
output: r = stdout,
|
|
615
|
+
overwrite: o = true,
|
|
616
|
+
hideCursor: t2 = true
|
|
617
|
+
} = {}) {
|
|
618
|
+
const s = l.createInterface({
|
|
619
|
+
input: e,
|
|
620
|
+
output: r,
|
|
621
|
+
prompt: "",
|
|
622
|
+
tabSize: 1
|
|
623
|
+
});
|
|
624
|
+
l.emitKeypressEvents(e, s), e instanceof ReadStream && e.isTTY && e.setRawMode(true);
|
|
625
|
+
const n = (f, { name: a, sequence: p }) => {
|
|
626
|
+
const c = String(f);
|
|
627
|
+
if (isActionKey([c, a, p], "cancel")) {
|
|
628
|
+
t2 && r.write(import_sisteransi.cursor.show), process.exit(0);
|
|
629
|
+
return;
|
|
630
|
+
}
|
|
631
|
+
if (!o)
|
|
632
|
+
return;
|
|
633
|
+
const i = a === "return" ? 0 : -1, m = a === "return" ? -1 : 0;
|
|
634
|
+
l.moveCursor(r, i, m, () => {
|
|
635
|
+
l.clearLine(r, 1, () => {
|
|
636
|
+
e.once("keypress", n);
|
|
637
|
+
});
|
|
638
|
+
});
|
|
639
|
+
};
|
|
640
|
+
return t2 && r.write(import_sisteransi.cursor.hide), e.once("keypress", n), () => {
|
|
641
|
+
e.off("keypress", n), t2 && r.write(import_sisteransi.cursor.show), e instanceof ReadStream && e.isTTY && !R && e.setRawMode(false), s.terminal = false, s.close();
|
|
642
|
+
};
|
|
643
|
+
}
|
|
644
|
+
var getColumns = (e) => ("columns" in e) && typeof e.columns == "number" ? e.columns : 80;
|
|
645
|
+
var getRows = (e) => ("rows" in e) && typeof e.rows == "number" ? e.rows : 20;
|
|
646
|
+
function wrapTextWithPrefix(e, r, o, t2 = o, s = o, n) {
|
|
647
|
+
const f = getColumns(e ?? stdout);
|
|
648
|
+
return wrapAnsi(r, f - o.length, {
|
|
649
|
+
hard: true,
|
|
650
|
+
trim: false
|
|
651
|
+
}).split(`
|
|
652
|
+
`).map((c, i, m) => {
|
|
653
|
+
const d = n ? n(c, i) : c;
|
|
654
|
+
return i === 0 ? `${t2}${d}` : i === m.length - 1 ? `${s}${d}` : `${o}${d}`;
|
|
655
|
+
}).join(`
|
|
656
|
+
`);
|
|
657
|
+
}
|
|
658
|
+
function runValidation(e, n) {
|
|
659
|
+
if ("~standard" in e) {
|
|
660
|
+
const a = e["~standard"].validate(n);
|
|
661
|
+
if (a instanceof Promise)
|
|
662
|
+
throw new TypeError("Schema validation must be synchronous. Update `validate()` and remove any asynchronous logic.");
|
|
663
|
+
return a.issues?.at(0)?.message;
|
|
664
|
+
}
|
|
665
|
+
return e(n);
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
class V {
|
|
669
|
+
input;
|
|
670
|
+
output;
|
|
671
|
+
_abortSignal;
|
|
672
|
+
rl;
|
|
673
|
+
opts;
|
|
674
|
+
_render;
|
|
675
|
+
_track = false;
|
|
676
|
+
_prevFrame = "";
|
|
677
|
+
_subscribers = /* @__PURE__ */ new Map;
|
|
678
|
+
_cursor = 0;
|
|
679
|
+
state = "initial";
|
|
680
|
+
error = "";
|
|
681
|
+
value;
|
|
682
|
+
userInput = "";
|
|
683
|
+
constructor(t2, e = true) {
|
|
684
|
+
const { input: i = stdin, output: n = stdout, render: s, signal: r, ...o } = t2;
|
|
685
|
+
this.opts = o, this.onKeypress = this.onKeypress.bind(this), this.close = this.close.bind(this), this.render = this.render.bind(this), this._render = s.bind(this), this._track = e, this._abortSignal = r, this.input = i, this.output = n;
|
|
686
|
+
}
|
|
687
|
+
unsubscribe() {
|
|
688
|
+
this._subscribers.clear();
|
|
689
|
+
}
|
|
690
|
+
setSubscriber(t2, e) {
|
|
691
|
+
const i = this._subscribers.get(t2) ?? [];
|
|
692
|
+
i.push(e), this._subscribers.set(t2, i);
|
|
693
|
+
}
|
|
694
|
+
on(t2, e) {
|
|
695
|
+
this.setSubscriber(t2, { cb: e });
|
|
696
|
+
}
|
|
697
|
+
once(t2, e) {
|
|
698
|
+
this.setSubscriber(t2, { cb: e, once: true });
|
|
699
|
+
}
|
|
700
|
+
emit(t2, ...e) {
|
|
701
|
+
const i = this._subscribers.get(t2) ?? [], n = [];
|
|
702
|
+
for (const s of i)
|
|
703
|
+
s.cb(...e), s.once && n.push(() => i.splice(i.indexOf(s), 1));
|
|
704
|
+
for (const s of n)
|
|
705
|
+
s();
|
|
706
|
+
}
|
|
707
|
+
prompt() {
|
|
708
|
+
return new Promise((t2) => {
|
|
709
|
+
if (this._abortSignal) {
|
|
710
|
+
if (this._abortSignal.aborted)
|
|
711
|
+
return this.state = "cancel", this.close(), t2(CANCEL_SYMBOL);
|
|
712
|
+
this._abortSignal.addEventListener("abort", () => {
|
|
713
|
+
this.state = "cancel", this.close();
|
|
714
|
+
}, { once: true });
|
|
715
|
+
}
|
|
716
|
+
this.rl = l__default.createInterface({
|
|
717
|
+
input: this.input,
|
|
718
|
+
tabSize: 2,
|
|
719
|
+
prompt: "",
|
|
720
|
+
escapeCodeTimeout: 50,
|
|
721
|
+
terminal: true
|
|
722
|
+
}), this.rl.prompt(), this.opts.initialUserInput !== undefined && this._setUserInput(this.opts.initialUserInput, true), this.input.on("keypress", this.onKeypress), setRawMode(this.input, true), this.output.on("resize", this.render), this.render(), this.once("submit", () => {
|
|
723
|
+
this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), setRawMode(this.input, false), t2(this.value);
|
|
724
|
+
}), this.once("cancel", () => {
|
|
725
|
+
this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), setRawMode(this.input, false), t2(CANCEL_SYMBOL);
|
|
726
|
+
});
|
|
727
|
+
});
|
|
728
|
+
}
|
|
729
|
+
_isActionKey(t2, e) {
|
|
730
|
+
return t2 === "\t";
|
|
731
|
+
}
|
|
732
|
+
_shouldSubmit(t2, e) {
|
|
733
|
+
return true;
|
|
734
|
+
}
|
|
735
|
+
_setValue(t2) {
|
|
736
|
+
this.value = t2, this.emit("value", this.value);
|
|
737
|
+
}
|
|
738
|
+
_setUserInput(t2, e) {
|
|
739
|
+
this.userInput = t2 ?? "", this.emit("userInput", this.userInput), e && this._track && this.rl && (this.rl.write(this.userInput), this._cursor = this.rl.cursor);
|
|
740
|
+
}
|
|
741
|
+
_clearUserInput() {
|
|
742
|
+
this.rl?.write(null, { ctrl: true, name: "u" }), this._setUserInput("");
|
|
743
|
+
}
|
|
744
|
+
onKeypress(t2, e) {
|
|
745
|
+
if (this._track && e.name !== "return" && (e.name && this._isActionKey(t2, e) && this.rl?.write(null, { ctrl: true, name: "h" }), this._cursor = this.rl?.cursor ?? 0, this._setUserInput(this.rl?.line)), this.state === "error" && (this.state = "active"), e?.name && (!this._track && settings.aliases.has(e.name) && this.emit("cursor", settings.aliases.get(e.name)), settings.actions.has(e.name) && this.emit("cursor", e.name)), t2 && (t2.toLowerCase() === "y" || t2.toLowerCase() === "n") && this.emit("confirm", t2.toLowerCase() === "y"), this.emit("key", t2, e), e?.name === "return" && this._shouldSubmit(t2, e)) {
|
|
746
|
+
if (this.opts.validate) {
|
|
747
|
+
const i = runValidation(this.opts.validate, this.value);
|
|
748
|
+
i && (this.error = i instanceof Error ? i.message : i, this.state = "error", this.rl?.write(this.userInput));
|
|
749
|
+
}
|
|
750
|
+
this.state !== "error" && (this.state = "submit");
|
|
751
|
+
}
|
|
752
|
+
isActionKey([t2, e?.name, e?.sequence], "cancel") && (this.state = "cancel"), (this.state === "submit" || this.state === "cancel") && this.emit("finalize"), this.render(), (this.state === "submit" || this.state === "cancel") && this.close();
|
|
753
|
+
}
|
|
754
|
+
close() {
|
|
755
|
+
this.input.unpipe(), this.input.removeListener("keypress", this.onKeypress), this.output.write(`
|
|
756
|
+
`), setRawMode(this.input, false), this.rl?.close(), this.rl = undefined, this.emit(`${this.state}`, this.value), this.unsubscribe();
|
|
757
|
+
}
|
|
758
|
+
restoreCursor() {
|
|
759
|
+
const t2 = wrapAnsi(this._prevFrame, process.stdout.columns, { hard: true, trim: false }).split(`
|
|
760
|
+
`).length - 1;
|
|
761
|
+
this.output.write(import_sisteransi.cursor.move(-999, t2 * -1));
|
|
762
|
+
}
|
|
763
|
+
render() {
|
|
764
|
+
const t2 = wrapAnsi(this._render(this) ?? "", process.stdout.columns, {
|
|
765
|
+
hard: true,
|
|
766
|
+
trim: false
|
|
767
|
+
});
|
|
768
|
+
if (t2 !== this._prevFrame) {
|
|
769
|
+
if (this.state === "initial")
|
|
770
|
+
this.output.write(import_sisteransi.cursor.hide);
|
|
771
|
+
else {
|
|
772
|
+
const e = diffLines(this._prevFrame, t2), i = getRows(this.output);
|
|
773
|
+
if (this.restoreCursor(), e) {
|
|
774
|
+
const n = Math.max(0, e.numLinesAfter - i), s = Math.max(0, e.numLinesBefore - i);
|
|
775
|
+
let r = e.lines.find((o) => o >= n);
|
|
776
|
+
if (r === undefined) {
|
|
777
|
+
this._prevFrame = t2;
|
|
778
|
+
return;
|
|
779
|
+
}
|
|
780
|
+
if (e.lines.length === 1) {
|
|
781
|
+
this.output.write(import_sisteransi.cursor.move(0, r - s)), this.output.write(import_sisteransi.erase.lines(1));
|
|
782
|
+
const o = t2.split(`
|
|
783
|
+
`);
|
|
784
|
+
this.output.write(o[r]), this._prevFrame = t2, this.output.write(import_sisteransi.cursor.move(0, o.length - r - 1));
|
|
785
|
+
return;
|
|
786
|
+
} else if (e.lines.length > 1) {
|
|
787
|
+
if (n < s)
|
|
788
|
+
r = n;
|
|
789
|
+
else {
|
|
790
|
+
const h = r - s;
|
|
791
|
+
h > 0 && this.output.write(import_sisteransi.cursor.move(0, h));
|
|
792
|
+
}
|
|
793
|
+
this.output.write(import_sisteransi.erase.down());
|
|
794
|
+
const f = t2.split(`
|
|
795
|
+
`).slice(r);
|
|
796
|
+
this.output.write(f.join(`
|
|
797
|
+
`)), this._prevFrame = t2;
|
|
798
|
+
return;
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
this.output.write(import_sisteransi.erase.down());
|
|
802
|
+
}
|
|
803
|
+
this.output.write(t2), this.state === "initial" && (this.state = "active"), this._prevFrame = t2;
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
function p$1(l2, e) {
|
|
808
|
+
if (l2 === undefined || e.length === 0)
|
|
809
|
+
return 0;
|
|
810
|
+
const i = e.findIndex((s) => s.value === l2);
|
|
811
|
+
return i !== -1 ? i : 0;
|
|
812
|
+
}
|
|
813
|
+
function g(l2, e) {
|
|
814
|
+
return (e.label ?? String(e.value)).toLowerCase().includes(l2.toLowerCase());
|
|
815
|
+
}
|
|
816
|
+
function m(l2, e) {
|
|
817
|
+
if (e)
|
|
818
|
+
return l2 ? e : e[0];
|
|
819
|
+
}
|
|
820
|
+
var T$1 = class T extends V {
|
|
821
|
+
filteredOptions;
|
|
822
|
+
multiple;
|
|
823
|
+
isNavigating = false;
|
|
824
|
+
selectedValues = [];
|
|
825
|
+
focusedValue;
|
|
826
|
+
#e = 0;
|
|
827
|
+
#s = "";
|
|
828
|
+
#t;
|
|
829
|
+
#i;
|
|
830
|
+
#n;
|
|
831
|
+
get cursor() {
|
|
832
|
+
return this.#e;
|
|
833
|
+
}
|
|
834
|
+
get userInputWithCursor() {
|
|
835
|
+
if (!this.userInput)
|
|
836
|
+
return styleText(["inverse", "hidden"], "_");
|
|
837
|
+
if (this._cursor >= this.userInput.length)
|
|
838
|
+
return `${this.userInput}█`;
|
|
839
|
+
const e = this.userInput.slice(0, this._cursor), [t2, ...i] = this.userInput.slice(this._cursor);
|
|
840
|
+
return `${e}${styleText("inverse", t2)}${i.join("")}`;
|
|
841
|
+
}
|
|
842
|
+
get options() {
|
|
843
|
+
return typeof this.#i == "function" ? this.#i() : this.#i;
|
|
844
|
+
}
|
|
845
|
+
constructor(e) {
|
|
846
|
+
super(e), this.#i = e.options, this.#n = e.placeholder;
|
|
847
|
+
const t2 = this.options;
|
|
848
|
+
this.filteredOptions = [...t2], this.multiple = e.multiple === true, this.#t = typeof e.options == "function" ? e.filter : e.filter ?? g;
|
|
849
|
+
let i;
|
|
850
|
+
if (e.initialValue && Array.isArray(e.initialValue) ? this.multiple ? i = e.initialValue : i = e.initialValue.slice(0, 1) : !this.multiple && this.options.length > 0 && (i = [this.options[0].value]), i)
|
|
851
|
+
for (const s of i) {
|
|
852
|
+
const n = t2.findIndex((o) => o.value === s);
|
|
853
|
+
n !== -1 && (this.toggleSelected(s), this.#e = n);
|
|
854
|
+
}
|
|
855
|
+
this.focusedValue = this.options[this.#e]?.value, this.on("key", (s, n) => this.#l(s, n)), this.on("userInput", (s) => this.#u(s));
|
|
856
|
+
}
|
|
857
|
+
_isActionKey(e, t2) {
|
|
858
|
+
return e === "\t" || this.multiple && this.isNavigating && t2.name === "space" && e !== undefined && e !== "";
|
|
859
|
+
}
|
|
860
|
+
#l(e, t2) {
|
|
861
|
+
const i = t2.name === "up", s = t2.name === "down", n = t2.name === "return", o = this.userInput === "" || this.userInput === "\t", u = this.#n, h = this.options, f = u !== undefined && u !== "" && h.some((r) => !r.disabled && (this.#t ? this.#t(u, r) : true));
|
|
862
|
+
if (t2.name === "tab" && o && f) {
|
|
863
|
+
this.userInput === "\t" && this._clearUserInput(), this._setUserInput(u, true), this.isNavigating = false;
|
|
864
|
+
return;
|
|
865
|
+
}
|
|
866
|
+
i || s ? (this.#e = findCursor(this.#e, i ? -1 : 1, this.filteredOptions), this.focusedValue = this.filteredOptions[this.#e]?.value, this.multiple || (this.selectedValues = [this.focusedValue]), this.isNavigating = true) : n ? this.value = m(this.multiple, this.selectedValues) : this.multiple ? this.focusedValue !== undefined && (t2.name === "tab" || this.isNavigating && t2.name === "space") ? this.toggleSelected(this.focusedValue) : this.isNavigating = false : (this.focusedValue && (this.selectedValues = [this.focusedValue]), this.isNavigating = false);
|
|
867
|
+
}
|
|
868
|
+
deselectAll() {
|
|
869
|
+
this.selectedValues = [];
|
|
870
|
+
}
|
|
871
|
+
toggleSelected(e) {
|
|
872
|
+
this.filteredOptions.length !== 0 && (this.multiple ? this.selectedValues.includes(e) ? this.selectedValues = this.selectedValues.filter((t2) => t2 !== e) : this.selectedValues = [...this.selectedValues, e] : this.selectedValues = [e]);
|
|
873
|
+
}
|
|
874
|
+
#u(e) {
|
|
875
|
+
if (e !== this.#s) {
|
|
876
|
+
this.#s = e;
|
|
877
|
+
const t2 = this.options;
|
|
878
|
+
e && this.#t ? this.filteredOptions = t2.filter((n) => this.#t?.(e, n)) : this.filteredOptions = [...t2];
|
|
879
|
+
const i = p$1(this.focusedValue, this.filteredOptions);
|
|
880
|
+
this.#e = findCursor(i, 0, this.filteredOptions);
|
|
881
|
+
const s = this.filteredOptions[this.#e];
|
|
882
|
+
s && !s.disabled ? this.focusedValue = s.value : this.focusedValue = undefined, this.multiple || (this.focusedValue !== undefined ? this.toggleSelected(this.focusedValue) : this.deselectAll());
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
};
|
|
886
|
+
|
|
887
|
+
class r extends V {
|
|
888
|
+
get cursor() {
|
|
889
|
+
return this.value ? 0 : 1;
|
|
890
|
+
}
|
|
891
|
+
get _value() {
|
|
892
|
+
return this.cursor === 0;
|
|
893
|
+
}
|
|
894
|
+
constructor(t2) {
|
|
895
|
+
super(t2, false), this.value = !!t2.initialValue, this.on("userInput", () => {
|
|
896
|
+
this.value = this._value;
|
|
897
|
+
}), this.on("confirm", (i) => {
|
|
898
|
+
this.output.write(import_sisteransi.cursor.move(0, -1)), this.value = i, this.state = "submit", this.close();
|
|
899
|
+
}), this.on("cursor", () => {
|
|
900
|
+
this.value = !this.value;
|
|
901
|
+
});
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
var _ = {
|
|
905
|
+
Y: { type: "year", len: 4 },
|
|
906
|
+
M: { type: "month", len: 2 },
|
|
907
|
+
D: { type: "day", len: 2 }
|
|
908
|
+
};
|
|
909
|
+
function M(r2) {
|
|
910
|
+
return [...r2].map((t2) => _[t2]);
|
|
911
|
+
}
|
|
912
|
+
function P(r2) {
|
|
913
|
+
const i = new Intl.DateTimeFormat(r2, {
|
|
914
|
+
year: "numeric",
|
|
915
|
+
month: "2-digit",
|
|
916
|
+
day: "2-digit"
|
|
917
|
+
}).formatToParts(new Date(2000, 0, 15)), s = [];
|
|
918
|
+
let n = "/";
|
|
919
|
+
for (const e of i)
|
|
920
|
+
e.type === "literal" ? n = e.value.trim() || e.value : (e.type === "year" || e.type === "month" || e.type === "day") && s.push({ type: e.type, len: e.type === "year" ? 4 : 2 });
|
|
921
|
+
return { segments: s, separator: n };
|
|
922
|
+
}
|
|
923
|
+
function p(r2) {
|
|
924
|
+
return Number.parseInt((r2 || "0").replace(/_/g, "0"), 10) || 0;
|
|
925
|
+
}
|
|
926
|
+
function f(r2) {
|
|
927
|
+
return {
|
|
928
|
+
year: p(r2.year),
|
|
929
|
+
month: p(r2.month),
|
|
930
|
+
day: p(r2.day)
|
|
931
|
+
};
|
|
932
|
+
}
|
|
933
|
+
function c(r2, t2) {
|
|
934
|
+
return new Date(r2 || 2001, t2 || 1, 0).getDate();
|
|
935
|
+
}
|
|
936
|
+
function b(r2) {
|
|
937
|
+
const { year: t2, month: i, day: s } = f(r2);
|
|
938
|
+
if (!t2 || t2 < 0 || t2 > 9999 || !i || i < 1 || i > 12 || !s || s < 1)
|
|
939
|
+
return;
|
|
940
|
+
const n = new Date(Date.UTC(t2, i - 1, s));
|
|
941
|
+
if (!(n.getUTCFullYear() !== t2 || n.getUTCMonth() !== i - 1 || n.getUTCDate() !== s))
|
|
942
|
+
return { year: t2, month: i, day: s };
|
|
943
|
+
}
|
|
944
|
+
function C(r2) {
|
|
945
|
+
const t2 = b(r2);
|
|
946
|
+
return t2 ? new Date(Date.UTC(t2.year, t2.month - 1, t2.day)) : undefined;
|
|
947
|
+
}
|
|
948
|
+
function T2(r2, t2, i, s) {
|
|
949
|
+
const n = i ? {
|
|
950
|
+
year: i.getUTCFullYear(),
|
|
951
|
+
month: i.getUTCMonth() + 1,
|
|
952
|
+
day: i.getUTCDate()
|
|
953
|
+
} : null, e = s ? {
|
|
954
|
+
year: s.getUTCFullYear(),
|
|
955
|
+
month: s.getUTCMonth() + 1,
|
|
956
|
+
day: s.getUTCDate()
|
|
957
|
+
} : null;
|
|
958
|
+
return r2 === "year" ? { min: n?.year ?? 1, max: e?.year ?? 9999 } : r2 === "month" ? {
|
|
959
|
+
min: n && t2.year === n.year ? n.month : 1,
|
|
960
|
+
max: e && t2.year === e.year ? e.month : 12
|
|
961
|
+
} : {
|
|
962
|
+
min: n && t2.year === n.year && t2.month === n.month ? n.day : 1,
|
|
963
|
+
max: e && t2.year === e.year && t2.month === e.month ? e.day : c(t2.year, t2.month)
|
|
964
|
+
};
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
class U extends V {
|
|
968
|
+
#i;
|
|
969
|
+
#o;
|
|
970
|
+
#t;
|
|
971
|
+
#h;
|
|
972
|
+
#u;
|
|
973
|
+
#e = { segmentIndex: 0, positionInSegment: 0 };
|
|
974
|
+
#n = true;
|
|
975
|
+
#s = null;
|
|
976
|
+
inlineError = "";
|
|
977
|
+
get segmentCursor() {
|
|
978
|
+
return { ...this.#e };
|
|
979
|
+
}
|
|
980
|
+
get segmentValues() {
|
|
981
|
+
return { ...this.#t };
|
|
982
|
+
}
|
|
983
|
+
get segments() {
|
|
984
|
+
return this.#i;
|
|
985
|
+
}
|
|
986
|
+
get separator() {
|
|
987
|
+
return this.#o;
|
|
988
|
+
}
|
|
989
|
+
get formattedValue() {
|
|
990
|
+
return this.#l(this.#t);
|
|
991
|
+
}
|
|
992
|
+
#l(t2) {
|
|
993
|
+
return this.#i.map((i) => t2[i.type]).join(this.#o);
|
|
994
|
+
}
|
|
995
|
+
#r() {
|
|
996
|
+
this._setUserInput(this.#l(this.#t)), this._setValue(C(this.#t) ?? undefined);
|
|
997
|
+
}
|
|
998
|
+
constructor(t2) {
|
|
999
|
+
const i = t2.format ? { segments: M(t2.format), separator: t2.separator ?? "/" } : P(t2.locale), s = t2.separator ?? i.separator, n = t2.format ? M(t2.format) : i.segments, e = t2.initialValue ?? t2.defaultValue, m2 = e ? {
|
|
1000
|
+
year: String(e.getUTCFullYear()).padStart(4, "0"),
|
|
1001
|
+
month: String(e.getUTCMonth() + 1).padStart(2, "0"),
|
|
1002
|
+
day: String(e.getUTCDate()).padStart(2, "0")
|
|
1003
|
+
} : { year: "____", month: "__", day: "__" }, o = n.map((a) => m2[a.type]).join(s);
|
|
1004
|
+
super({ ...t2, initialUserInput: o }, false), this.#i = n, this.#o = s, this.#t = m2, this.#h = t2.minDate, this.#u = t2.maxDate, this.#r(), this.on("cursor", (a) => this.#f(a)), this.on("key", (a, u) => this.#y(a, u)), this.on("finalize", () => this.#p(t2));
|
|
1005
|
+
}
|
|
1006
|
+
#a() {
|
|
1007
|
+
const t2 = Math.max(0, Math.min(this.#e.segmentIndex, this.#i.length - 1)), i = this.#i[t2];
|
|
1008
|
+
if (i)
|
|
1009
|
+
return this.#e.positionInSegment = Math.max(0, Math.min(this.#e.positionInSegment, i.len - 1)), { segment: i, index: t2 };
|
|
1010
|
+
}
|
|
1011
|
+
#m(t2) {
|
|
1012
|
+
this.inlineError = "", this.#s = null;
|
|
1013
|
+
const i = this.#a();
|
|
1014
|
+
i && (this.#e.segmentIndex = Math.max(0, Math.min(this.#i.length - 1, i.index + t2)), this.#e.positionInSegment = 0, this.#n = true);
|
|
1015
|
+
}
|
|
1016
|
+
#d(t2) {
|
|
1017
|
+
const i = this.#a();
|
|
1018
|
+
if (!i)
|
|
1019
|
+
return;
|
|
1020
|
+
const { segment: s } = i, n = this.#t[s.type], e = !n || n.replace(/_/g, "") === "", m2 = Number.parseInt((n || "0").replace(/_/g, "0"), 10) || 0, o = T2(s.type, f(this.#t), this.#h, this.#u);
|
|
1021
|
+
let a;
|
|
1022
|
+
e ? a = t2 === 1 ? o.min : o.max : a = Math.max(Math.min(o.max, m2 + t2), o.min), this.#t = {
|
|
1023
|
+
...this.#t,
|
|
1024
|
+
[s.type]: a.toString().padStart(s.len, "0")
|
|
1025
|
+
}, this.#n = true, this.#s = null, this.#r();
|
|
1026
|
+
}
|
|
1027
|
+
#f(t2) {
|
|
1028
|
+
if (t2)
|
|
1029
|
+
switch (t2) {
|
|
1030
|
+
case "right":
|
|
1031
|
+
return this.#m(1);
|
|
1032
|
+
case "left":
|
|
1033
|
+
return this.#m(-1);
|
|
1034
|
+
case "up":
|
|
1035
|
+
return this.#d(1);
|
|
1036
|
+
case "down":
|
|
1037
|
+
return this.#d(-1);
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
#y(t2, i) {
|
|
1041
|
+
if (i?.name === "backspace" || i?.sequence === "" || i?.sequence === "\b" || t2 === "" || t2 === "\b") {
|
|
1042
|
+
this.inlineError = "";
|
|
1043
|
+
const n = this.#a();
|
|
1044
|
+
if (!n)
|
|
1045
|
+
return;
|
|
1046
|
+
if (!this.#t[n.segment.type].replace(/_/g, "")) {
|
|
1047
|
+
this.#m(-1);
|
|
1048
|
+
return;
|
|
1049
|
+
}
|
|
1050
|
+
this.#t[n.segment.type] = "_".repeat(n.segment.len), this.#n = true, this.#e.positionInSegment = 0, this.#r();
|
|
1051
|
+
return;
|
|
1052
|
+
}
|
|
1053
|
+
if (i?.name === "tab") {
|
|
1054
|
+
this.inlineError = "";
|
|
1055
|
+
const n = this.#a();
|
|
1056
|
+
if (!n)
|
|
1057
|
+
return;
|
|
1058
|
+
const e = i.shift ? -1 : 1, m2 = n.index + e;
|
|
1059
|
+
m2 >= 0 && m2 < this.#i.length && (this.#e.segmentIndex = m2, this.#e.positionInSegment = 0, this.#n = true);
|
|
1060
|
+
return;
|
|
1061
|
+
}
|
|
1062
|
+
if (t2 && /^[0-9]$/.test(t2)) {
|
|
1063
|
+
const n = this.#a();
|
|
1064
|
+
if (!n)
|
|
1065
|
+
return;
|
|
1066
|
+
const { segment: e } = n, m2 = !this.#t[e.type].replace(/_/g, "");
|
|
1067
|
+
if (this.#n && this.#s !== null && !m2) {
|
|
1068
|
+
const h = this.#s + t2, d = { ...this.#t, [e.type]: h }, g2 = this.#g(d, e);
|
|
1069
|
+
if (g2) {
|
|
1070
|
+
this.inlineError = g2, this.#s = null, this.#n = false;
|
|
1071
|
+
return;
|
|
1072
|
+
}
|
|
1073
|
+
this.inlineError = "", this.#t[e.type] = h, this.#s = null, this.#n = false, this.#r(), n.index < this.#i.length - 1 && (this.#e.segmentIndex = n.index + 1, this.#e.positionInSegment = 0, this.#n = true);
|
|
1074
|
+
return;
|
|
1075
|
+
}
|
|
1076
|
+
this.#n && !m2 && (this.#t[e.type] = "_".repeat(e.len), this.#e.positionInSegment = 0), this.#n = false, this.#s = null;
|
|
1077
|
+
const o = this.#t[e.type], a = o.indexOf("_"), u = a >= 0 ? a : Math.min(this.#e.positionInSegment, e.len - 1);
|
|
1078
|
+
if (u < 0 || u >= e.len)
|
|
1079
|
+
return;
|
|
1080
|
+
let l2 = o.slice(0, u) + t2 + o.slice(u + 1), D = false;
|
|
1081
|
+
if (u === 0 && o === "__" && (e.type === "month" || e.type === "day")) {
|
|
1082
|
+
const h = Number.parseInt(t2, 10);
|
|
1083
|
+
l2 = `0${t2}`, D = h <= (e.type === "month" ? 1 : 2);
|
|
1084
|
+
}
|
|
1085
|
+
if (e.type === "year" && (l2 = (o.replace(/_/g, "") + t2).padStart(e.len, "_")), !l2.includes("_")) {
|
|
1086
|
+
const h = { ...this.#t, [e.type]: l2 }, d = this.#g(h, e);
|
|
1087
|
+
if (d) {
|
|
1088
|
+
this.inlineError = d;
|
|
1089
|
+
return;
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
this.inlineError = "", this.#t[e.type] = l2;
|
|
1093
|
+
const y = l2.includes("_") ? undefined : b(this.#t);
|
|
1094
|
+
if (y) {
|
|
1095
|
+
const { year: h, month: d } = y, g2 = c(h, d);
|
|
1096
|
+
this.#t = {
|
|
1097
|
+
year: String(Math.max(0, Math.min(9999, h))).padStart(4, "0"),
|
|
1098
|
+
month: String(Math.max(1, Math.min(12, d))).padStart(2, "0"),
|
|
1099
|
+
day: String(Math.max(1, Math.min(g2, y.day))).padStart(2, "0")
|
|
1100
|
+
};
|
|
1101
|
+
}
|
|
1102
|
+
this.#r();
|
|
1103
|
+
const S = l2.indexOf("_");
|
|
1104
|
+
D ? (this.#n = true, this.#s = t2) : S >= 0 ? this.#e.positionInSegment = S : a >= 0 && n.index < this.#i.length - 1 ? (this.#e.segmentIndex = n.index + 1, this.#e.positionInSegment = 0, this.#n = true) : this.#e.positionInSegment = Math.min(u + 1, e.len - 1);
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
#g(t2, i) {
|
|
1108
|
+
const { month: s, day: n } = f(t2);
|
|
1109
|
+
if (i.type === "month" && (s < 0 || s > 12))
|
|
1110
|
+
return settings.date.messages.invalidMonth;
|
|
1111
|
+
if (i.type === "day" && (n < 0 || n > 31))
|
|
1112
|
+
return settings.date.messages.invalidDay(31, "any month");
|
|
1113
|
+
}
|
|
1114
|
+
#p(t2) {
|
|
1115
|
+
const { year: i, month: s, day: n } = f(this.#t);
|
|
1116
|
+
if (i && s && n) {
|
|
1117
|
+
const e = c(i, s);
|
|
1118
|
+
this.#t = {
|
|
1119
|
+
...this.#t,
|
|
1120
|
+
day: String(Math.min(n, e)).padStart(2, "0")
|
|
1121
|
+
};
|
|
1122
|
+
}
|
|
1123
|
+
this.value = C(this.#t) ?? t2.defaultValue ?? undefined;
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
var u$1 = class u extends V {
|
|
1127
|
+
options;
|
|
1128
|
+
cursor = 0;
|
|
1129
|
+
#t;
|
|
1130
|
+
getGroupItems(t2) {
|
|
1131
|
+
return this.options.filter((r2) => r2.group === t2);
|
|
1132
|
+
}
|
|
1133
|
+
isGroupSelected(t2) {
|
|
1134
|
+
const r2 = this.getGroupItems(t2), e = this.value;
|
|
1135
|
+
return e === undefined ? false : r2.every((s) => e.includes(s.value));
|
|
1136
|
+
}
|
|
1137
|
+
toggleValue() {
|
|
1138
|
+
const t2 = this.options[this.cursor];
|
|
1139
|
+
if (this.value === undefined && (this.value = []), t2.group === true) {
|
|
1140
|
+
const r2 = t2.value, e = this.getGroupItems(r2);
|
|
1141
|
+
this.isGroupSelected(r2) ? this.value = this.value.filter((s) => e.findIndex((i) => i.value === s) === -1) : this.value = [...this.value, ...e.map((s) => s.value)], this.value = Array.from(new Set(this.value));
|
|
1142
|
+
} else {
|
|
1143
|
+
const r2 = this.value.includes(t2.value);
|
|
1144
|
+
this.value = r2 ? this.value.filter((e) => e !== t2.value) : [...this.value, t2.value];
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
constructor(t2) {
|
|
1148
|
+
super(t2, false);
|
|
1149
|
+
const { options: r2 } = t2;
|
|
1150
|
+
this.#t = t2.selectableGroups !== false, this.options = Object.entries(r2).flatMap(([e, s]) => [
|
|
1151
|
+
{ value: e, group: true, label: e },
|
|
1152
|
+
...s.map((i) => ({ ...i, group: e }))
|
|
1153
|
+
]), this.value = [...t2.initialValues ?? []], this.cursor = Math.max(this.options.findIndex(({ value: e }) => e === t2.cursorAt), this.#t ? 0 : 1), this.on("cursor", (e) => {
|
|
1154
|
+
switch (e) {
|
|
1155
|
+
case "left":
|
|
1156
|
+
case "up": {
|
|
1157
|
+
this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
|
|
1158
|
+
const s = this.options[this.cursor]?.group === true;
|
|
1159
|
+
!this.#t && s && (this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1);
|
|
1160
|
+
break;
|
|
1161
|
+
}
|
|
1162
|
+
case "down":
|
|
1163
|
+
case "right": {
|
|
1164
|
+
this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
|
|
1165
|
+
const s = this.options[this.cursor]?.group === true;
|
|
1166
|
+
!this.#t && s && (this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1);
|
|
1167
|
+
break;
|
|
1168
|
+
}
|
|
1169
|
+
case "space":
|
|
1170
|
+
this.toggleValue();
|
|
1171
|
+
break;
|
|
1172
|
+
}
|
|
1173
|
+
});
|
|
1174
|
+
}
|
|
1175
|
+
};
|
|
1176
|
+
var o$1 = /* @__PURE__ */ new Set(["up", "down", "left", "right"]);
|
|
1177
|
+
|
|
1178
|
+
class h extends V {
|
|
1179
|
+
#t = false;
|
|
1180
|
+
#s;
|
|
1181
|
+
focused = "editor";
|
|
1182
|
+
get userInputWithCursor() {
|
|
1183
|
+
if (this.state === "submit")
|
|
1184
|
+
return this.userInput;
|
|
1185
|
+
const t2 = this.userInput;
|
|
1186
|
+
if (this.cursor >= t2.length)
|
|
1187
|
+
return `${t2}█`;
|
|
1188
|
+
const s = t2.slice(0, this.cursor), r2 = t2[this.cursor], i = t2.slice(this.cursor + 1);
|
|
1189
|
+
return r2 === `
|
|
1190
|
+
` ? `${s}█
|
|
1191
|
+
${i}` : `${s}${styleText("inverse", r2)}${i}`;
|
|
1192
|
+
}
|
|
1193
|
+
get cursor() {
|
|
1194
|
+
return this._cursor;
|
|
1195
|
+
}
|
|
1196
|
+
#r(t2) {
|
|
1197
|
+
if (this.userInput.length === 0) {
|
|
1198
|
+
this._setUserInput(t2);
|
|
1199
|
+
return;
|
|
1200
|
+
}
|
|
1201
|
+
this._setUserInput(this.userInput.slice(0, this.cursor) + t2 + this.userInput.slice(this.cursor));
|
|
1202
|
+
}
|
|
1203
|
+
#i(t2) {
|
|
1204
|
+
const s = this.value ?? "";
|
|
1205
|
+
switch (t2) {
|
|
1206
|
+
case "up":
|
|
1207
|
+
this._cursor = findTextCursor(this._cursor, 0, -1, s);
|
|
1208
|
+
return;
|
|
1209
|
+
case "down":
|
|
1210
|
+
this._cursor = findTextCursor(this._cursor, 0, 1, s);
|
|
1211
|
+
return;
|
|
1212
|
+
case "left":
|
|
1213
|
+
this._cursor = findTextCursor(this._cursor, -1, 0, s);
|
|
1214
|
+
return;
|
|
1215
|
+
case "right":
|
|
1216
|
+
this._cursor = findTextCursor(this._cursor, 1, 0, s);
|
|
1217
|
+
return;
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
_shouldSubmit(t2, s) {
|
|
1221
|
+
if (this.#s)
|
|
1222
|
+
return this.focused === "submit" ? true : (this.#r(`
|
|
1223
|
+
`), this._cursor++, false);
|
|
1224
|
+
const r2 = this.#t;
|
|
1225
|
+
return this.#t = true, r2 && this.cursor === this.userInput.length ? (this.userInput[this.cursor - 1] === `
|
|
1226
|
+
` && (this._setUserInput(this.userInput.slice(0, this.cursor - 1) + this.userInput.slice(this.cursor)), this._cursor--), true) : (this.#r(`
|
|
1227
|
+
`), this._cursor++, false);
|
|
1228
|
+
}
|
|
1229
|
+
constructor(t2) {
|
|
1230
|
+
const s = t2.initialUserInput ?? t2.initialValue;
|
|
1231
|
+
super({
|
|
1232
|
+
...t2,
|
|
1233
|
+
initialUserInput: s
|
|
1234
|
+
}, false), s !== undefined && (this._cursor = s.length), this.#s = t2.showSubmit ?? false, this.on("key", (r2, i) => {
|
|
1235
|
+
if (i?.name && o$1.has(i.name)) {
|
|
1236
|
+
this.#t = false, this.#i(i.name);
|
|
1237
|
+
return;
|
|
1238
|
+
}
|
|
1239
|
+
if (r2 === "\t" && this.#s) {
|
|
1240
|
+
this.focused = this.focused === "editor" ? "submit" : "editor";
|
|
1241
|
+
return;
|
|
1242
|
+
}
|
|
1243
|
+
if (i?.name !== "return") {
|
|
1244
|
+
if (this.#t = false, i?.name === "backspace" && this.cursor > 0) {
|
|
1245
|
+
this._setUserInput(this.userInput.slice(0, this.cursor - 1) + this.userInput.slice(this.cursor)), this._cursor--;
|
|
1246
|
+
return;
|
|
1247
|
+
}
|
|
1248
|
+
if (i?.name === "delete" && this.cursor < this.userInput.length) {
|
|
1249
|
+
this._setUserInput(this.userInput.slice(0, this.cursor) + this.userInput.slice(this.cursor + 1));
|
|
1250
|
+
return;
|
|
1251
|
+
}
|
|
1252
|
+
r2 && (this.#s && this.focused === "submit" && (this.focused = "editor"), this.#r(r2 ?? ""), this._cursor++);
|
|
1253
|
+
}
|
|
1254
|
+
}), this.on("userInput", (r2) => {
|
|
1255
|
+
this._setValue(r2);
|
|
1256
|
+
}), this.on("finalize", () => {
|
|
1257
|
+
this.value || (this.value = t2.defaultValue), this.value === undefined && (this.value = "");
|
|
1258
|
+
});
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1261
|
+
class a extends V {
|
|
1262
|
+
options;
|
|
1263
|
+
cursor = 0;
|
|
1264
|
+
get _selectedValue() {
|
|
1265
|
+
return this.options[this.cursor];
|
|
1266
|
+
}
|
|
1267
|
+
changeValue() {
|
|
1268
|
+
this.value = this._selectedValue.value;
|
|
1269
|
+
}
|
|
1270
|
+
constructor(t2) {
|
|
1271
|
+
super(t2, false), this.options = t2.options;
|
|
1272
|
+
const i = this.options.findIndex(({ value: s }) => s === t2.initialValue), e = i === -1 ? 0 : i;
|
|
1273
|
+
this.cursor = this.options[e].disabled ? findCursor(e, 1, this.options) : e, this.changeValue(), this.on("cursor", (s) => {
|
|
1274
|
+
switch (s) {
|
|
1275
|
+
case "left":
|
|
1276
|
+
case "up":
|
|
1277
|
+
this.cursor = findCursor(this.cursor, -1, this.options);
|
|
1278
|
+
break;
|
|
1279
|
+
case "down":
|
|
1280
|
+
case "right":
|
|
1281
|
+
this.cursor = findCursor(this.cursor, 1, this.options);
|
|
1282
|
+
break;
|
|
1283
|
+
}
|
|
1284
|
+
this.changeValue();
|
|
1285
|
+
});
|
|
1286
|
+
}
|
|
1287
|
+
}
|
|
1288
|
+
class n extends V {
|
|
1289
|
+
get userInputWithCursor() {
|
|
1290
|
+
if (this.state === "submit")
|
|
1291
|
+
return this.userInput;
|
|
1292
|
+
const t2 = this.userInput;
|
|
1293
|
+
if (this.cursor >= t2.length)
|
|
1294
|
+
return `${this.userInput}█`;
|
|
1295
|
+
const e = t2.slice(0, this.cursor), [s, ...r2] = t2.slice(this.cursor);
|
|
1296
|
+
return `${e}${styleText("inverse", s)}${r2.join("")}`;
|
|
1297
|
+
}
|
|
1298
|
+
get cursor() {
|
|
1299
|
+
return this._cursor;
|
|
1300
|
+
}
|
|
1301
|
+
constructor(t2) {
|
|
1302
|
+
super({
|
|
1303
|
+
...t2,
|
|
1304
|
+
initialUserInput: t2.initialUserInput ?? t2.initialValue
|
|
1305
|
+
}), this.on("userInput", (e) => {
|
|
1306
|
+
this._setValue(e);
|
|
1307
|
+
}), this.on("finalize", () => {
|
|
1308
|
+
this.value || (this.value = t2.defaultValue), this.value === undefined && (this.value = "");
|
|
1309
|
+
});
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
|
|
1313
|
+
// node_modules/@clack/prompts/dist/index.mjs
|
|
1314
|
+
import { styleText as styleText2, stripVTControlCharacters } from "node:util";
|
|
1315
|
+
import process$1 from "node:process";
|
|
1316
|
+
var import_sisteransi2 = __toESM(require_src(), 1);
|
|
1317
|
+
function isUnicodeSupported() {
|
|
1318
|
+
if (process$1.platform !== "win32") {
|
|
1319
|
+
return process$1.env.TERM !== "linux";
|
|
1320
|
+
}
|
|
1321
|
+
return Boolean(process$1.env.CI) || Boolean(process$1.env.WT_SESSION) || Boolean(process$1.env.TERMINUS_SUBLIME) || process$1.env.ConEmuTask === "{cmd::Cmder}" || process$1.env.TERM_PROGRAM === "Terminus-Sublime" || process$1.env.TERM_PROGRAM === "vscode" || process$1.env.TERM === "xterm-256color" || process$1.env.TERM === "alacritty" || process$1.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
|
|
1322
|
+
}
|
|
1323
|
+
var unicode = isUnicodeSupported();
|
|
1324
|
+
var isCI = () => process.env.CI === "true";
|
|
1325
|
+
var unicodeOr = (o2, e) => unicode ? o2 : e;
|
|
1326
|
+
var S_STEP_ACTIVE = unicodeOr("◆", "*");
|
|
1327
|
+
var S_STEP_CANCEL = unicodeOr("■", "x");
|
|
1328
|
+
var S_STEP_ERROR = unicodeOr("▲", "x");
|
|
1329
|
+
var S_STEP_SUBMIT = unicodeOr("◇", "o");
|
|
1330
|
+
var S_BAR_START = unicodeOr("┌", "T");
|
|
1331
|
+
var S_BAR = unicodeOr("│", "|");
|
|
1332
|
+
var S_BAR_END = unicodeOr("└", "—");
|
|
1333
|
+
var S_BAR_START_RIGHT = unicodeOr("┐", "T");
|
|
1334
|
+
var S_BAR_END_RIGHT = unicodeOr("┘", "—");
|
|
1335
|
+
var S_RADIO_ACTIVE = unicodeOr("●", ">");
|
|
1336
|
+
var S_RADIO_INACTIVE = unicodeOr("○", " ");
|
|
1337
|
+
var S_CHECKBOX_ACTIVE = unicodeOr("◻", "[•]");
|
|
1338
|
+
var S_CHECKBOX_SELECTED = unicodeOr("◼", "[+]");
|
|
1339
|
+
var S_CHECKBOX_INACTIVE = unicodeOr("◻", "[ ]");
|
|
1340
|
+
var S_PASSWORD_MASK = unicodeOr("▪", "•");
|
|
1341
|
+
var S_BAR_H = unicodeOr("─", "-");
|
|
1342
|
+
var S_CORNER_TOP_RIGHT = unicodeOr("╮", "+");
|
|
1343
|
+
var S_CONNECT_LEFT = unicodeOr("├", "+");
|
|
1344
|
+
var S_CORNER_BOTTOM_RIGHT = unicodeOr("╯", "+");
|
|
1345
|
+
var S_CORNER_BOTTOM_LEFT = unicodeOr("╰", "+");
|
|
1346
|
+
var S_CORNER_TOP_LEFT = unicodeOr("╭", "+");
|
|
1347
|
+
var S_INFO = unicodeOr("●", "•");
|
|
1348
|
+
var S_SUCCESS = unicodeOr("◆", "*");
|
|
1349
|
+
var S_WARN = unicodeOr("▲", "!");
|
|
1350
|
+
var S_ERROR = unicodeOr("■", "x");
|
|
1351
|
+
var symbol = (o2) => {
|
|
1352
|
+
switch (o2) {
|
|
1353
|
+
case "initial":
|
|
1354
|
+
case "active":
|
|
1355
|
+
return styleText2("cyan", S_STEP_ACTIVE);
|
|
1356
|
+
case "cancel":
|
|
1357
|
+
return styleText2("red", S_STEP_CANCEL);
|
|
1358
|
+
case "error":
|
|
1359
|
+
return styleText2("yellow", S_STEP_ERROR);
|
|
1360
|
+
case "submit":
|
|
1361
|
+
return styleText2("green", S_STEP_SUBMIT);
|
|
1362
|
+
}
|
|
1363
|
+
};
|
|
1364
|
+
var symbolBar = (o2) => {
|
|
1365
|
+
switch (o2) {
|
|
1366
|
+
case "initial":
|
|
1367
|
+
case "active":
|
|
1368
|
+
return styleText2("cyan", S_BAR);
|
|
1369
|
+
case "cancel":
|
|
1370
|
+
return styleText2("red", S_BAR);
|
|
1371
|
+
case "error":
|
|
1372
|
+
return styleText2("yellow", S_BAR);
|
|
1373
|
+
case "submit":
|
|
1374
|
+
return styleText2("green", S_BAR);
|
|
1375
|
+
}
|
|
1376
|
+
};
|
|
1377
|
+
function formatInstructionFooter(o2, e) {
|
|
1378
|
+
const r2 = [`${e ? `${styleText2("cyan", S_BAR)} ` : ""}${o2.join(" • ")}`];
|
|
1379
|
+
return e && r2.push(styleText2("cyan", S_BAR_END)), r2;
|
|
1380
|
+
}
|
|
1381
|
+
var E$1 = (l2, o2, g2, c2, h2, O = false) => {
|
|
1382
|
+
let r2 = o2, w = 0;
|
|
1383
|
+
if (O)
|
|
1384
|
+
for (let i = c2 - 1;i >= g2 && (r2 -= l2[i].length, w++, !(r2 <= h2)); i--)
|
|
1385
|
+
;
|
|
1386
|
+
else
|
|
1387
|
+
for (let i = g2;i < c2 && (r2 -= l2[i].length, w++, !(r2 <= h2)); i++)
|
|
1388
|
+
;
|
|
1389
|
+
return { lineCount: r2, removals: w };
|
|
1390
|
+
};
|
|
1391
|
+
var limitOptions = ({
|
|
1392
|
+
cursor: l2,
|
|
1393
|
+
options: o2,
|
|
1394
|
+
style: g2,
|
|
1395
|
+
output: c2 = process.stdout,
|
|
1396
|
+
maxItems: h2 = Number.POSITIVE_INFINITY,
|
|
1397
|
+
columnPadding: O = 0,
|
|
1398
|
+
rowPadding: r2 = 4
|
|
1399
|
+
}) => {
|
|
1400
|
+
const i = getColumns(c2) - O, I = getRows(c2), C2 = styleText2("dim", "..."), x = Math.max(I - r2, 0), m2 = Math.max(Math.min(h2, x), 5);
|
|
1401
|
+
let p2 = 0;
|
|
1402
|
+
l2 >= m2 - 3 && (p2 = Math.max(Math.min(l2 - m2 + 3, o2.length - m2), 0));
|
|
1403
|
+
let f2 = m2 < o2.length && p2 > 0, u3 = m2 < o2.length && p2 + m2 < o2.length;
|
|
1404
|
+
const W = Math.min(p2 + m2, o2.length), e = [];
|
|
1405
|
+
let d = 0;
|
|
1406
|
+
f2 && d++, u3 && d++;
|
|
1407
|
+
const v = p2 + (f2 ? 1 : 0), P2 = W - (u3 ? 1 : 0);
|
|
1408
|
+
for (let t2 = v;t2 < P2; t2++) {
|
|
1409
|
+
const n2 = wrapAnsi(g2(o2[t2], t2 === l2), i, {
|
|
1410
|
+
hard: true,
|
|
1411
|
+
trim: false
|
|
1412
|
+
}).split(`
|
|
1413
|
+
`);
|
|
1414
|
+
e.push(n2), d += n2.length;
|
|
1415
|
+
}
|
|
1416
|
+
if (d > x) {
|
|
1417
|
+
let t2 = 0, n2 = 0, s = d;
|
|
1418
|
+
const M2 = l2 - v;
|
|
1419
|
+
let a2 = x;
|
|
1420
|
+
const T3 = () => E$1(e, s, 0, M2, a2), L = () => E$1(e, s, M2 + 1, e.length, a2, true);
|
|
1421
|
+
f2 ? ({ lineCount: s, removals: t2 } = T3(), s > a2 && (u3 || (a2 -= 1), { lineCount: s, removals: n2 } = L())) : (u3 || (a2 -= 1), { lineCount: s, removals: n2 } = L(), s > a2 && (a2 -= 1, { lineCount: s, removals: t2 } = T3())), t2 > 0 && (f2 = true, e.splice(0, t2)), n2 > 0 && (u3 = true, e.splice(e.length - n2, n2));
|
|
1422
|
+
}
|
|
1423
|
+
const b2 = [];
|
|
1424
|
+
f2 && b2.push(C2);
|
|
1425
|
+
for (const t2 of e)
|
|
1426
|
+
for (const n2 of t2)
|
|
1427
|
+
b2.push(n2);
|
|
1428
|
+
return u3 && b2.push(C2), b2;
|
|
1429
|
+
};
|
|
1430
|
+
var confirm = (i) => {
|
|
1431
|
+
const a2 = i.active ?? "Yes", s = i.inactive ?? "No";
|
|
1432
|
+
return new r({
|
|
1433
|
+
active: a2,
|
|
1434
|
+
inactive: s,
|
|
1435
|
+
signal: i.signal,
|
|
1436
|
+
input: i.input,
|
|
1437
|
+
output: i.output,
|
|
1438
|
+
initialValue: i.initialValue ?? true,
|
|
1439
|
+
render() {
|
|
1440
|
+
const e = i.withGuide ?? settings.withGuide, u3 = `${symbol(this.state)} `, l2 = e ? `${styleText2("gray", S_BAR)} ` : "", f2 = wrapTextWithPrefix(i.output, i.message, l2, u3), o2 = `${e ? `${styleText2("gray", S_BAR)}
|
|
1441
|
+
` : ""}${f2}
|
|
1442
|
+
`, c2 = this.value ? a2 : s;
|
|
1443
|
+
switch (this.state) {
|
|
1444
|
+
case "submit": {
|
|
1445
|
+
const r2 = e ? `${styleText2("gray", S_BAR)} ` : "";
|
|
1446
|
+
return `${o2}${r2}${styleText2("dim", c2)}`;
|
|
1447
|
+
}
|
|
1448
|
+
case "cancel": {
|
|
1449
|
+
const r2 = e ? `${styleText2("gray", S_BAR)} ` : "";
|
|
1450
|
+
return `${o2}${r2}${styleText2(["strikethrough", "dim"], c2)}${e ? `
|
|
1451
|
+
${styleText2("gray", S_BAR)}` : ""}`;
|
|
1452
|
+
}
|
|
1453
|
+
default: {
|
|
1454
|
+
const r2 = e ? `${styleText2("cyan", S_BAR)} ` : "", g2 = e ? styleText2("cyan", S_BAR_END) : "";
|
|
1455
|
+
return `${o2}${r2}${this.value ? `${styleText2("green", S_RADIO_ACTIVE)} ${a2}` : `${styleText2("dim", S_RADIO_INACTIVE)} ${styleText2("dim", a2)}`}${i.vertical ? e ? `
|
|
1456
|
+
${styleText2("cyan", S_BAR)} ` : `
|
|
1457
|
+
` : ` ${styleText2("dim", "/")} `}${this.value ? `${styleText2("dim", S_RADIO_INACTIVE)} ${styleText2("dim", s)}` : `${styleText2("green", S_RADIO_ACTIVE)} ${s}`}
|
|
1458
|
+
${g2}
|
|
1459
|
+
`;
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
}).prompt();
|
|
1464
|
+
};
|
|
1465
|
+
var MULTISELECT_INSTRUCTIONS = [
|
|
1466
|
+
`${styleText2("dim", "↑/↓")} to navigate`,
|
|
1467
|
+
`${styleText2("dim", "Space:")} select`,
|
|
1468
|
+
`${styleText2("dim", "Enter:")} confirm`
|
|
1469
|
+
];
|
|
1470
|
+
var cancel = (o2 = "", t2) => {
|
|
1471
|
+
const i = t2?.output ?? process.stdout, e = t2?.withGuide ?? settings.withGuide ? `${styleText2("gray", S_BAR_END)} ` : "";
|
|
1472
|
+
i.write(`${e}${styleText2("red", o2)}
|
|
1473
|
+
|
|
1474
|
+
`);
|
|
1475
|
+
};
|
|
1476
|
+
var intro = (o2 = "", t2) => {
|
|
1477
|
+
const i = t2?.output ?? process.stdout, e = t2?.withGuide ?? settings.withGuide ? `${styleText2("gray", S_BAR_START)} ` : "";
|
|
1478
|
+
i.write(`${e}${o2}
|
|
1479
|
+
`);
|
|
1480
|
+
};
|
|
1481
|
+
var outro = (o2 = "", t2) => {
|
|
1482
|
+
const i = t2?.output ?? process.stdout, e = t2?.withGuide ?? settings.withGuide ? `${styleText2("gray", S_BAR)}
|
|
1483
|
+
${styleText2("gray", S_BAR_END)} ` : "";
|
|
1484
|
+
i.write(`${e}${o2}
|
|
1485
|
+
|
|
1486
|
+
`);
|
|
1487
|
+
};
|
|
1488
|
+
var W$1 = (o2) => o2;
|
|
1489
|
+
var C2 = (o2, e, s) => {
|
|
1490
|
+
const a2 = {
|
|
1491
|
+
hard: true,
|
|
1492
|
+
trim: false
|
|
1493
|
+
}, i = wrapAnsi(o2, e, a2).split(`
|
|
1494
|
+
`), c2 = i.reduce((n2, t2) => Math.max(dist_default2(t2), n2), 0), u3 = i.map(s).reduce((n2, t2) => Math.max(dist_default2(t2), n2), 0), g2 = e - (u3 - c2);
|
|
1495
|
+
return wrapAnsi(o2, g2, a2);
|
|
1496
|
+
};
|
|
1497
|
+
var note = (o2 = "", e = "", s) => {
|
|
1498
|
+
const a2 = s?.output ?? process$1.stdout, i = s?.withGuide ?? settings.withGuide, c2 = s?.format ?? W$1, g2 = ["", ...C2(o2, getColumns(a2) - 6, c2).split(`
|
|
1499
|
+
`).map(c2), ""], n2 = dist_default2(e), t2 = Math.max(g2.reduce((m2, F) => {
|
|
1500
|
+
const O = dist_default2(F);
|
|
1501
|
+
return O > m2 ? O : m2;
|
|
1502
|
+
}, 0), n2) + 2, h2 = g2.map((m2) => `${styleText2("gray", S_BAR)} ${m2}${" ".repeat(t2 - dist_default2(m2))}${styleText2("gray", S_BAR)}`).join(`
|
|
1503
|
+
`), T3 = i ? `${styleText2("gray", S_BAR)}
|
|
1504
|
+
` : "", l$1 = i ? S_CONNECT_LEFT : S_CORNER_BOTTOM_LEFT;
|
|
1505
|
+
a2.write(`${T3}${styleText2("green", S_STEP_SUBMIT)} ${styleText2("reset", e)} ${styleText2("gray", S_BAR_H.repeat(Math.max(t2 - n2 - 1, 1)) + S_CORNER_TOP_RIGHT)}
|
|
1506
|
+
${h2}
|
|
1507
|
+
${styleText2("gray", l$1 + S_BAR_H.repeat(t2 + 2) + S_CORNER_BOTTOM_RIGHT)}
|
|
1508
|
+
`);
|
|
1509
|
+
};
|
|
1510
|
+
var W = (l2) => styleText2("magenta", l2);
|
|
1511
|
+
var spinner = ({
|
|
1512
|
+
indicator: l2 = "dots",
|
|
1513
|
+
onCancel: h2,
|
|
1514
|
+
output: n2 = process.stdout,
|
|
1515
|
+
cancelMessage: G,
|
|
1516
|
+
errorMessage: O,
|
|
1517
|
+
frames: E = unicode ? ["◒", "◐", "◓", "◑"] : ["•", "o", "O", "0"],
|
|
1518
|
+
delay: F = unicode ? 80 : 120,
|
|
1519
|
+
signal: m2,
|
|
1520
|
+
...I
|
|
1521
|
+
} = {}) => {
|
|
1522
|
+
const u3 = isCI();
|
|
1523
|
+
let M2, T3, d = false, S = false, s = "", p2, w = performance.now();
|
|
1524
|
+
const x = getColumns(n2), k = I?.styleFrame ?? W, g2 = (e) => {
|
|
1525
|
+
const r2 = e > 1 ? O ?? settings.messages.error : G ?? settings.messages.cancel;
|
|
1526
|
+
S = e === 1, d && (a2(r2, e), S && typeof h2 == "function" && h2());
|
|
1527
|
+
}, f2 = () => g2(2), i = () => g2(1), A = () => {
|
|
1528
|
+
process.on("uncaughtExceptionMonitor", f2), process.on("unhandledRejection", f2), process.on("SIGINT", i), process.on("SIGTERM", i), process.on("exit", g2), m2 && m2.addEventListener("abort", i);
|
|
1529
|
+
}, H = () => {
|
|
1530
|
+
process.removeListener("uncaughtExceptionMonitor", f2), process.removeListener("unhandledRejection", f2), process.removeListener("SIGINT", i), process.removeListener("SIGTERM", i), process.removeListener("exit", g2), m2 && m2.removeEventListener("abort", i);
|
|
1531
|
+
}, y = () => {
|
|
1532
|
+
if (p2 === undefined)
|
|
1533
|
+
return;
|
|
1534
|
+
u3 && n2.write(`
|
|
1535
|
+
`);
|
|
1536
|
+
const r2 = wrapAnsi(p2, x, {
|
|
1537
|
+
hard: true,
|
|
1538
|
+
trim: false
|
|
1539
|
+
}).split(`
|
|
1540
|
+
`);
|
|
1541
|
+
r2.length > 1 && n2.write(import_sisteransi2.cursor.up(r2.length - 1)), n2.write(import_sisteransi2.cursor.to(0)), n2.write(import_sisteransi2.erase.down());
|
|
1542
|
+
}, C3 = (e) => e.replace(/\.+$/, ""), _2 = (e) => {
|
|
1543
|
+
const r2 = (performance.now() - e) / 1000, t2 = Math.floor(r2 / 60), o2 = Math.floor(r2 % 60);
|
|
1544
|
+
return t2 > 0 ? `[${t2}m ${o2}s]` : `[${o2}s]`;
|
|
1545
|
+
}, N = I.withGuide ?? settings.withGuide, P2 = (e = "") => {
|
|
1546
|
+
d = true, M2 = block({ output: n2 }), s = C3(e), w = performance.now(), N && n2.write(`${styleText2("gray", S_BAR)}
|
|
1547
|
+
`);
|
|
1548
|
+
let r2 = 0, t2 = 0;
|
|
1549
|
+
A(), T3 = setInterval(() => {
|
|
1550
|
+
if (u3 && s === p2)
|
|
1551
|
+
return;
|
|
1552
|
+
y(), p2 = s;
|
|
1553
|
+
const o2 = k(E[r2]);
|
|
1554
|
+
let v;
|
|
1555
|
+
if (u3)
|
|
1556
|
+
v = `${o2} ${s}...`;
|
|
1557
|
+
else if (l2 === "timer")
|
|
1558
|
+
v = `${o2} ${s} ${_2(w)}`;
|
|
1559
|
+
else {
|
|
1560
|
+
const B = ".".repeat(Math.floor(t2)).slice(0, 3);
|
|
1561
|
+
v = `${o2} ${s}${B}`;
|
|
1562
|
+
}
|
|
1563
|
+
const j = wrapAnsi(v, x, {
|
|
1564
|
+
hard: true,
|
|
1565
|
+
trim: false
|
|
1566
|
+
});
|
|
1567
|
+
n2.write(j), r2 = r2 + 1 < E.length ? r2 + 1 : 0, t2 = t2 < 4 ? t2 + 0.125 : 0;
|
|
1568
|
+
}, F);
|
|
1569
|
+
}, a2 = (e = "", r2 = 0, t2 = false) => {
|
|
1570
|
+
if (!d)
|
|
1571
|
+
return;
|
|
1572
|
+
d = false, clearInterval(T3), y();
|
|
1573
|
+
const o2 = r2 === 0 ? styleText2("green", S_STEP_SUBMIT) : r2 === 1 ? styleText2("red", S_STEP_CANCEL) : styleText2("red", S_STEP_ERROR);
|
|
1574
|
+
s = e ?? s, t2 || (l2 === "timer" ? n2.write(`${o2} ${s} ${_2(w)}
|
|
1575
|
+
`) : n2.write(`${o2} ${s}
|
|
1576
|
+
`)), H(), M2();
|
|
1577
|
+
};
|
|
1578
|
+
return {
|
|
1579
|
+
start: P2,
|
|
1580
|
+
stop: (e = "") => a2(e, 0),
|
|
1581
|
+
message: (e = "") => {
|
|
1582
|
+
s = C3(e ?? s);
|
|
1583
|
+
},
|
|
1584
|
+
cancel: (e = "") => a2(e, 1),
|
|
1585
|
+
error: (e = "") => a2(e, 2),
|
|
1586
|
+
clear: () => a2("", 0, true),
|
|
1587
|
+
get isCancelled() {
|
|
1588
|
+
return S;
|
|
1589
|
+
}
|
|
1590
|
+
};
|
|
1591
|
+
};
|
|
1592
|
+
var u3 = {
|
|
1593
|
+
light: unicodeOr("─", "-"),
|
|
1594
|
+
heavy: unicodeOr("━", "="),
|
|
1595
|
+
block: unicodeOr("█", "#")
|
|
1596
|
+
};
|
|
1597
|
+
var SELECT_INSTRUCTIONS = [
|
|
1598
|
+
`${styleText2("dim", "↑/↓")} to navigate`,
|
|
1599
|
+
`${styleText2("dim", "Enter:")} confirm`
|
|
1600
|
+
];
|
|
1601
|
+
var c2 = (t2, a2) => t2.includes(`
|
|
1602
|
+
`) ? t2.split(`
|
|
1603
|
+
`).map((i) => a2(i)).join(`
|
|
1604
|
+
`) : a2(t2);
|
|
1605
|
+
var select = (t2) => {
|
|
1606
|
+
const a2 = (i, m2) => {
|
|
1607
|
+
const s = i.label ?? String(i.value);
|
|
1608
|
+
switch (m2) {
|
|
1609
|
+
case "disabled":
|
|
1610
|
+
return `${styleText2("gray", S_RADIO_INACTIVE)} ${c2(s, (n2) => styleText2("gray", n2))}${i.hint ? ` ${styleText2("dim", `(${i.hint ?? "disabled"})`)}` : ""}`;
|
|
1611
|
+
case "selected":
|
|
1612
|
+
return `${c2(s, (n2) => styleText2("dim", n2))}`;
|
|
1613
|
+
case "active":
|
|
1614
|
+
return `${styleText2("green", S_RADIO_ACTIVE)} ${s}${i.hint ? ` ${styleText2("dim", `(${i.hint})`)}` : ""}`;
|
|
1615
|
+
case "cancelled":
|
|
1616
|
+
return `${c2(s, (n2) => styleText2(["strikethrough", "dim"], n2))}`;
|
|
1617
|
+
default:
|
|
1618
|
+
return `${styleText2("dim", S_RADIO_INACTIVE)} ${c2(s, (n2) => styleText2("dim", n2))}`;
|
|
1619
|
+
}
|
|
1620
|
+
};
|
|
1621
|
+
return new a({
|
|
1622
|
+
options: t2.options,
|
|
1623
|
+
signal: t2.signal,
|
|
1624
|
+
input: t2.input,
|
|
1625
|
+
output: t2.output,
|
|
1626
|
+
initialValue: t2.initialValue,
|
|
1627
|
+
render() {
|
|
1628
|
+
const i = t2.withGuide ?? settings.withGuide, m2 = `${symbol(this.state)} `, s = `${symbolBar(this.state)} `, n2 = wrapTextWithPrefix(t2.output, t2.message, s, m2), u4 = `${i ? `${styleText2("gray", S_BAR)}
|
|
1629
|
+
` : ""}${n2}
|
|
1630
|
+
`;
|
|
1631
|
+
switch (this.state) {
|
|
1632
|
+
case "submit": {
|
|
1633
|
+
const r2 = i ? `${styleText2("gray", S_BAR)} ` : "", o2 = wrapTextWithPrefix(t2.output, a2(this.options[this.cursor], "selected"), r2);
|
|
1634
|
+
return `${u4}${o2}`;
|
|
1635
|
+
}
|
|
1636
|
+
case "cancel": {
|
|
1637
|
+
const r2 = i ? `${styleText2("gray", S_BAR)} ` : "", o2 = wrapTextWithPrefix(t2.output, a2(this.options[this.cursor], "cancelled"), r2);
|
|
1638
|
+
return `${u4}${o2}${i ? `
|
|
1639
|
+
${styleText2("gray", S_BAR)}` : ""}`;
|
|
1640
|
+
}
|
|
1641
|
+
default: {
|
|
1642
|
+
const r2 = i ? `${styleText2("cyan", S_BAR)} ` : "", o2 = u4.split(`
|
|
1643
|
+
`).length, $ = formatInstructionFooter(SELECT_INSTRUCTIONS, i), h2 = $.join(`
|
|
1644
|
+
`), b2 = $.length + 1;
|
|
1645
|
+
return `${u4}${r2}${limitOptions({
|
|
1646
|
+
output: t2.output,
|
|
1647
|
+
cursor: this.cursor,
|
|
1648
|
+
options: this.options,
|
|
1649
|
+
maxItems: t2.maxItems,
|
|
1650
|
+
columnPadding: r2.length,
|
|
1651
|
+
rowPadding: o2 + b2,
|
|
1652
|
+
style: (p2, x) => a2(p2, p2.disabled ? "disabled" : x ? "active" : "inactive")
|
|
1653
|
+
}).join(`
|
|
1654
|
+
${r2}`)}
|
|
1655
|
+
${h2}
|
|
1656
|
+
`;
|
|
1657
|
+
}
|
|
1658
|
+
}
|
|
1659
|
+
}
|
|
1660
|
+
}).prompt();
|
|
1661
|
+
};
|
|
1662
|
+
var i = `${styleText2("gray", S_BAR)} `;
|
|
1663
|
+
var text = (t2) => new n({
|
|
1664
|
+
validate: t2.validate,
|
|
1665
|
+
placeholder: t2.placeholder,
|
|
1666
|
+
defaultValue: t2.defaultValue,
|
|
1667
|
+
initialValue: t2.initialValue,
|
|
1668
|
+
output: t2.output,
|
|
1669
|
+
signal: t2.signal,
|
|
1670
|
+
input: t2.input,
|
|
1671
|
+
render() {
|
|
1672
|
+
const i2 = t2?.withGuide ?? settings.withGuide, s = `${`${i2 ? `${styleText2("gray", S_BAR)}
|
|
1673
|
+
` : ""}${symbol(this.state)} `}${t2.message}
|
|
1674
|
+
`, c3 = t2.placeholder ? styleText2("inverse", t2.placeholder[0]) + styleText2("dim", t2.placeholder.slice(1)) : styleText2(["inverse", "hidden"], "_"), o2 = this.userInput ? this.userInputWithCursor : c3, a2 = this.value ?? "";
|
|
1675
|
+
switch (this.state) {
|
|
1676
|
+
case "error": {
|
|
1677
|
+
const n2 = this.error ? ` ${styleText2("yellow", this.error)}` : "", r2 = i2 ? `${styleText2("yellow", S_BAR)} ` : "", d = i2 ? styleText2("yellow", S_BAR_END) : "";
|
|
1678
|
+
return `${s.trim()}
|
|
1679
|
+
${r2}${o2}
|
|
1680
|
+
${d}${n2}
|
|
1681
|
+
`;
|
|
1682
|
+
}
|
|
1683
|
+
case "submit": {
|
|
1684
|
+
const n2 = a2 ? ` ${styleText2("dim", a2)}` : "", r2 = i2 ? styleText2("gray", S_BAR) : "";
|
|
1685
|
+
return `${s}${r2}${n2}`;
|
|
1686
|
+
}
|
|
1687
|
+
case "cancel": {
|
|
1688
|
+
const n2 = a2 ? ` ${styleText2(["strikethrough", "dim"], a2)}` : "", r2 = i2 ? styleText2("gray", S_BAR) : "";
|
|
1689
|
+
return `${s}${r2}${n2}${a2.trim() ? `
|
|
1690
|
+
${r2}` : ""}`;
|
|
1691
|
+
}
|
|
1692
|
+
default: {
|
|
1693
|
+
const n2 = i2 ? `${styleText2("cyan", S_BAR)} ` : "", r2 = i2 ? styleText2("cyan", S_BAR_END) : "";
|
|
1694
|
+
return `${s}${n2}${o2}
|
|
1695
|
+
${r2}
|
|
1696
|
+
`;
|
|
1697
|
+
}
|
|
1698
|
+
}
|
|
1699
|
+
}
|
|
1700
|
+
}).prompt();
|
|
1701
|
+
|
|
1702
|
+
// src/cli.ts
|
|
1703
|
+
var import_picocolors = __toESM(require_picocolors(), 1);
|
|
1704
|
+
|
|
1705
|
+
// src/git.ts
|
|
1706
|
+
import { spawnSync } from "child_process";
|
|
1707
|
+
function runGitCommand(args, cwd) {
|
|
1708
|
+
const proc = spawnSync("git", ["-C", cwd, ...args], { encoding: "utf-8" });
|
|
1709
|
+
if (proc.status !== 0) {
|
|
1710
|
+
throw new Error("Git command failed");
|
|
1711
|
+
}
|
|
1712
|
+
const text2 = proc.stdout || "";
|
|
1713
|
+
const lines = text2.trim().split(`
|
|
1714
|
+
`).filter((l2) => l2.length > 0);
|
|
1715
|
+
return lines.length;
|
|
1716
|
+
}
|
|
1717
|
+
async function checkIsGitRepo(cwd) {
|
|
1718
|
+
const proc = spawnSync("git", ["-C", cwd, "rev-parse", "--is-inside-work-tree"], { encoding: "utf-8" });
|
|
1719
|
+
return proc.status === 0;
|
|
1720
|
+
}
|
|
1721
|
+
async function getAuthorshipStats(repoPath = process.cwd()) {
|
|
1722
|
+
const isRepo = await checkIsGitRepo(repoPath);
|
|
1723
|
+
if (!isRepo) {
|
|
1724
|
+
throw new Error(`Directory is not a git repository: ${repoPath}`);
|
|
1725
|
+
}
|
|
1726
|
+
const total = runGitCommand(["log", "--oneline"], repoPath);
|
|
1727
|
+
const ai = runGitCommand(["log", "-i", "--grep=Co-Authored-By", "--oneline"], repoPath);
|
|
1728
|
+
const totalNoMerges = runGitCommand(["log", "--no-merges", "--oneline"], repoPath);
|
|
1729
|
+
const aiNoMerges = runGitCommand(["log", "--no-merges", "-i", "--grep=Co-Authored-By", "--oneline"], repoPath);
|
|
1730
|
+
return {
|
|
1731
|
+
total,
|
|
1732
|
+
ai,
|
|
1733
|
+
ratio: total === 0 ? 0 : ai / total,
|
|
1734
|
+
totalNoMerges,
|
|
1735
|
+
aiNoMerges,
|
|
1736
|
+
ratioNoMerges: totalNoMerges === 0 ? 0 : aiNoMerges / totalNoMerges
|
|
1737
|
+
};
|
|
1738
|
+
}
|
|
1739
|
+
|
|
1740
|
+
// src/carbon.ts
|
|
1741
|
+
import { homedir } from "os";
|
|
1742
|
+
import { join } from "path";
|
|
1743
|
+
import { readFile, access } from "fs/promises";
|
|
1744
|
+
// data/grid-factors.json
|
|
1745
|
+
var grid_factors_default = {
|
|
1746
|
+
vietnam: 681,
|
|
1747
|
+
france: 21.7,
|
|
1748
|
+
us_east: 380,
|
|
1749
|
+
singapore: 408,
|
|
1750
|
+
india_average: 715
|
|
1751
|
+
};
|
|
1752
|
+
|
|
1753
|
+
// src/carbon.ts
|
|
1754
|
+
class ClaudeLogParser {
|
|
1755
|
+
baseDir;
|
|
1756
|
+
constructor(baseDir = homedir()) {
|
|
1757
|
+
this.baseDir = baseDir;
|
|
1758
|
+
}
|
|
1759
|
+
async parse() {
|
|
1760
|
+
const logPath = join(this.baseDir, ".claude", "tokenomics-log.jsonl");
|
|
1761
|
+
try {
|
|
1762
|
+
await access(logPath);
|
|
1763
|
+
} catch {
|
|
1764
|
+
return { total: 0, output: 0, cache: 0, sessions: 0 };
|
|
1765
|
+
}
|
|
1766
|
+
const text2 = await readFile(logPath, "utf-8");
|
|
1767
|
+
const lines = text2.trim().split(`
|
|
1768
|
+
`).filter((l2) => l2.length > 0);
|
|
1769
|
+
let total = 0, output = 0, cache = 0;
|
|
1770
|
+
const sessions = new Set;
|
|
1771
|
+
for (const line of lines) {
|
|
1772
|
+
try {
|
|
1773
|
+
const data = JSON.parse(line);
|
|
1774
|
+
total += data.total_tokens || 0;
|
|
1775
|
+
output += data.output_tokens || 0;
|
|
1776
|
+
cache += data.cache_read || 0;
|
|
1777
|
+
if (data.session_id)
|
|
1778
|
+
sessions.add(data.session_id);
|
|
1779
|
+
} catch (e) {}
|
|
1780
|
+
}
|
|
1781
|
+
return { total, output, cache, sessions: sessions.size };
|
|
1782
|
+
}
|
|
1783
|
+
}
|
|
1784
|
+
|
|
1785
|
+
class CursorLogParser {
|
|
1786
|
+
async parse() {
|
|
1787
|
+
return { total: 0, output: 0, cache: 0, sessions: 0 };
|
|
1788
|
+
}
|
|
1789
|
+
}
|
|
1790
|
+
function getLocalGridFactor() {
|
|
1791
|
+
try {
|
|
1792
|
+
const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
1793
|
+
if (tz.includes("Ho_Chi_Minh") || tz.includes("Bangkok") || tz.includes("Jakarta") || tz.includes("Asia/Manila"))
|
|
1794
|
+
return { region: "Vietnam/SEA", factor: grid_factors_default.vietnam };
|
|
1795
|
+
if (tz.includes("Paris") || tz.includes("Europe/"))
|
|
1796
|
+
return { region: "France/EU", factor: grid_factors_default.france };
|
|
1797
|
+
if (tz.includes("New_York") || tz.includes("America/"))
|
|
1798
|
+
return { region: "US", factor: grid_factors_default.us_east };
|
|
1799
|
+
if (tz.includes("Singapore"))
|
|
1800
|
+
return { region: "Singapore", factor: grid_factors_default.singapore };
|
|
1801
|
+
if (tz.includes("Calcutta") || tz.includes("Kolkata") || tz.includes("Asia/Kabul"))
|
|
1802
|
+
return { region: "India", factor: grid_factors_default.india_average };
|
|
1803
|
+
} catch (e) {}
|
|
1804
|
+
return { region: "Global Average", factor: 450 };
|
|
1805
|
+
}
|
|
1806
|
+
async function getCarbonStats() {
|
|
1807
|
+
const parsers = [new ClaudeLogParser, new CursorLogParser];
|
|
1808
|
+
let totalTokens = 0, outputTokens = 0, cacheReadTokens = 0, sessions = 0;
|
|
1809
|
+
for (const parser of parsers) {
|
|
1810
|
+
const stats = await parser.parse();
|
|
1811
|
+
totalTokens += stats.total;
|
|
1812
|
+
outputTokens += stats.output;
|
|
1813
|
+
cacheReadTokens += stats.cache;
|
|
1814
|
+
sessions += stats.sessions;
|
|
1815
|
+
}
|
|
1816
|
+
const energyKwh = outputTokens / 1e6 * 0.662;
|
|
1817
|
+
const localGrid = getLocalGridFactor();
|
|
1818
|
+
return {
|
|
1819
|
+
totalTokens,
|
|
1820
|
+
outputTokens,
|
|
1821
|
+
cacheReadTokens,
|
|
1822
|
+
energyKwh,
|
|
1823
|
+
co2KgVietnam: energyKwh * grid_factors_default.vietnam / 1000,
|
|
1824
|
+
co2KgFrance: energyKwh * grid_factors_default.france / 1000,
|
|
1825
|
+
localCo2Kg: energyKwh * localGrid.factor / 1000,
|
|
1826
|
+
localRegion: localGrid.region,
|
|
1827
|
+
sessions
|
|
1828
|
+
};
|
|
1829
|
+
}
|
|
1830
|
+
|
|
1831
|
+
// src/capabilities.ts
|
|
1832
|
+
import { homedir as homedir2 } from "os";
|
|
1833
|
+
import { join as join2 } from "path";
|
|
1834
|
+
import { existsSync, readdirSync } from "fs";
|
|
1835
|
+
async function getCapabilitiesStats(repoPath = process.cwd(), homeDirPath = homedir2()) {
|
|
1836
|
+
const stats = {
|
|
1837
|
+
mcps: [],
|
|
1838
|
+
skills: [],
|
|
1839
|
+
hasOrchestration: false
|
|
1840
|
+
};
|
|
1841
|
+
if (existsSync(join2(repoPath, "AGENTS.md"))) {
|
|
1842
|
+
stats.hasOrchestration = true;
|
|
1843
|
+
}
|
|
1844
|
+
const projectSkillsPath = join2(repoPath, ".agents", "skills");
|
|
1845
|
+
if (existsSync(projectSkillsPath)) {
|
|
1846
|
+
try {
|
|
1847
|
+
const skills = readdirSync(projectSkillsPath, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
|
|
1848
|
+
stats.skills.push(...skills);
|
|
1849
|
+
} catch (e) {}
|
|
1850
|
+
}
|
|
1851
|
+
const geminiSkillsPath = join2(homeDirPath, ".gemini", "skills");
|
|
1852
|
+
if (existsSync(geminiSkillsPath)) {
|
|
1853
|
+
try {
|
|
1854
|
+
const skills = readdirSync(geminiSkillsPath, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
|
|
1855
|
+
for (const skill of skills) {
|
|
1856
|
+
if (!stats.skills.includes(skill))
|
|
1857
|
+
stats.skills.push(skill);
|
|
1858
|
+
}
|
|
1859
|
+
} catch (e) {}
|
|
1860
|
+
}
|
|
1861
|
+
const geminiMcpPath = join2(homeDirPath, ".gemini", "antigravity-cli", "mcp");
|
|
1862
|
+
if (existsSync(geminiMcpPath)) {
|
|
1863
|
+
try {
|
|
1864
|
+
const mcps = readdirSync(geminiMcpPath, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
|
|
1865
|
+
stats.mcps.push(...mcps);
|
|
1866
|
+
} catch (e) {}
|
|
1867
|
+
}
|
|
1868
|
+
const claudeSettingsPath = join2(homeDirPath, ".claude", "settings.json");
|
|
1869
|
+
if (existsSync(claudeSettingsPath)) {
|
|
1870
|
+
try {
|
|
1871
|
+
const claudeSettings = __require(claudeSettingsPath);
|
|
1872
|
+
if (claudeSettings.enabledPlugins) {
|
|
1873
|
+
Object.keys(claudeSettings.enabledPlugins).forEach((plugin) => {
|
|
1874
|
+
if (claudeSettings.enabledPlugins[plugin] && !stats.mcps.includes(plugin)) {
|
|
1875
|
+
stats.mcps.push(`plugin:${plugin}`);
|
|
1876
|
+
}
|
|
1877
|
+
});
|
|
1878
|
+
}
|
|
1879
|
+
} catch (e) {}
|
|
1880
|
+
}
|
|
1881
|
+
return stats;
|
|
1882
|
+
}
|
|
1883
|
+
|
|
1884
|
+
// src/cli.ts
|
|
1885
|
+
import { writeFileSync, chmodSync, existsSync as existsSync2 } from "fs";
|
|
1886
|
+
import { join as join3 } from "path";
|
|
1887
|
+
import os from "os";
|
|
1888
|
+
var ASCII_LOGO = `
|
|
1889
|
+
____ _ _ _____ _ ___ _____ ____
|
|
1890
|
+
/ __ \\| | | |_ _| | |_ _| ___| _ \\
|
|
1891
|
+
| | | | | | | | | | | | || |__ | |_) |
|
|
1892
|
+
| | | | |_| | | | | |___ | || __|| _ <
|
|
1893
|
+
| |__| | _ | | | | _ || || |___| | \\ \\
|
|
1894
|
+
\\____/|_| |_| |_| |_| |_|___|_____|_| \\_\\
|
|
1895
|
+
`;
|
|
1896
|
+
async function runOnboarding() {
|
|
1897
|
+
console.clear();
|
|
1898
|
+
console.log(import_picocolors.default.cyan(ASCII_LOGO));
|
|
1899
|
+
intro(import_picocolors.default.inverse(" outlier: Welcome "));
|
|
1900
|
+
note(`Outlier is a local-first Policy Engine & Governance Framework for AI Engineering.
|
|
1901
|
+
|
|
1902
|
+
Our mission is AI Safety for developers:
|
|
1903
|
+
As agents (Cursor, Copilot, Claude) write more of our code, we lose visibility into:
|
|
1904
|
+
1. Deskilling Risk (Are we becoming spectators in our own codebase?)
|
|
1905
|
+
2. Carbon Cost (What is the true regional energy cost of token caching?)
|
|
1906
|
+
3. Capability Drift (What hidden skills and external tools are our agents using?)
|
|
1907
|
+
|
|
1908
|
+
We built Outlier to enforce Zero-Trust and protect Human Mastery. You are in control.`, "The Problem: AI Safety in Development");
|
|
1909
|
+
note(`Outlier operates entirely on your machine.
|
|
1910
|
+
- Local Only: No API keys. No cloud telemetry. No data leaves your machine.
|
|
1911
|
+
- Native Auditing: We only read your local \`~/.claude\` logs and \`.git/\` commit history.
|
|
1912
|
+
- Actionable Policies: We enforce rules locally via terminal or Git pre-commit hooks.`, "Privacy & Zero-Trust Principles");
|
|
1913
|
+
note(`Available Commands:
|
|
1914
|
+
- status: Run a full system audit (Reliance, Carbon, Capabilities)
|
|
1915
|
+
- policy: Configure team/enterprise guardrails and CLI blockers
|
|
1916
|
+
- carbon: View isolated token caching metrics and regional counterfactuals
|
|
1917
|
+
- authorship: View Git authorship ratio (Human vs AI)`, "How it is used");
|
|
1918
|
+
note(`When you start the audit, Outlier will locally parse your Git commits to identify AI co-authorship and cross-reference your agent logs to calculate token waste.
|
|
1919
|
+
|
|
1920
|
+
The results will assign you a "vibe" and evaluate if you are at risk of deskilling.`, "What to Expect");
|
|
1921
|
+
const ready = await confirm({
|
|
1922
|
+
message: "Are you ready to run your first Governance Audit and measure your AI reliance?",
|
|
1923
|
+
initialValue: true
|
|
1924
|
+
});
|
|
1925
|
+
if (isCancel(ready) || !ready) {
|
|
1926
|
+
cancel("Onboarding paused. Run outlier again when you are ready.");
|
|
1927
|
+
process.exit(0);
|
|
1928
|
+
}
|
|
1929
|
+
const configPath = join3(os.homedir(), ".outlier_config");
|
|
1930
|
+
writeFileSync(configPath, JSON.stringify({ onboarded: true, date: new Date().toISOString() }));
|
|
1931
|
+
}
|
|
1932
|
+
async function main() {
|
|
1933
|
+
console.clear();
|
|
1934
|
+
console.log(import_picocolors.default.cyan(ASCII_LOGO));
|
|
1935
|
+
console.log(import_picocolors.default.dim(` Outlier v0.4.1 · AI Code Reliance & Telemetry Engine
|
|
1936
|
+
`));
|
|
1937
|
+
let action = process.argv[2];
|
|
1938
|
+
if (action === "--help" || action === "-h" || action === "help") {
|
|
1939
|
+
console.log(import_picocolors.default.bold(`
|
|
1940
|
+
COMMANDS:`));
|
|
1941
|
+
console.log(` ${import_picocolors.default.cyan("outlier")} Interactive menu (Onboarding for first-timers)`);
|
|
1942
|
+
console.log(` ${import_picocolors.default.cyan("outlier status")} Run full AI reliance & capability audit`);
|
|
1943
|
+
console.log(` ${import_picocolors.default.cyan("outlier authorship")} Scan git history for AI co-authorship ratio`);
|
|
1944
|
+
console.log(` ${import_picocolors.default.cyan("outlier carbon")} Scan local logs for token waste & carbon cost`);
|
|
1945
|
+
console.log(` ${import_picocolors.default.cyan("outlier policy")} Configure CI/CD guardrails and thresholds`);
|
|
1946
|
+
console.log(` ${import_picocolors.default.cyan("outlier impact")} See the compounding horizon of AI Deskilling`);
|
|
1947
|
+
console.log(` ${import_picocolors.default.cyan("outlier knowledge")} Explore references, graphs, and the core literature`);
|
|
1948
|
+
console.log(` ${import_picocolors.default.cyan("outlier participate")} Help build the academic literature on AI deskilling`);
|
|
1949
|
+
console.log(`
|
|
1950
|
+
` + import_picocolors.default.dim("Run without arguments to start the interactive wizard."));
|
|
1951
|
+
process.exit(0);
|
|
1952
|
+
}
|
|
1953
|
+
const configPath = join3(os.homedir(), ".outlier_config");
|
|
1954
|
+
if (!existsSync2(configPath) && !action) {
|
|
1955
|
+
await runOnboarding();
|
|
1956
|
+
action = "status";
|
|
1957
|
+
}
|
|
1958
|
+
intro(import_picocolors.default.inverse(" outlier "));
|
|
1959
|
+
if (!action || action === "audit") {
|
|
1960
|
+
if (action !== "audit") {
|
|
1961
|
+
action = await select({
|
|
1962
|
+
message: "Select outlier governance module:",
|
|
1963
|
+
options: [
|
|
1964
|
+
{ value: "status", label: "Status Report", hint: "Run full AI reliance and capability audit" },
|
|
1965
|
+
{ value: "capabilities", label: "Capabilities Map", hint: "Audit active MCPs, skills, and orchestrations" },
|
|
1966
|
+
{ value: "authorship", label: "Code Durability", hint: "Scan git history for AI Code Reliance & Hallucination Risk" },
|
|
1967
|
+
{ value: "carbon", label: "Cache Bloat", hint: "Scan local logs for context waste & token costs" },
|
|
1968
|
+
{ value: "policy", label: "Policy Profiles", hint: "Set Personal, Team, or Enterprise guardrails in CI" },
|
|
1969
|
+
{ value: "impact", label: "Impact Horizon", hint: "What do you lose and gain in the next 5-10 years?" },
|
|
1970
|
+
{ value: "knowledge", label: "Literature Base", hint: "Explore references and the core academic foundation" },
|
|
1971
|
+
{ value: "participate", label: "Participate", hint: "Contribute to the literature on AI deskilling" }
|
|
1972
|
+
]
|
|
1973
|
+
});
|
|
1974
|
+
if (isCancel(action)) {
|
|
1975
|
+
cancel("Operation cancelled.");
|
|
1976
|
+
process.exit(0);
|
|
1977
|
+
}
|
|
1978
|
+
} else {
|
|
1979
|
+
action = "status";
|
|
1980
|
+
}
|
|
1981
|
+
}
|
|
1982
|
+
const s = spinner();
|
|
1983
|
+
if (action === "carbon") {
|
|
1984
|
+
s.start("Scanning local agent session logs...");
|
|
1985
|
+
try {
|
|
1986
|
+
const carbon = await getCarbonStats();
|
|
1987
|
+
s.stop("Audit complete");
|
|
1988
|
+
note(`Sessions: ${carbon.sessions}
|
|
1989
|
+
Output Tokens: ${(carbon.outputTokens / 1e6).toFixed(2)}M
|
|
1990
|
+
Est. Energy: ${carbon.energyKwh.toFixed(2)} kWh
|
|
1991
|
+
|
|
1992
|
+
Your Local Grid (${carbon.localRegion}): ${import_picocolors.default.cyan(carbon.localCo2Kg.toFixed(2) + " kgCO2")}
|
|
1993
|
+
|
|
1994
|
+
Counterfactual (Vietnam): ${import_picocolors.default.red(carbon.co2KgVietnam.toFixed(2) + " kgCO2")}
|
|
1995
|
+
Counterfactual (France): ${import_picocolors.default.green(carbon.co2KgFrance.toFixed(2) + " kgCO2")}
|
|
1996
|
+
|
|
1997
|
+
Ratio: ~31x carbon penalty on coal-heavy grid`, "Session Carbon Breakdown");
|
|
1998
|
+
} catch (e) {
|
|
1999
|
+
s.stop("Audit failed");
|
|
2000
|
+
console.error(import_picocolors.default.red(e.message));
|
|
2001
|
+
}
|
|
2002
|
+
} else if (action === "authorship") {
|
|
2003
|
+
s.start("Scanning local git history...");
|
|
2004
|
+
try {
|
|
2005
|
+
const gitStats = await getAuthorshipStats().catch(() => null);
|
|
2006
|
+
s.stop("Audit complete");
|
|
2007
|
+
if (gitStats) {
|
|
2008
|
+
const pct = (gitStats.ratio * 100).toFixed(1);
|
|
2009
|
+
const nmPct = (gitStats.ratioNoMerges * 100).toFixed(1);
|
|
2010
|
+
let color = import_picocolors.default.green;
|
|
2011
|
+
let warning = "";
|
|
2012
|
+
if (gitStats.ratio > 0.7) {
|
|
2013
|
+
color = import_picocolors.default.red;
|
|
2014
|
+
warning = import_picocolors.default.red(" ⚠ high dependency");
|
|
2015
|
+
} else if (gitStats.ratio > 0.4) {
|
|
2016
|
+
color = import_picocolors.default.yellow;
|
|
2017
|
+
warning = import_picocolors.default.yellow(" ⚠ moderate");
|
|
2018
|
+
}
|
|
2019
|
+
note(`Total Commits: ${gitStats.total}
|
|
2020
|
+
AI Co-Authored: ${gitStats.ai}
|
|
2021
|
+
Authorship Ratio: ${color(pct + "%")}${warning}
|
|
2022
|
+
|
|
2023
|
+
Non-merge Commits: ${gitStats.totalNoMerges}
|
|
2024
|
+
AI Co-Authored: ${gitStats.aiNoMerges}
|
|
2025
|
+
Conservative Floor: ${color(nmPct + "%")}`, "Git Authorship Breakdown");
|
|
2026
|
+
}
|
|
2027
|
+
} catch (e) {
|
|
2028
|
+
s.stop("Audit failed");
|
|
2029
|
+
console.error(import_picocolors.default.red(e.message));
|
|
2030
|
+
}
|
|
2031
|
+
} else if (action === "status") {
|
|
2032
|
+
const isStrict = process.argv.includes("--strict");
|
|
2033
|
+
let gitStats = null;
|
|
2034
|
+
let carbon = null;
|
|
2035
|
+
let capabilities = null;
|
|
2036
|
+
if (!isStrict) {
|
|
2037
|
+
s.start("[SYSTEM] Booting local-first sandbox...");
|
|
2038
|
+
await new Promise((r2) => setTimeout(r2, 800));
|
|
2039
|
+
s.message(`↳ Guarantee: No API calls. Your code and logs never leave this machine.`);
|
|
2040
|
+
await new Promise((r2) => setTimeout(r2, 1200));
|
|
2041
|
+
s.message("[GIT] Scanning your commit history...");
|
|
2042
|
+
gitStats = await getAuthorshipStats().catch(() => null);
|
|
2043
|
+
await new Promise((r2) => setTimeout(r2, 600));
|
|
2044
|
+
s.message(`↳ Check: Are you writing the code, or just reviewing what the AI wrote?`);
|
|
2045
|
+
await new Promise((r2) => setTimeout(r2, 1200));
|
|
2046
|
+
s.message("[TOKENS] Parsing local AI logs (~/.claude/)...");
|
|
2047
|
+
carbon = await getCarbonStats().catch(() => null);
|
|
2048
|
+
await new Promise((r2) => setTimeout(r2, 600));
|
|
2049
|
+
s.message(`↳ Check: How much API waste is your workflow generating locally?`);
|
|
2050
|
+
await new Promise((r2) => setTimeout(r2, 1200));
|
|
2051
|
+
s.message("[ANALYSIS] Calculating your mastery score...");
|
|
2052
|
+
capabilities = await getCapabilitiesStats().catch(() => null);
|
|
2053
|
+
await new Promise((r2) => setTimeout(r2, 600));
|
|
2054
|
+
s.message(`↳ Warning: Heavy AI use creates the 'Illusion of Competence'. Don't lose your edge.`);
|
|
2055
|
+
await new Promise((r2) => setTimeout(r2, 1200));
|
|
2056
|
+
s.message("[PRINT] Generating Thermal Receipt...");
|
|
2057
|
+
await new Promise((r2) => setTimeout(r2, 600));
|
|
2058
|
+
} else {
|
|
2059
|
+
s.start("Running outlier telemetry audit...");
|
|
2060
|
+
gitStats = await getAuthorshipStats().catch(() => null);
|
|
2061
|
+
carbon = await getCarbonStats().catch(() => null);
|
|
2062
|
+
capabilities = await getCapabilitiesStats().catch(() => null);
|
|
2063
|
+
}
|
|
2064
|
+
s.stop("Audit complete");
|
|
2065
|
+
try {
|
|
2066
|
+
let authPct = "0%";
|
|
2067
|
+
let ruleFailures = 0;
|
|
2068
|
+
let authWarning = "";
|
|
2069
|
+
let wittyRemark = isStrict ? "" : "No git history (・_・ヾ";
|
|
2070
|
+
let mentorString = "";
|
|
2071
|
+
if (gitStats) {
|
|
2072
|
+
authPct = `${(gitStats.ratio * 100).toFixed(1)}%`;
|
|
2073
|
+
if (!isStrict) {
|
|
2074
|
+
if (gitStats.ratio < 0.1)
|
|
2075
|
+
wittyRemark = "Artisan, hand-crafted code. Very 2019 of you (=^ ◡ ^=)";
|
|
2076
|
+
else if (gitStats.ratio < 0.6)
|
|
2077
|
+
wittyRemark = "A true centaur. Half human, half matrix (=`ω´=)";
|
|
2078
|
+
else if (gitStats.ratio < 0.95)
|
|
2079
|
+
wittyRemark = "Orchestrating the swarm. You are the manager now (ФДФ)";
|
|
2080
|
+
else
|
|
2081
|
+
wittyRemark = "100% Cybernetic. Codebase goes brrrrr (=ಠᆽಠ=)";
|
|
2082
|
+
}
|
|
2083
|
+
if (gitStats.ratio > 0.7) {
|
|
2084
|
+
authWarning = import_picocolors.default.red(isStrict ? `⚠ High Risk Surface: ${authPct} AI-generated. Human review required.` : `⚠ Mentoring Emergency: ${authPct} AI-generated. High risk of skill atrophy.`);
|
|
2085
|
+
if (!isStrict) {
|
|
2086
|
+
mentorString = `
|
|
2087
|
+
mentor: ${import_picocolors.default.blue("\uD83D\uDCA1 Architecture Challenge Pending (See Git Hook)")}`;
|
|
2088
|
+
}
|
|
2089
|
+
ruleFailures++;
|
|
2090
|
+
}
|
|
2091
|
+
}
|
|
2092
|
+
let cachePct = "0";
|
|
2093
|
+
let co2Str = "0.0kg";
|
|
2094
|
+
let regionStr = "Global Average";
|
|
2095
|
+
if (carbon) {
|
|
2096
|
+
if (carbon.totalTokens > 0) {
|
|
2097
|
+
cachePct = (carbon.cacheReadTokens / carbon.totalTokens * 100).toFixed(1);
|
|
2098
|
+
}
|
|
2099
|
+
co2Str = `${carbon.localCo2Kg.toFixed(2)}kg CO2`;
|
|
2100
|
+
regionStr = carbon.localRegion;
|
|
2101
|
+
}
|
|
2102
|
+
const vibeRow = !isStrict ? `
|
|
2103
|
+
vibe: ${import_picocolors.default.italic(wittyRemark)}` : "";
|
|
2104
|
+
const capIcon = isStrict ? "" : "(Ф∇Ф) ";
|
|
2105
|
+
const authIcon = isStrict ? "" : "(=^・ω・^=) ";
|
|
2106
|
+
const costIcon = isStrict ? "" : "(O_O;) ";
|
|
2107
|
+
const failIcon = isStrict ? "⚠" : "(=ಠᆽಠ=)";
|
|
2108
|
+
const passIcon = isStrict ? "✓" : "(=^ ◡ ^=)";
|
|
2109
|
+
note(`${capIcon}${import_picocolors.default.dim("[1] Capability Engine")} ${import_picocolors.default.cyan("▰▰▰▰▰▰▱▱▱▱")} ${import_picocolors.default.bold("Active")}
|
|
2110
|
+
status: ${import_picocolors.default.green("✓ Configured")}
|
|
2111
|
+
${authIcon}${import_picocolors.default.dim("[2] AI Code Reliance")} ${import_picocolors.default.yellow("▰▰▰▰▰▰▰▰▱▱")} ${import_picocolors.default.bold(`${authPct} Reliance`)}${vibeRow}
|
|
2112
|
+
gate: ${gitStats && gitStats.ratio <= 0.7 ? import_picocolors.default.green("✓ Human Mastery Sustained") : `${import_picocolors.default.red(`${failIcon} Deskilling Risk Detected`)} ${import_picocolors.default.red("⚠ Security Audit Required")}`}${mentorString}
|
|
2113
|
+
${costIcon}${import_picocolors.default.dim("[3] Tokenomics & Cost")} ${import_picocolors.default.magenta("▰▰▰▰▰▰▰▰▰▱")} ${import_picocolors.default.bold(`${cachePct}% Cache Bloat`)}
|
|
2114
|
+
waste: ${import_picocolors.default.yellow(`⚠ ${cachePct}% of tokens are redundant context reads`)}
|
|
2115
|
+
carbon: ${import_picocolors.default.green(`✓ ${co2Str} (Est. ${regionStr} Grid)`)}
|
|
2116
|
+
${import_picocolors.default.bold("Governance:")} ${ruleFailures > 0 ? import_picocolors.default.red(`${failIcon} ${ruleFailures + 1} policy failures`) : import_picocolors.default.green(`${passIcon} All clear`)}`, `${import_picocolors.default.bold("[outlier]")} ${5 - (ruleFailures + 1)}/5 policies • ${authWarning || import_picocolors.default.green(`${passIcon} safe surface`)} • ${co2Str}`);
|
|
2117
|
+
} catch (e) {
|
|
2118
|
+
s.stop("Audit failed");
|
|
2119
|
+
console.error(import_picocolors.default.red(e.message));
|
|
2120
|
+
}
|
|
2121
|
+
} else if (action === "capabilities") {
|
|
2122
|
+
s.start("Auditing AI surface area (MCPs, Skills, Orchestrators)...");
|
|
2123
|
+
try {
|
|
2124
|
+
const caps = await getCapabilitiesStats();
|
|
2125
|
+
s.stop("Capabilities Scan Complete");
|
|
2126
|
+
note(`Orchestration Policy: ${caps.hasOrchestration ? import_picocolors.default.green("Detected (AGENTS.md)") : import_picocolors.default.yellow("None")}
|
|
2127
|
+
|
|
2128
|
+
Active Skills (${caps.skills.length}):
|
|
2129
|
+
${caps.skills.length > 0 ? import_picocolors.default.cyan(caps.skills.map((s2) => ` • ${s2}`).join(`
|
|
2130
|
+
`)) : " None"}
|
|
2131
|
+
|
|
2132
|
+
Active MCP Servers (${caps.mcps.length}):
|
|
2133
|
+
${caps.mcps.length > 0 ? import_picocolors.default.magenta(caps.mcps.map((m2) => ` • ${m2}`).join(`
|
|
2134
|
+
`)) : " None"}
|
|
2135
|
+
|
|
2136
|
+
${import_picocolors.default.bold("Governance Assessment:")}
|
|
2137
|
+
This repository provides agents with ${caps.mcps.length} toolsets and ${caps.skills.length} skills.
|
|
2138
|
+
${caps.skills.length > 5 ? import_picocolors.default.red("⚠ High Surface Area: Ensure strict authorship review is enabled.") : import_picocolors.default.green("✓ Low Surface Area: Risk contained.")}`, "AI Capabilities Map");
|
|
2139
|
+
} catch (e) {
|
|
2140
|
+
s.stop("Audit failed");
|
|
2141
|
+
console.error(import_picocolors.default.red(e.message));
|
|
2142
|
+
}
|
|
2143
|
+
} else if (action === "policy") {
|
|
2144
|
+
const tier = await select({
|
|
2145
|
+
message: "Select the governance tier to configure:",
|
|
2146
|
+
options: [
|
|
2147
|
+
{ value: "personal", label: "Personal (Self-imposed)", hint: "Set your own limits for skill retention" },
|
|
2148
|
+
{ value: "team", label: "Team Guardrails", hint: "Engineering lead sets thresholds for human review" },
|
|
2149
|
+
{ value: "enterprise", label: "Enterprise Compliance", hint: "Production thresholds (e.g., max 60% AI authorship)" },
|
|
2150
|
+
{ value: "regulatory", label: "Regulatory Audit", hint: "Decree 142 human-oversight logging" }
|
|
2151
|
+
]
|
|
2152
|
+
});
|
|
2153
|
+
if (isCancel(tier)) {
|
|
2154
|
+
cancel("Policy configuration cancelled.");
|
|
2155
|
+
process.exit(0);
|
|
2156
|
+
}
|
|
2157
|
+
if (tier === "personal" || tier === "team" || tier === "enterprise") {
|
|
2158
|
+
const maxAuthorship = await select({
|
|
2159
|
+
message: `Set the maximum allowed AI Authorship Share for ${tier} profile:`,
|
|
2160
|
+
options: [
|
|
2161
|
+
{ value: "50", label: "50% (Strict Human-Majority)" },
|
|
2162
|
+
{ value: "70", label: "70% (Standard Hybrid)" },
|
|
2163
|
+
{ value: "85", label: "85% (High Velocity)" },
|
|
2164
|
+
{ value: "100", label: "100% (Unrestricted)" }
|
|
2165
|
+
]
|
|
2166
|
+
});
|
|
2167
|
+
if (isCancel(maxAuthorship)) {
|
|
2168
|
+
cancel("Policy configuration cancelled.");
|
|
2169
|
+
process.exit(0);
|
|
2170
|
+
}
|
|
2171
|
+
s.start(`Applying ${tier} policy guardrails...`);
|
|
2172
|
+
const gitDir = join3(process.cwd(), ".git");
|
|
2173
|
+
const isRepo = existsSync2(gitDir);
|
|
2174
|
+
if (!isRepo) {
|
|
2175
|
+
console.error(import_picocolors.default.red("Must be run inside a git repository"));
|
|
2176
|
+
process.exit(1);
|
|
2177
|
+
}
|
|
2178
|
+
const isStrict = process.argv.includes("--strict");
|
|
2179
|
+
const bouncerMsg = isStrict ? `echo "⚠️ outlier policy warning: AI authorship ($CURRENT_RATIO%) exceeds threshold ($MAX_RATIO%)"` : `echo "\uD83D\uDEE1️ Outlier Bouncer: Repository AI-generation ($CURRENT_RATIO%) exceeds your defined mastery threshold ($MAX_RATIO%)."
|
|
2180
|
+
echo "Take a moment to review your recent architectural decisions. Ensure you still understand the system."`;
|
|
2181
|
+
const hookPath = join3(gitDir, "hooks", "pre-commit");
|
|
2182
|
+
if (existsSync2(hookPath)) {
|
|
2183
|
+
const { copyFileSync } = __require("fs");
|
|
2184
|
+
copyFileSync(hookPath, `${hookPath}.backup`);
|
|
2185
|
+
}
|
|
2186
|
+
const hookScript = `#!/bin/sh
|
|
2187
|
+
# outlier Pre-Commit Governance Hook
|
|
2188
|
+
|
|
2189
|
+
# Calculate AI Authorship Ratio
|
|
2190
|
+
TOTAL=$(git log --oneline | wc -l | tr -d ' ')
|
|
2191
|
+
AI=$(git log -i --grep='Co-Authored-By' --oneline | wc -l | tr -d ' ')
|
|
2192
|
+
if [ "$TOTAL" -eq 0 ]; then exit 0; fi
|
|
2193
|
+
CURRENT_RATIO=$(awk "BEGIN {print ($AI / $TOTAL) * 100}")
|
|
2194
|
+
MAX_RATIO=${maxAuthorship}
|
|
2195
|
+
|
|
2196
|
+
OVER_LIMIT=$(awk "BEGIN {print ($CURRENT_RATIO > $MAX_RATIO) ? 1 : 0}")
|
|
2197
|
+
if [ "$OVER_LIMIT" -eq 1 ]; then
|
|
2198
|
+
${bouncerMsg}
|
|
2199
|
+
# Warn instead of hard-blocking the commit, protecting human iterations
|
|
2200
|
+
exit 0
|
|
2201
|
+
fi
|
|
2202
|
+
echo "✅ Governance Policy OK"
|
|
2203
|
+
`;
|
|
2204
|
+
writeFileSync(hookPath, hookScript);
|
|
2205
|
+
chmodSync(hookPath, "755");
|
|
2206
|
+
await new Promise((resolve) => setTimeout(resolve, 800));
|
|
2207
|
+
s.stop("Policy Applied");
|
|
2208
|
+
note(`Tier: ${import_picocolors.default.bold(tier.toString().toUpperCase())}
|
|
2209
|
+
Rule 1: ${import_picocolors.default.green(`AI Authorship must not exceed ${maxAuthorship}%`)}
|
|
2210
|
+
Rule 2: ${import_picocolors.default.green("Require human review on consecutive high-AI sprints")}
|
|
2211
|
+
Enforcement: ${import_picocolors.default.cyan("Local pre-commit hook installed (backup created)")}`, "Active Governance Policy");
|
|
2212
|
+
} else if (tier === "regulatory") {
|
|
2213
|
+
s.start("Generating Regulatory Compliance Audit (Decree 142)...");
|
|
2214
|
+
await new Promise((resolve) => setTimeout(resolve, 1200));
|
|
2215
|
+
const reportPath = join3(process.cwd(), "outlier-audit-report.jsonl");
|
|
2216
|
+
writeFileSync(reportPath, JSON.stringify({ timestamp: new Date().toISOString(), status: "PREVIEW", policy: "Decree 142", simulatedOversight: true }) + `
|
|
2217
|
+
`);
|
|
2218
|
+
s.stop("Audit Generated");
|
|
2219
|
+
note(`Jurisdiction: ${import_picocolors.default.bold("Vietnam (Decree 142)")}
|
|
2220
|
+
Status: ${import_picocolors.default.green("Compliant - Human oversight logged locally")}
|
|
2221
|
+
Privacy: ${import_picocolors.default.green("Preserved - No citizen data exported")}
|
|
2222
|
+
Artifact: ${import_picocolors.default.cyan(reportPath)}`, "Regulatory Compliance");
|
|
2223
|
+
}
|
|
2224
|
+
} else if (action === "participate") {
|
|
2225
|
+
s.start("Connecting to the Outlier research project...");
|
|
2226
|
+
await new Promise((resolve) => setTimeout(resolve, 600));
|
|
2227
|
+
s.stop("Secure connection established.");
|
|
2228
|
+
const q1 = await select({
|
|
2229
|
+
message: import_picocolors.default.cyan("What is your current engineering reality today?"),
|
|
2230
|
+
options: [
|
|
2231
|
+
{ value: "artisan", label: "Solo Artisan (I write 90%+ of the code myself)" },
|
|
2232
|
+
{ value: "manager", label: "AI Manager (I prompt, the agents write)" },
|
|
2233
|
+
{ value: "reviewer", label: "Full-time Reviewer (I spend my days reviewing agent PRs)" }
|
|
2234
|
+
]
|
|
2235
|
+
});
|
|
2236
|
+
if (isCancel(q1)) {
|
|
2237
|
+
cancel("Survey aborted.");
|
|
2238
|
+
process.exit(0);
|
|
2239
|
+
}
|
|
2240
|
+
const q2 = await select({
|
|
2241
|
+
message: import_picocolors.default.cyan("Do you feel you are losing your deep architectural mastery? (Deskilling)"),
|
|
2242
|
+
options: [
|
|
2243
|
+
{ value: "yes_heavy", label: "Yes, heavily. I forget how my own systems work." },
|
|
2244
|
+
{ value: "yes_slight", label: "Slightly. I rely on the AI to fix its own bugs." },
|
|
2245
|
+
{ value: "no", label: "No. I maintain strict oversight and mastery." }
|
|
2246
|
+
]
|
|
2247
|
+
});
|
|
2248
|
+
if (isCancel(q2)) {
|
|
2249
|
+
cancel("Survey aborted.");
|
|
2250
|
+
process.exit(0);
|
|
2251
|
+
}
|
|
2252
|
+
const feedback = await text({
|
|
2253
|
+
message: import_picocolors.default.cyan(`In your own words, what is AI actually doing to your codebase or your job?
|
|
2254
|
+
(Note: This will draft a public GitHub issue)`),
|
|
2255
|
+
placeholder: "Honestly, I just let the agent write the regex...",
|
|
2256
|
+
validate(value) {
|
|
2257
|
+
if (!value || value.length === 0)
|
|
2258
|
+
return `C'mon, say something!`;
|
|
2259
|
+
}
|
|
2260
|
+
});
|
|
2261
|
+
if (isCancel(feedback)) {
|
|
2262
|
+
cancel("Survey aborted.");
|
|
2263
|
+
process.exit(0);
|
|
2264
|
+
}
|
|
2265
|
+
note(`${import_picocolors.default.italic(`"${feedback}"`)}
|
|
2266
|
+
|
|
2267
|
+
Your input is invaluable. To make it official and contribute to the literature, we've generated a secure transmission link for you.`, "Outlier Research");
|
|
2268
|
+
const surveyData = `**Engineering Reality:** ${q1}
|
|
2269
|
+
**Deskilling Impact:** ${q2}
|
|
2270
|
+
**Thoughts:**
|
|
2271
|
+
${feedback}`;
|
|
2272
|
+
const url = `https://github.com/rosh100yx/outlier/issues/new?assignees=&labels=enhancement&projects=&template=feature_request.md&title=%5BOutlier+Research%5D+Feedback&body=${encodeURIComponent(`Drop a screenshot of your Thermal Receipt here!
|
|
2273
|
+
|
|
2274
|
+
` + surveyData)}`;
|
|
2275
|
+
console.log(`
|
|
2276
|
+
${import_picocolors.default.bold("Submit here (and drop your screenshot!):")} ${import_picocolors.default.underline(import_picocolors.default.cyan(url))}
|
|
2277
|
+
`);
|
|
2278
|
+
} else if (action === "impact") {
|
|
2279
|
+
console.log(`
|
|
2280
|
+
` + import_picocolors.default.bold(import_picocolors.default.bgMagenta(" THE COMPOUNDING HORIZON OF DESKILLING ")) + `
|
|
2281
|
+
`);
|
|
2282
|
+
console.log(import_picocolors.default.bold("What Do We Lose and Gain?"));
|
|
2283
|
+
console.log(import_picocolors.default.cyan("■ Today (The 5-minute task)"));
|
|
2284
|
+
console.log(` ${import_picocolors.default.green("Gain:")} Velocity. AI scaffolds your components.`);
|
|
2285
|
+
console.log(` ${import_picocolors.default.red("Lose:")} Syntax recall. Memory of the low-level pipes.`);
|
|
2286
|
+
console.log(import_picocolors.default.cyan(`
|
|
2287
|
+
■ Tomorrow (The 5-hour task - e.g. Claude Opus 4.5)`));
|
|
2288
|
+
console.log(` ${import_picocolors.default.green("Gain:")} Massive scale. You are a systems orchestrator.`);
|
|
2289
|
+
console.log(` ${import_picocolors.default.red("Lose:")} Architectural intimacy. You become a reviewer.`);
|
|
2290
|
+
console.log(import_picocolors.default.cyan(`
|
|
2291
|
+
■ Next 5-10 Years (The 1M+ LOC Crisis)`));
|
|
2292
|
+
console.log(` When an agent introduces a fatal state bug in a monolithic architecture, human reviewers will lack the muscle memory to debug it. Outlier measures this exact sovereignty erosion.
|
|
2293
|
+
`);
|
|
2294
|
+
} else if (action === "knowledge") {
|
|
2295
|
+
console.log(`
|
|
2296
|
+
` + import_picocolors.default.bold(import_picocolors.default.bgBlue(" CORE LITERATURE & REFERENCES ")) + `
|
|
2297
|
+
`);
|
|
2298
|
+
console.log(`1. ${import_picocolors.default.cyan("METR (Measuring AI Ability)")} - Evaluating AI on long-horizon software tasks.`);
|
|
2299
|
+
console.log(`2. ${import_picocolors.default.cyan('The "NPC" vs "High-Agency" Paradigm')} - Remaining sovereign in a room full of agents.`);
|
|
2300
|
+
console.log(`3. ${import_picocolors.default.cyan("Proof of Human Mastery")} - The cryptoeconomic necessity of proving human architectural understanding.`);
|
|
2301
|
+
console.log(`
|
|
2302
|
+
Read the full academic foundation at: ${import_picocolors.default.underline("https://github.com/rosh100yx/outlier")}
|
|
2303
|
+
`);
|
|
2304
|
+
}
|
|
2305
|
+
outro("Local telemetry run completed. No data left your machine.");
|
|
2306
|
+
if (action === "status" || action === "authorship" || action === "carbon") {
|
|
2307
|
+
const d = new Date;
|
|
2308
|
+
const dateStr = d.toLocaleDateString("en-US", { month: "short", day: "2-digit", year: "numeric" }).toUpperCase();
|
|
2309
|
+
const timeStr = d.toLocaleTimeString("en-US", { hour12: false });
|
|
2310
|
+
let repoName = process.cwd().split("/").pop() || "Unknown";
|
|
2311
|
+
console.log(`
|
|
2312
|
+
${import_picocolors.default.dim("-------------------------")} ${import_picocolors.default.bold("AUDIT RECEIPT")} ${import_picocolors.default.dim("-------------------------")}`);
|
|
2313
|
+
console.log(`
|
|
2314
|
+
Project ${import_picocolors.default.bold(repoName.padEnd(16).substring(0, 16))}`);
|
|
2315
|
+
console.log(` Timestamp ${import_picocolors.default.dim(`${dateStr} ${timeStr}`)}
|
|
2316
|
+
`);
|
|
2317
|
+
console.log(` 01x Authorship Policy ${process.argv.includes("--strict") ? "Strict Mode" : "Vibe Check"}`);
|
|
2318
|
+
console.log(` 02x AI Reliance Risk ${action === "carbon" ? "N/A" : "Assessed"}`);
|
|
2319
|
+
console.log(` 03x Cache Bloat Tokens ${action === "authorship" ? "N/A" : "Audited"}`);
|
|
2320
|
+
console.log(` 04x Regional Grid Check ${action === "authorship" ? "N/A" : "Completed"}
|
|
2321
|
+
`);
|
|
2322
|
+
console.log(import_picocolors.default.dim(" **********************************************************"));
|
|
2323
|
+
console.log(`
|
|
2324
|
+
${import_picocolors.default.italic("patterns emerge in the commit history,")}`);
|
|
2325
|
+
console.log(` ${import_picocolors.default.italic("code becomes commoditized by algorithms.")}`);
|
|
2326
|
+
console.log(` ${import_picocolors.default.italic("human mastery is the only true moat.")}
|
|
2327
|
+
`);
|
|
2328
|
+
console.log(import_picocolors.default.dim(` **********************************************************
|
|
2329
|
+
`));
|
|
2330
|
+
console.log(" Outlier Governance Engine");
|
|
2331
|
+
console.log(import_picocolors.default.bold(`
|
|
2332
|
+
***AUDIT COMPLETE***`));
|
|
2333
|
+
console.log(import_picocolors.default.bold(` ***STAY VIGILANT***
|
|
2334
|
+
`));
|
|
2335
|
+
}
|
|
2336
|
+
console.log(import_picocolors.default.dim(`└ Share your audit: https://x.com/intent/tweet?text=${encodeURIComponent(`I just audited my codebase for AI reliance and deskilling risk. What does your repo score?
|
|
2337
|
+
|
|
2338
|
+
\uD83D\uDCCF #Outlier`)}`));
|
|
2339
|
+
if (action === "status") {
|
|
2340
|
+
console.log(import_picocolors.default.dim(`└ Have thoughts on AI deskilling? Tell us: `) + import_picocolors.default.cyan(`outlier participate`));
|
|
2341
|
+
console.log(import_picocolors.default.dim(`└ Keep your local policies updated: `) + import_picocolors.default.cyan(`outlier update`));
|
|
2342
|
+
}
|
|
2343
|
+
}
|
|
2344
|
+
main().catch(console.error);
|