loclaude 0.0.2 → 0.0.3
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/CHANGELOG.md +19 -0
- package/README.md +2 -0
- package/package.json +10 -9
- package/libs/cli/CHANGELOG.md +0 -59
- package/libs/cli/LICENSE +0 -31
- package/libs/cli/README.md +0 -5
- package/libs/cli/dist/cac.d.ts +0 -6
- package/libs/cli/dist/cac.d.ts.map +0 -1
- package/libs/cli/dist/commands/config.d.ts +0 -6
- package/libs/cli/dist/commands/config.d.ts.map +0 -1
- package/libs/cli/dist/commands/docker.d.ts +0 -17
- package/libs/cli/dist/commands/docker.d.ts.map +0 -1
- package/libs/cli/dist/commands/doctor.d.ts +0 -9
- package/libs/cli/dist/commands/doctor.d.ts.map +0 -1
- package/libs/cli/dist/commands/index.d.ts +0 -6
- package/libs/cli/dist/commands/index.d.ts.map +0 -1
- package/libs/cli/dist/commands/init.d.ts +0 -11
- package/libs/cli/dist/commands/init.d.ts.map +0 -1
- package/libs/cli/dist/commands/models.d.ts +0 -9
- package/libs/cli/dist/commands/models.d.ts.map +0 -1
- package/libs/cli/dist/config.d.ts +0 -74
- package/libs/cli/dist/config.d.ts.map +0 -1
- package/libs/cli/dist/constants.d.ts +0 -12
- package/libs/cli/dist/constants.d.ts.map +0 -1
- package/libs/cli/dist/index.bun.js +0 -4349
- package/libs/cli/dist/index.bun.js.map +0 -55
- package/libs/cli/dist/index.d.ts +0 -2
- package/libs/cli/dist/index.d.ts.map +0 -1
- package/libs/cli/dist/index.js +0 -4352
- package/libs/cli/dist/index.js.map +0 -55
- package/libs/cli/dist/output.d.ts +0 -107
- package/libs/cli/dist/output.d.ts.map +0 -1
- package/libs/cli/dist/spawn.d.ts +0 -35
- package/libs/cli/dist/spawn.d.ts.map +0 -1
- package/libs/cli/dist/types.d.ts +0 -50
- package/libs/cli/dist/types.d.ts.map +0 -1
- package/libs/cli/dist/utils.d.ts +0 -32
- package/libs/cli/dist/utils.d.ts.map +0 -1
- package/libs/cli/package.json +0 -90
|
@@ -1,4349 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
var __create = Object.create;
|
|
3
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
4
|
-
var __defProp = Object.defineProperty;
|
|
5
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
-
var __toESM = (mod, isNodeMode, target) => {
|
|
8
|
-
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
9
|
-
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
10
|
-
for (let key of __getOwnPropNames(mod))
|
|
11
|
-
if (!__hasOwnProp.call(to, key))
|
|
12
|
-
__defProp(to, key, {
|
|
13
|
-
get: () => mod[key],
|
|
14
|
-
enumerable: true
|
|
15
|
-
});
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
19
|
-
var __require = import.meta.require;
|
|
20
|
-
|
|
21
|
-
// ../../node_modules/.bun/cli-width@4.1.0/node_modules/cli-width/index.js
|
|
22
|
-
var require_cli_width = __commonJS((exports, module) => {
|
|
23
|
-
module.exports = cliWidth;
|
|
24
|
-
function normalizeOpts(options) {
|
|
25
|
-
const defaultOpts = {
|
|
26
|
-
defaultWidth: 0,
|
|
27
|
-
output: process.stdout,
|
|
28
|
-
tty: __require("tty")
|
|
29
|
-
};
|
|
30
|
-
if (!options) {
|
|
31
|
-
return defaultOpts;
|
|
32
|
-
}
|
|
33
|
-
Object.keys(defaultOpts).forEach(function(key) {
|
|
34
|
-
if (!options[key]) {
|
|
35
|
-
options[key] = defaultOpts[key];
|
|
36
|
-
}
|
|
37
|
-
});
|
|
38
|
-
return options;
|
|
39
|
-
}
|
|
40
|
-
function cliWidth(options) {
|
|
41
|
-
const opts = normalizeOpts(options);
|
|
42
|
-
if (opts.output.getWindowSize) {
|
|
43
|
-
return opts.output.getWindowSize()[0] || opts.defaultWidth;
|
|
44
|
-
}
|
|
45
|
-
if (opts.tty.getWindowSize) {
|
|
46
|
-
return opts.tty.getWindowSize()[1] || opts.defaultWidth;
|
|
47
|
-
}
|
|
48
|
-
if (opts.output.columns) {
|
|
49
|
-
return opts.output.columns;
|
|
50
|
-
}
|
|
51
|
-
if (process.env.CLI_WIDTH) {
|
|
52
|
-
const width = parseInt(process.env.CLI_WIDTH, 10);
|
|
53
|
-
if (!isNaN(width) && width !== 0) {
|
|
54
|
-
return width;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
return opts.defaultWidth;
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
// ../../node_modules/.bun/mute-stream@3.0.0/node_modules/mute-stream/lib/index.js
|
|
62
|
-
var require_lib = __commonJS((exports, module) => {
|
|
63
|
-
var Stream = __require("stream");
|
|
64
|
-
|
|
65
|
-
class MuteStream extends Stream {
|
|
66
|
-
#isTTY = null;
|
|
67
|
-
constructor(opts = {}) {
|
|
68
|
-
super(opts);
|
|
69
|
-
this.writable = this.readable = true;
|
|
70
|
-
this.muted = false;
|
|
71
|
-
this.on("pipe", this._onpipe);
|
|
72
|
-
this.replace = opts.replace;
|
|
73
|
-
this._prompt = opts.prompt || null;
|
|
74
|
-
this._hadControl = false;
|
|
75
|
-
}
|
|
76
|
-
#destSrc(key, def) {
|
|
77
|
-
if (this._dest) {
|
|
78
|
-
return this._dest[key];
|
|
79
|
-
}
|
|
80
|
-
if (this._src) {
|
|
81
|
-
return this._src[key];
|
|
82
|
-
}
|
|
83
|
-
return def;
|
|
84
|
-
}
|
|
85
|
-
#proxy(method, ...args) {
|
|
86
|
-
if (typeof this._dest?.[method] === "function") {
|
|
87
|
-
this._dest[method](...args);
|
|
88
|
-
}
|
|
89
|
-
if (typeof this._src?.[method] === "function") {
|
|
90
|
-
this._src[method](...args);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
get isTTY() {
|
|
94
|
-
if (this.#isTTY !== null) {
|
|
95
|
-
return this.#isTTY;
|
|
96
|
-
}
|
|
97
|
-
return this.#destSrc("isTTY", false);
|
|
98
|
-
}
|
|
99
|
-
set isTTY(val) {
|
|
100
|
-
this.#isTTY = val;
|
|
101
|
-
}
|
|
102
|
-
get rows() {
|
|
103
|
-
return this.#destSrc("rows");
|
|
104
|
-
}
|
|
105
|
-
get columns() {
|
|
106
|
-
return this.#destSrc("columns");
|
|
107
|
-
}
|
|
108
|
-
mute() {
|
|
109
|
-
this.muted = true;
|
|
110
|
-
}
|
|
111
|
-
unmute() {
|
|
112
|
-
this.muted = false;
|
|
113
|
-
}
|
|
114
|
-
_onpipe(src) {
|
|
115
|
-
this._src = src;
|
|
116
|
-
}
|
|
117
|
-
pipe(dest, options) {
|
|
118
|
-
this._dest = dest;
|
|
119
|
-
return super.pipe(dest, options);
|
|
120
|
-
}
|
|
121
|
-
pause() {
|
|
122
|
-
if (this._src) {
|
|
123
|
-
return this._src.pause();
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
resume() {
|
|
127
|
-
if (this._src) {
|
|
128
|
-
return this._src.resume();
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
write(c) {
|
|
132
|
-
if (this.muted) {
|
|
133
|
-
if (!this.replace) {
|
|
134
|
-
return true;
|
|
135
|
-
}
|
|
136
|
-
if (c.match(/^\u001b/)) {
|
|
137
|
-
if (c.indexOf(this._prompt) === 0) {
|
|
138
|
-
c = c.slice(this._prompt.length);
|
|
139
|
-
c = c.replace(/./g, this.replace);
|
|
140
|
-
c = this._prompt + c;
|
|
141
|
-
}
|
|
142
|
-
this._hadControl = true;
|
|
143
|
-
return this.emit("data", c);
|
|
144
|
-
} else {
|
|
145
|
-
if (this._prompt && this._hadControl && c.indexOf(this._prompt) === 0) {
|
|
146
|
-
this._hadControl = false;
|
|
147
|
-
this.emit("data", this._prompt);
|
|
148
|
-
c = c.slice(this._prompt.length);
|
|
149
|
-
}
|
|
150
|
-
c = c.toString().replace(/./g, this.replace);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
this.emit("data", c);
|
|
154
|
-
}
|
|
155
|
-
end(c) {
|
|
156
|
-
if (this.muted) {
|
|
157
|
-
if (c && this.replace) {
|
|
158
|
-
c = c.toString().replace(/./g, this.replace);
|
|
159
|
-
} else {
|
|
160
|
-
c = null;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
if (c) {
|
|
164
|
-
this.emit("data", c);
|
|
165
|
-
}
|
|
166
|
-
this.emit("end");
|
|
167
|
-
}
|
|
168
|
-
destroy(...args) {
|
|
169
|
-
return this.#proxy("destroy", ...args);
|
|
170
|
-
}
|
|
171
|
-
destroySoon(...args) {
|
|
172
|
-
return this.#proxy("destroySoon", ...args);
|
|
173
|
-
}
|
|
174
|
-
close(...args) {
|
|
175
|
-
return this.#proxy("close", ...args);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
module.exports = MuteStream;
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
// ../../node_modules/.bun/bytes@3.1.2/node_modules/bytes/index.js
|
|
182
|
-
var require_bytes = __commonJS((exports, module) => {
|
|
183
|
-
/*!
|
|
184
|
-
* bytes
|
|
185
|
-
* Copyright(c) 2012-2014 TJ Holowaychuk
|
|
186
|
-
* Copyright(c) 2015 Jed Watson
|
|
187
|
-
* MIT Licensed
|
|
188
|
-
*/
|
|
189
|
-
module.exports = bytes;
|
|
190
|
-
module.exports.format = format;
|
|
191
|
-
module.exports.parse = parse;
|
|
192
|
-
var formatThousandsRegExp = /\B(?=(\d{3})+(?!\d))/g;
|
|
193
|
-
var formatDecimalsRegExp = /(?:\.0*|(\.[^0]+)0+)$/;
|
|
194
|
-
var map = {
|
|
195
|
-
b: 1,
|
|
196
|
-
kb: 1 << 10,
|
|
197
|
-
mb: 1 << 20,
|
|
198
|
-
gb: 1 << 30,
|
|
199
|
-
tb: Math.pow(1024, 4),
|
|
200
|
-
pb: Math.pow(1024, 5)
|
|
201
|
-
};
|
|
202
|
-
var parseRegExp = /^((-|\+)?(\d+(?:\.\d+)?)) *(kb|mb|gb|tb|pb)$/i;
|
|
203
|
-
function bytes(value, options) {
|
|
204
|
-
if (typeof value === "string") {
|
|
205
|
-
return parse(value);
|
|
206
|
-
}
|
|
207
|
-
if (typeof value === "number") {
|
|
208
|
-
return format(value, options);
|
|
209
|
-
}
|
|
210
|
-
return null;
|
|
211
|
-
}
|
|
212
|
-
function format(value, options) {
|
|
213
|
-
if (!Number.isFinite(value)) {
|
|
214
|
-
return null;
|
|
215
|
-
}
|
|
216
|
-
var mag = Math.abs(value);
|
|
217
|
-
var thousandsSeparator = options && options.thousandsSeparator || "";
|
|
218
|
-
var unitSeparator = options && options.unitSeparator || "";
|
|
219
|
-
var decimalPlaces = options && options.decimalPlaces !== undefined ? options.decimalPlaces : 2;
|
|
220
|
-
var fixedDecimals = Boolean(options && options.fixedDecimals);
|
|
221
|
-
var unit = options && options.unit || "";
|
|
222
|
-
if (!unit || !map[unit.toLowerCase()]) {
|
|
223
|
-
if (mag >= map.pb) {
|
|
224
|
-
unit = "PB";
|
|
225
|
-
} else if (mag >= map.tb) {
|
|
226
|
-
unit = "TB";
|
|
227
|
-
} else if (mag >= map.gb) {
|
|
228
|
-
unit = "GB";
|
|
229
|
-
} else if (mag >= map.mb) {
|
|
230
|
-
unit = "MB";
|
|
231
|
-
} else if (mag >= map.kb) {
|
|
232
|
-
unit = "KB";
|
|
233
|
-
} else {
|
|
234
|
-
unit = "B";
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
var val = value / map[unit.toLowerCase()];
|
|
238
|
-
var str = val.toFixed(decimalPlaces);
|
|
239
|
-
if (!fixedDecimals) {
|
|
240
|
-
str = str.replace(formatDecimalsRegExp, "$1");
|
|
241
|
-
}
|
|
242
|
-
if (thousandsSeparator) {
|
|
243
|
-
str = str.split(".").map(function(s, i) {
|
|
244
|
-
return i === 0 ? s.replace(formatThousandsRegExp, thousandsSeparator) : s;
|
|
245
|
-
}).join(".");
|
|
246
|
-
}
|
|
247
|
-
return str + unitSeparator + unit;
|
|
248
|
-
}
|
|
249
|
-
function parse(val) {
|
|
250
|
-
if (typeof val === "number" && !isNaN(val)) {
|
|
251
|
-
return val;
|
|
252
|
-
}
|
|
253
|
-
if (typeof val !== "string") {
|
|
254
|
-
return null;
|
|
255
|
-
}
|
|
256
|
-
var results = parseRegExp.exec(val);
|
|
257
|
-
var floatValue;
|
|
258
|
-
var unit = "b";
|
|
259
|
-
if (!results) {
|
|
260
|
-
floatValue = parseInt(val, 10);
|
|
261
|
-
unit = "b";
|
|
262
|
-
} else {
|
|
263
|
-
floatValue = parseFloat(results[1]);
|
|
264
|
-
unit = results[4].toLowerCase();
|
|
265
|
-
}
|
|
266
|
-
if (isNaN(floatValue)) {
|
|
267
|
-
return null;
|
|
268
|
-
}
|
|
269
|
-
return Math.floor(map[unit] * floatValue);
|
|
270
|
-
}
|
|
271
|
-
});
|
|
272
|
-
|
|
273
|
-
// ../../node_modules/.bun/picocolors@1.1.1/node_modules/picocolors/picocolors.js
|
|
274
|
-
var require_picocolors = __commonJS((exports, module) => {
|
|
275
|
-
var p = process || {};
|
|
276
|
-
var argv = p.argv || [];
|
|
277
|
-
var env = p.env || {};
|
|
278
|
-
var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
|
|
279
|
-
var formatter = (open, close, replace = open) => (input) => {
|
|
280
|
-
let string = "" + input, index = string.indexOf(close, open.length);
|
|
281
|
-
return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
|
|
282
|
-
};
|
|
283
|
-
var replaceClose = (string, close, replace, index) => {
|
|
284
|
-
let result = "", cursor = 0;
|
|
285
|
-
do {
|
|
286
|
-
result += string.substring(cursor, index) + replace;
|
|
287
|
-
cursor = index + close.length;
|
|
288
|
-
index = string.indexOf(close, cursor);
|
|
289
|
-
} while (~index);
|
|
290
|
-
return result + string.substring(cursor);
|
|
291
|
-
};
|
|
292
|
-
var createColors = (enabled = isColorSupported) => {
|
|
293
|
-
let f = enabled ? formatter : () => String;
|
|
294
|
-
return {
|
|
295
|
-
isColorSupported: enabled,
|
|
296
|
-
reset: f("\x1B[0m", "\x1B[0m"),
|
|
297
|
-
bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
|
|
298
|
-
dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
|
|
299
|
-
italic: f("\x1B[3m", "\x1B[23m"),
|
|
300
|
-
underline: f("\x1B[4m", "\x1B[24m"),
|
|
301
|
-
inverse: f("\x1B[7m", "\x1B[27m"),
|
|
302
|
-
hidden: f("\x1B[8m", "\x1B[28m"),
|
|
303
|
-
strikethrough: f("\x1B[9m", "\x1B[29m"),
|
|
304
|
-
black: f("\x1B[30m", "\x1B[39m"),
|
|
305
|
-
red: f("\x1B[31m", "\x1B[39m"),
|
|
306
|
-
green: f("\x1B[32m", "\x1B[39m"),
|
|
307
|
-
yellow: f("\x1B[33m", "\x1B[39m"),
|
|
308
|
-
blue: f("\x1B[34m", "\x1B[39m"),
|
|
309
|
-
magenta: f("\x1B[35m", "\x1B[39m"),
|
|
310
|
-
cyan: f("\x1B[36m", "\x1B[39m"),
|
|
311
|
-
white: f("\x1B[37m", "\x1B[39m"),
|
|
312
|
-
gray: f("\x1B[90m", "\x1B[39m"),
|
|
313
|
-
bgBlack: f("\x1B[40m", "\x1B[49m"),
|
|
314
|
-
bgRed: f("\x1B[41m", "\x1B[49m"),
|
|
315
|
-
bgGreen: f("\x1B[42m", "\x1B[49m"),
|
|
316
|
-
bgYellow: f("\x1B[43m", "\x1B[49m"),
|
|
317
|
-
bgBlue: f("\x1B[44m", "\x1B[49m"),
|
|
318
|
-
bgMagenta: f("\x1B[45m", "\x1B[49m"),
|
|
319
|
-
bgCyan: f("\x1B[46m", "\x1B[49m"),
|
|
320
|
-
bgWhite: f("\x1B[47m", "\x1B[49m"),
|
|
321
|
-
blackBright: f("\x1B[90m", "\x1B[39m"),
|
|
322
|
-
redBright: f("\x1B[91m", "\x1B[39m"),
|
|
323
|
-
greenBright: f("\x1B[92m", "\x1B[39m"),
|
|
324
|
-
yellowBright: f("\x1B[93m", "\x1B[39m"),
|
|
325
|
-
blueBright: f("\x1B[94m", "\x1B[39m"),
|
|
326
|
-
magentaBright: f("\x1B[95m", "\x1B[39m"),
|
|
327
|
-
cyanBright: f("\x1B[96m", "\x1B[39m"),
|
|
328
|
-
whiteBright: f("\x1B[97m", "\x1B[39m"),
|
|
329
|
-
bgBlackBright: f("\x1B[100m", "\x1B[49m"),
|
|
330
|
-
bgRedBright: f("\x1B[101m", "\x1B[49m"),
|
|
331
|
-
bgGreenBright: f("\x1B[102m", "\x1B[49m"),
|
|
332
|
-
bgYellowBright: f("\x1B[103m", "\x1B[49m"),
|
|
333
|
-
bgBlueBright: f("\x1B[104m", "\x1B[49m"),
|
|
334
|
-
bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
|
|
335
|
-
bgCyanBright: f("\x1B[106m", "\x1B[49m"),
|
|
336
|
-
bgWhiteBright: f("\x1B[107m", "\x1B[49m")
|
|
337
|
-
};
|
|
338
|
-
};
|
|
339
|
-
module.exports = createColors();
|
|
340
|
-
module.exports.createColors = createColors;
|
|
341
|
-
});
|
|
342
|
-
|
|
343
|
-
// ../../node_modules/.bun/cac@6.7.14/node_modules/cac/dist/index.mjs
|
|
344
|
-
import { EventEmitter } from "events";
|
|
345
|
-
function toArr(any) {
|
|
346
|
-
return any == null ? [] : Array.isArray(any) ? any : [any];
|
|
347
|
-
}
|
|
348
|
-
function toVal(out, key, val, opts) {
|
|
349
|
-
var x, old = out[key], nxt = ~opts.string.indexOf(key) ? val == null || val === true ? "" : String(val) : typeof val === "boolean" ? val : ~opts.boolean.indexOf(key) ? val === "false" ? false : val === "true" || (out._.push((x = +val, x * 0 === 0) ? x : val), !!val) : (x = +val, x * 0 === 0) ? x : val;
|
|
350
|
-
out[key] = old == null ? nxt : Array.isArray(old) ? old.concat(nxt) : [old, nxt];
|
|
351
|
-
}
|
|
352
|
-
function mri2(args, opts) {
|
|
353
|
-
args = args || [];
|
|
354
|
-
opts = opts || {};
|
|
355
|
-
var k, arr, arg, name, val, out = { _: [] };
|
|
356
|
-
var i = 0, j = 0, idx = 0, len = args.length;
|
|
357
|
-
const alibi = opts.alias !== undefined;
|
|
358
|
-
const strict = opts.unknown !== undefined;
|
|
359
|
-
const defaults = opts.default !== undefined;
|
|
360
|
-
opts.alias = opts.alias || {};
|
|
361
|
-
opts.string = toArr(opts.string);
|
|
362
|
-
opts.boolean = toArr(opts.boolean);
|
|
363
|
-
if (alibi) {
|
|
364
|
-
for (k in opts.alias) {
|
|
365
|
-
arr = opts.alias[k] = toArr(opts.alias[k]);
|
|
366
|
-
for (i = 0;i < arr.length; i++) {
|
|
367
|
-
(opts.alias[arr[i]] = arr.concat(k)).splice(i, 1);
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
for (i = opts.boolean.length;i-- > 0; ) {
|
|
372
|
-
arr = opts.alias[opts.boolean[i]] || [];
|
|
373
|
-
for (j = arr.length;j-- > 0; )
|
|
374
|
-
opts.boolean.push(arr[j]);
|
|
375
|
-
}
|
|
376
|
-
for (i = opts.string.length;i-- > 0; ) {
|
|
377
|
-
arr = opts.alias[opts.string[i]] || [];
|
|
378
|
-
for (j = arr.length;j-- > 0; )
|
|
379
|
-
opts.string.push(arr[j]);
|
|
380
|
-
}
|
|
381
|
-
if (defaults) {
|
|
382
|
-
for (k in opts.default) {
|
|
383
|
-
name = typeof opts.default[k];
|
|
384
|
-
arr = opts.alias[k] = opts.alias[k] || [];
|
|
385
|
-
if (opts[name] !== undefined) {
|
|
386
|
-
opts[name].push(k);
|
|
387
|
-
for (i = 0;i < arr.length; i++) {
|
|
388
|
-
opts[name].push(arr[i]);
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
const keys = strict ? Object.keys(opts.alias) : [];
|
|
394
|
-
for (i = 0;i < len; i++) {
|
|
395
|
-
arg = args[i];
|
|
396
|
-
if (arg === "--") {
|
|
397
|
-
out._ = out._.concat(args.slice(++i));
|
|
398
|
-
break;
|
|
399
|
-
}
|
|
400
|
-
for (j = 0;j < arg.length; j++) {
|
|
401
|
-
if (arg.charCodeAt(j) !== 45)
|
|
402
|
-
break;
|
|
403
|
-
}
|
|
404
|
-
if (j === 0) {
|
|
405
|
-
out._.push(arg);
|
|
406
|
-
} else if (arg.substring(j, j + 3) === "no-") {
|
|
407
|
-
name = arg.substring(j + 3);
|
|
408
|
-
if (strict && !~keys.indexOf(name)) {
|
|
409
|
-
return opts.unknown(arg);
|
|
410
|
-
}
|
|
411
|
-
out[name] = false;
|
|
412
|
-
} else {
|
|
413
|
-
for (idx = j + 1;idx < arg.length; idx++) {
|
|
414
|
-
if (arg.charCodeAt(idx) === 61)
|
|
415
|
-
break;
|
|
416
|
-
}
|
|
417
|
-
name = arg.substring(j, idx);
|
|
418
|
-
val = arg.substring(++idx) || (i + 1 === len || ("" + args[i + 1]).charCodeAt(0) === 45 || args[++i]);
|
|
419
|
-
arr = j === 2 ? [name] : name;
|
|
420
|
-
for (idx = 0;idx < arr.length; idx++) {
|
|
421
|
-
name = arr[idx];
|
|
422
|
-
if (strict && !~keys.indexOf(name))
|
|
423
|
-
return opts.unknown("-".repeat(j) + name);
|
|
424
|
-
toVal(out, name, idx + 1 < arr.length || val, opts);
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
if (defaults) {
|
|
429
|
-
for (k in opts.default) {
|
|
430
|
-
if (out[k] === undefined) {
|
|
431
|
-
out[k] = opts.default[k];
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
if (alibi) {
|
|
436
|
-
for (k in out) {
|
|
437
|
-
arr = opts.alias[k] || [];
|
|
438
|
-
while (arr.length > 0) {
|
|
439
|
-
out[arr.shift()] = out[k];
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
return out;
|
|
444
|
-
}
|
|
445
|
-
var removeBrackets = (v) => v.replace(/[<[].+/, "").trim();
|
|
446
|
-
var findAllBrackets = (v) => {
|
|
447
|
-
const ANGLED_BRACKET_RE_GLOBAL = /<([^>]+)>/g;
|
|
448
|
-
const SQUARE_BRACKET_RE_GLOBAL = /\[([^\]]+)\]/g;
|
|
449
|
-
const res = [];
|
|
450
|
-
const parse = (match) => {
|
|
451
|
-
let variadic = false;
|
|
452
|
-
let value = match[1];
|
|
453
|
-
if (value.startsWith("...")) {
|
|
454
|
-
value = value.slice(3);
|
|
455
|
-
variadic = true;
|
|
456
|
-
}
|
|
457
|
-
return {
|
|
458
|
-
required: match[0].startsWith("<"),
|
|
459
|
-
value,
|
|
460
|
-
variadic
|
|
461
|
-
};
|
|
462
|
-
};
|
|
463
|
-
let angledMatch;
|
|
464
|
-
while (angledMatch = ANGLED_BRACKET_RE_GLOBAL.exec(v)) {
|
|
465
|
-
res.push(parse(angledMatch));
|
|
466
|
-
}
|
|
467
|
-
let squareMatch;
|
|
468
|
-
while (squareMatch = SQUARE_BRACKET_RE_GLOBAL.exec(v)) {
|
|
469
|
-
res.push(parse(squareMatch));
|
|
470
|
-
}
|
|
471
|
-
return res;
|
|
472
|
-
};
|
|
473
|
-
var getMriOptions = (options) => {
|
|
474
|
-
const result = { alias: {}, boolean: [] };
|
|
475
|
-
for (const [index, option] of options.entries()) {
|
|
476
|
-
if (option.names.length > 1) {
|
|
477
|
-
result.alias[option.names[0]] = option.names.slice(1);
|
|
478
|
-
}
|
|
479
|
-
if (option.isBoolean) {
|
|
480
|
-
if (option.negated) {
|
|
481
|
-
const hasStringTypeOption = options.some((o, i) => {
|
|
482
|
-
return i !== index && o.names.some((name) => option.names.includes(name)) && typeof o.required === "boolean";
|
|
483
|
-
});
|
|
484
|
-
if (!hasStringTypeOption) {
|
|
485
|
-
result.boolean.push(option.names[0]);
|
|
486
|
-
}
|
|
487
|
-
} else {
|
|
488
|
-
result.boolean.push(option.names[0]);
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
return result;
|
|
493
|
-
};
|
|
494
|
-
var findLongest = (arr) => {
|
|
495
|
-
return arr.sort((a, b) => {
|
|
496
|
-
return a.length > b.length ? -1 : 1;
|
|
497
|
-
})[0];
|
|
498
|
-
};
|
|
499
|
-
var padRight = (str, length) => {
|
|
500
|
-
return str.length >= length ? str : `${str}${" ".repeat(length - str.length)}`;
|
|
501
|
-
};
|
|
502
|
-
var camelcase = (input) => {
|
|
503
|
-
return input.replace(/([a-z])-([a-z])/g, (_, p1, p2) => {
|
|
504
|
-
return p1 + p2.toUpperCase();
|
|
505
|
-
});
|
|
506
|
-
};
|
|
507
|
-
var setDotProp = (obj, keys, val) => {
|
|
508
|
-
let i = 0;
|
|
509
|
-
let length = keys.length;
|
|
510
|
-
let t = obj;
|
|
511
|
-
let x;
|
|
512
|
-
for (;i < length; ++i) {
|
|
513
|
-
x = t[keys[i]];
|
|
514
|
-
t = t[keys[i]] = i === length - 1 ? val : x != null ? x : !!~keys[i + 1].indexOf(".") || !(+keys[i + 1] > -1) ? {} : [];
|
|
515
|
-
}
|
|
516
|
-
};
|
|
517
|
-
var setByType = (obj, transforms) => {
|
|
518
|
-
for (const key of Object.keys(transforms)) {
|
|
519
|
-
const transform = transforms[key];
|
|
520
|
-
if (transform.shouldTransform) {
|
|
521
|
-
obj[key] = Array.prototype.concat.call([], obj[key]);
|
|
522
|
-
if (typeof transform.transformFunction === "function") {
|
|
523
|
-
obj[key] = obj[key].map(transform.transformFunction);
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
};
|
|
528
|
-
var getFileName = (input) => {
|
|
529
|
-
const m = /([^\\\/]+)$/.exec(input);
|
|
530
|
-
return m ? m[1] : "";
|
|
531
|
-
};
|
|
532
|
-
var camelcaseOptionName = (name) => {
|
|
533
|
-
return name.split(".").map((v, i) => {
|
|
534
|
-
return i === 0 ? camelcase(v) : v;
|
|
535
|
-
}).join(".");
|
|
536
|
-
};
|
|
537
|
-
|
|
538
|
-
class CACError extends Error {
|
|
539
|
-
constructor(message) {
|
|
540
|
-
super(message);
|
|
541
|
-
this.name = this.constructor.name;
|
|
542
|
-
if (typeof Error.captureStackTrace === "function") {
|
|
543
|
-
Error.captureStackTrace(this, this.constructor);
|
|
544
|
-
} else {
|
|
545
|
-
this.stack = new Error(message).stack;
|
|
546
|
-
}
|
|
547
|
-
}
|
|
548
|
-
}
|
|
549
|
-
|
|
550
|
-
class Option {
|
|
551
|
-
constructor(rawName, description, config) {
|
|
552
|
-
this.rawName = rawName;
|
|
553
|
-
this.description = description;
|
|
554
|
-
this.config = Object.assign({}, config);
|
|
555
|
-
rawName = rawName.replace(/\.\*/g, "");
|
|
556
|
-
this.negated = false;
|
|
557
|
-
this.names = removeBrackets(rawName).split(",").map((v) => {
|
|
558
|
-
let name = v.trim().replace(/^-{1,2}/, "");
|
|
559
|
-
if (name.startsWith("no-")) {
|
|
560
|
-
this.negated = true;
|
|
561
|
-
name = name.replace(/^no-/, "");
|
|
562
|
-
}
|
|
563
|
-
return camelcaseOptionName(name);
|
|
564
|
-
}).sort((a, b) => a.length > b.length ? 1 : -1);
|
|
565
|
-
this.name = this.names[this.names.length - 1];
|
|
566
|
-
if (this.negated && this.config.default == null) {
|
|
567
|
-
this.config.default = true;
|
|
568
|
-
}
|
|
569
|
-
if (rawName.includes("<")) {
|
|
570
|
-
this.required = true;
|
|
571
|
-
} else if (rawName.includes("[")) {
|
|
572
|
-
this.required = false;
|
|
573
|
-
} else {
|
|
574
|
-
this.isBoolean = true;
|
|
575
|
-
}
|
|
576
|
-
}
|
|
577
|
-
}
|
|
578
|
-
var processArgs = process.argv;
|
|
579
|
-
var platformInfo = `${process.platform}-${process.arch} node-${process.version}`;
|
|
580
|
-
|
|
581
|
-
class Command {
|
|
582
|
-
constructor(rawName, description, config = {}, cli) {
|
|
583
|
-
this.rawName = rawName;
|
|
584
|
-
this.description = description;
|
|
585
|
-
this.config = config;
|
|
586
|
-
this.cli = cli;
|
|
587
|
-
this.options = [];
|
|
588
|
-
this.aliasNames = [];
|
|
589
|
-
this.name = removeBrackets(rawName);
|
|
590
|
-
this.args = findAllBrackets(rawName);
|
|
591
|
-
this.examples = [];
|
|
592
|
-
}
|
|
593
|
-
usage(text) {
|
|
594
|
-
this.usageText = text;
|
|
595
|
-
return this;
|
|
596
|
-
}
|
|
597
|
-
allowUnknownOptions() {
|
|
598
|
-
this.config.allowUnknownOptions = true;
|
|
599
|
-
return this;
|
|
600
|
-
}
|
|
601
|
-
ignoreOptionDefaultValue() {
|
|
602
|
-
this.config.ignoreOptionDefaultValue = true;
|
|
603
|
-
return this;
|
|
604
|
-
}
|
|
605
|
-
version(version, customFlags = "-v, --version") {
|
|
606
|
-
this.versionNumber = version;
|
|
607
|
-
this.option(customFlags, "Display version number");
|
|
608
|
-
return this;
|
|
609
|
-
}
|
|
610
|
-
example(example) {
|
|
611
|
-
this.examples.push(example);
|
|
612
|
-
return this;
|
|
613
|
-
}
|
|
614
|
-
option(rawName, description, config) {
|
|
615
|
-
const option = new Option(rawName, description, config);
|
|
616
|
-
this.options.push(option);
|
|
617
|
-
return this;
|
|
618
|
-
}
|
|
619
|
-
alias(name) {
|
|
620
|
-
this.aliasNames.push(name);
|
|
621
|
-
return this;
|
|
622
|
-
}
|
|
623
|
-
action(callback) {
|
|
624
|
-
this.commandAction = callback;
|
|
625
|
-
return this;
|
|
626
|
-
}
|
|
627
|
-
isMatched(name) {
|
|
628
|
-
return this.name === name || this.aliasNames.includes(name);
|
|
629
|
-
}
|
|
630
|
-
get isDefaultCommand() {
|
|
631
|
-
return this.name === "" || this.aliasNames.includes("!");
|
|
632
|
-
}
|
|
633
|
-
get isGlobalCommand() {
|
|
634
|
-
return this instanceof GlobalCommand;
|
|
635
|
-
}
|
|
636
|
-
hasOption(name) {
|
|
637
|
-
name = name.split(".")[0];
|
|
638
|
-
return this.options.find((option) => {
|
|
639
|
-
return option.names.includes(name);
|
|
640
|
-
});
|
|
641
|
-
}
|
|
642
|
-
outputHelp() {
|
|
643
|
-
const { name, commands } = this.cli;
|
|
644
|
-
const {
|
|
645
|
-
versionNumber,
|
|
646
|
-
options: globalOptions,
|
|
647
|
-
helpCallback
|
|
648
|
-
} = this.cli.globalCommand;
|
|
649
|
-
let sections = [
|
|
650
|
-
{
|
|
651
|
-
body: `${name}${versionNumber ? `/${versionNumber}` : ""}`
|
|
652
|
-
}
|
|
653
|
-
];
|
|
654
|
-
sections.push({
|
|
655
|
-
title: "Usage",
|
|
656
|
-
body: ` $ ${name} ${this.usageText || this.rawName}`
|
|
657
|
-
});
|
|
658
|
-
const showCommands = (this.isGlobalCommand || this.isDefaultCommand) && commands.length > 0;
|
|
659
|
-
if (showCommands) {
|
|
660
|
-
const longestCommandName = findLongest(commands.map((command) => command.rawName));
|
|
661
|
-
sections.push({
|
|
662
|
-
title: "Commands",
|
|
663
|
-
body: commands.map((command) => {
|
|
664
|
-
return ` ${padRight(command.rawName, longestCommandName.length)} ${command.description}`;
|
|
665
|
-
}).join(`
|
|
666
|
-
`)
|
|
667
|
-
});
|
|
668
|
-
sections.push({
|
|
669
|
-
title: `For more info, run any command with the \`--help\` flag`,
|
|
670
|
-
body: commands.map((command) => ` $ ${name}${command.name === "" ? "" : ` ${command.name}`} --help`).join(`
|
|
671
|
-
`)
|
|
672
|
-
});
|
|
673
|
-
}
|
|
674
|
-
let options = this.isGlobalCommand ? globalOptions : [...this.options, ...globalOptions || []];
|
|
675
|
-
if (!this.isGlobalCommand && !this.isDefaultCommand) {
|
|
676
|
-
options = options.filter((option) => option.name !== "version");
|
|
677
|
-
}
|
|
678
|
-
if (options.length > 0) {
|
|
679
|
-
const longestOptionName = findLongest(options.map((option) => option.rawName));
|
|
680
|
-
sections.push({
|
|
681
|
-
title: "Options",
|
|
682
|
-
body: options.map((option) => {
|
|
683
|
-
return ` ${padRight(option.rawName, longestOptionName.length)} ${option.description} ${option.config.default === undefined ? "" : `(default: ${option.config.default})`}`;
|
|
684
|
-
}).join(`
|
|
685
|
-
`)
|
|
686
|
-
});
|
|
687
|
-
}
|
|
688
|
-
if (this.examples.length > 0) {
|
|
689
|
-
sections.push({
|
|
690
|
-
title: "Examples",
|
|
691
|
-
body: this.examples.map((example) => {
|
|
692
|
-
if (typeof example === "function") {
|
|
693
|
-
return example(name);
|
|
694
|
-
}
|
|
695
|
-
return example;
|
|
696
|
-
}).join(`
|
|
697
|
-
`)
|
|
698
|
-
});
|
|
699
|
-
}
|
|
700
|
-
if (helpCallback) {
|
|
701
|
-
sections = helpCallback(sections) || sections;
|
|
702
|
-
}
|
|
703
|
-
console.log(sections.map((section) => {
|
|
704
|
-
return section.title ? `${section.title}:
|
|
705
|
-
${section.body}` : section.body;
|
|
706
|
-
}).join(`
|
|
707
|
-
|
|
708
|
-
`));
|
|
709
|
-
}
|
|
710
|
-
outputVersion() {
|
|
711
|
-
const { name } = this.cli;
|
|
712
|
-
const { versionNumber } = this.cli.globalCommand;
|
|
713
|
-
if (versionNumber) {
|
|
714
|
-
console.log(`${name}/${versionNumber} ${platformInfo}`);
|
|
715
|
-
}
|
|
716
|
-
}
|
|
717
|
-
checkRequiredArgs() {
|
|
718
|
-
const minimalArgsCount = this.args.filter((arg) => arg.required).length;
|
|
719
|
-
if (this.cli.args.length < minimalArgsCount) {
|
|
720
|
-
throw new CACError(`missing required args for command \`${this.rawName}\``);
|
|
721
|
-
}
|
|
722
|
-
}
|
|
723
|
-
checkUnknownOptions() {
|
|
724
|
-
const { options, globalCommand } = this.cli;
|
|
725
|
-
if (!this.config.allowUnknownOptions) {
|
|
726
|
-
for (const name of Object.keys(options)) {
|
|
727
|
-
if (name !== "--" && !this.hasOption(name) && !globalCommand.hasOption(name)) {
|
|
728
|
-
throw new CACError(`Unknown option \`${name.length > 1 ? `--${name}` : `-${name}`}\``);
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
}
|
|
732
|
-
}
|
|
733
|
-
checkOptionValue() {
|
|
734
|
-
const { options: parsedOptions, globalCommand } = this.cli;
|
|
735
|
-
const options = [...globalCommand.options, ...this.options];
|
|
736
|
-
for (const option of options) {
|
|
737
|
-
const value = parsedOptions[option.name.split(".")[0]];
|
|
738
|
-
if (option.required) {
|
|
739
|
-
const hasNegated = options.some((o) => o.negated && o.names.includes(option.name));
|
|
740
|
-
if (value === true || value === false && !hasNegated) {
|
|
741
|
-
throw new CACError(`option \`${option.rawName}\` value is missing`);
|
|
742
|
-
}
|
|
743
|
-
}
|
|
744
|
-
}
|
|
745
|
-
}
|
|
746
|
-
}
|
|
747
|
-
|
|
748
|
-
class GlobalCommand extends Command {
|
|
749
|
-
constructor(cli) {
|
|
750
|
-
super("@@global@@", "", {}, cli);
|
|
751
|
-
}
|
|
752
|
-
}
|
|
753
|
-
var __assign = Object.assign;
|
|
754
|
-
|
|
755
|
-
class CAC extends EventEmitter {
|
|
756
|
-
constructor(name = "") {
|
|
757
|
-
super();
|
|
758
|
-
this.name = name;
|
|
759
|
-
this.commands = [];
|
|
760
|
-
this.rawArgs = [];
|
|
761
|
-
this.args = [];
|
|
762
|
-
this.options = {};
|
|
763
|
-
this.globalCommand = new GlobalCommand(this);
|
|
764
|
-
this.globalCommand.usage("<command> [options]");
|
|
765
|
-
}
|
|
766
|
-
usage(text) {
|
|
767
|
-
this.globalCommand.usage(text);
|
|
768
|
-
return this;
|
|
769
|
-
}
|
|
770
|
-
command(rawName, description, config) {
|
|
771
|
-
const command = new Command(rawName, description || "", config, this);
|
|
772
|
-
command.globalCommand = this.globalCommand;
|
|
773
|
-
this.commands.push(command);
|
|
774
|
-
return command;
|
|
775
|
-
}
|
|
776
|
-
option(rawName, description, config) {
|
|
777
|
-
this.globalCommand.option(rawName, description, config);
|
|
778
|
-
return this;
|
|
779
|
-
}
|
|
780
|
-
help(callback) {
|
|
781
|
-
this.globalCommand.option("-h, --help", "Display this message");
|
|
782
|
-
this.globalCommand.helpCallback = callback;
|
|
783
|
-
this.showHelpOnExit = true;
|
|
784
|
-
return this;
|
|
785
|
-
}
|
|
786
|
-
version(version, customFlags = "-v, --version") {
|
|
787
|
-
this.globalCommand.version(version, customFlags);
|
|
788
|
-
this.showVersionOnExit = true;
|
|
789
|
-
return this;
|
|
790
|
-
}
|
|
791
|
-
example(example) {
|
|
792
|
-
this.globalCommand.example(example);
|
|
793
|
-
return this;
|
|
794
|
-
}
|
|
795
|
-
outputHelp() {
|
|
796
|
-
if (this.matchedCommand) {
|
|
797
|
-
this.matchedCommand.outputHelp();
|
|
798
|
-
} else {
|
|
799
|
-
this.globalCommand.outputHelp();
|
|
800
|
-
}
|
|
801
|
-
}
|
|
802
|
-
outputVersion() {
|
|
803
|
-
this.globalCommand.outputVersion();
|
|
804
|
-
}
|
|
805
|
-
setParsedInfo({ args, options }, matchedCommand, matchedCommandName) {
|
|
806
|
-
this.args = args;
|
|
807
|
-
this.options = options;
|
|
808
|
-
if (matchedCommand) {
|
|
809
|
-
this.matchedCommand = matchedCommand;
|
|
810
|
-
}
|
|
811
|
-
if (matchedCommandName) {
|
|
812
|
-
this.matchedCommandName = matchedCommandName;
|
|
813
|
-
}
|
|
814
|
-
return this;
|
|
815
|
-
}
|
|
816
|
-
unsetMatchedCommand() {
|
|
817
|
-
this.matchedCommand = undefined;
|
|
818
|
-
this.matchedCommandName = undefined;
|
|
819
|
-
}
|
|
820
|
-
parse(argv = processArgs, {
|
|
821
|
-
run = true
|
|
822
|
-
} = {}) {
|
|
823
|
-
this.rawArgs = argv;
|
|
824
|
-
if (!this.name) {
|
|
825
|
-
this.name = argv[1] ? getFileName(argv[1]) : "cli";
|
|
826
|
-
}
|
|
827
|
-
let shouldParse = true;
|
|
828
|
-
for (const command of this.commands) {
|
|
829
|
-
const parsed = this.mri(argv.slice(2), command);
|
|
830
|
-
const commandName = parsed.args[0];
|
|
831
|
-
if (command.isMatched(commandName)) {
|
|
832
|
-
shouldParse = false;
|
|
833
|
-
const parsedInfo = __assign(__assign({}, parsed), {
|
|
834
|
-
args: parsed.args.slice(1)
|
|
835
|
-
});
|
|
836
|
-
this.setParsedInfo(parsedInfo, command, commandName);
|
|
837
|
-
this.emit(`command:${commandName}`, command);
|
|
838
|
-
}
|
|
839
|
-
}
|
|
840
|
-
if (shouldParse) {
|
|
841
|
-
for (const command of this.commands) {
|
|
842
|
-
if (command.name === "") {
|
|
843
|
-
shouldParse = false;
|
|
844
|
-
const parsed = this.mri(argv.slice(2), command);
|
|
845
|
-
this.setParsedInfo(parsed, command);
|
|
846
|
-
this.emit(`command:!`, command);
|
|
847
|
-
}
|
|
848
|
-
}
|
|
849
|
-
}
|
|
850
|
-
if (shouldParse) {
|
|
851
|
-
const parsed = this.mri(argv.slice(2));
|
|
852
|
-
this.setParsedInfo(parsed);
|
|
853
|
-
}
|
|
854
|
-
if (this.options.help && this.showHelpOnExit) {
|
|
855
|
-
this.outputHelp();
|
|
856
|
-
run = false;
|
|
857
|
-
this.unsetMatchedCommand();
|
|
858
|
-
}
|
|
859
|
-
if (this.options.version && this.showVersionOnExit && this.matchedCommandName == null) {
|
|
860
|
-
this.outputVersion();
|
|
861
|
-
run = false;
|
|
862
|
-
this.unsetMatchedCommand();
|
|
863
|
-
}
|
|
864
|
-
const parsedArgv = { args: this.args, options: this.options };
|
|
865
|
-
if (run) {
|
|
866
|
-
this.runMatchedCommand();
|
|
867
|
-
}
|
|
868
|
-
if (!this.matchedCommand && this.args[0]) {
|
|
869
|
-
this.emit("command:*");
|
|
870
|
-
}
|
|
871
|
-
return parsedArgv;
|
|
872
|
-
}
|
|
873
|
-
mri(argv, command) {
|
|
874
|
-
const cliOptions = [
|
|
875
|
-
...this.globalCommand.options,
|
|
876
|
-
...command ? command.options : []
|
|
877
|
-
];
|
|
878
|
-
const mriOptions = getMriOptions(cliOptions);
|
|
879
|
-
let argsAfterDoubleDashes = [];
|
|
880
|
-
const doubleDashesIndex = argv.indexOf("--");
|
|
881
|
-
if (doubleDashesIndex > -1) {
|
|
882
|
-
argsAfterDoubleDashes = argv.slice(doubleDashesIndex + 1);
|
|
883
|
-
argv = argv.slice(0, doubleDashesIndex);
|
|
884
|
-
}
|
|
885
|
-
let parsed = mri2(argv, mriOptions);
|
|
886
|
-
parsed = Object.keys(parsed).reduce((res, name) => {
|
|
887
|
-
return __assign(__assign({}, res), {
|
|
888
|
-
[camelcaseOptionName(name)]: parsed[name]
|
|
889
|
-
});
|
|
890
|
-
}, { _: [] });
|
|
891
|
-
const args = parsed._;
|
|
892
|
-
const options = {
|
|
893
|
-
"--": argsAfterDoubleDashes
|
|
894
|
-
};
|
|
895
|
-
const ignoreDefault = command && command.config.ignoreOptionDefaultValue ? command.config.ignoreOptionDefaultValue : this.globalCommand.config.ignoreOptionDefaultValue;
|
|
896
|
-
let transforms = Object.create(null);
|
|
897
|
-
for (const cliOption of cliOptions) {
|
|
898
|
-
if (!ignoreDefault && cliOption.config.default !== undefined) {
|
|
899
|
-
for (const name of cliOption.names) {
|
|
900
|
-
options[name] = cliOption.config.default;
|
|
901
|
-
}
|
|
902
|
-
}
|
|
903
|
-
if (Array.isArray(cliOption.config.type)) {
|
|
904
|
-
if (transforms[cliOption.name] === undefined) {
|
|
905
|
-
transforms[cliOption.name] = Object.create(null);
|
|
906
|
-
transforms[cliOption.name]["shouldTransform"] = true;
|
|
907
|
-
transforms[cliOption.name]["transformFunction"] = cliOption.config.type[0];
|
|
908
|
-
}
|
|
909
|
-
}
|
|
910
|
-
}
|
|
911
|
-
for (const key of Object.keys(parsed)) {
|
|
912
|
-
if (key !== "_") {
|
|
913
|
-
const keys = key.split(".");
|
|
914
|
-
setDotProp(options, keys, parsed[key]);
|
|
915
|
-
setByType(options, transforms);
|
|
916
|
-
}
|
|
917
|
-
}
|
|
918
|
-
return {
|
|
919
|
-
args,
|
|
920
|
-
options
|
|
921
|
-
};
|
|
922
|
-
}
|
|
923
|
-
runMatchedCommand() {
|
|
924
|
-
const { args, options, matchedCommand: command } = this;
|
|
925
|
-
if (!command || !command.commandAction)
|
|
926
|
-
return;
|
|
927
|
-
command.checkUnknownOptions();
|
|
928
|
-
command.checkOptionValue();
|
|
929
|
-
command.checkRequiredArgs();
|
|
930
|
-
const actionArgs = [];
|
|
931
|
-
command.args.forEach((arg, index) => {
|
|
932
|
-
if (arg.variadic) {
|
|
933
|
-
actionArgs.push(args.slice(index));
|
|
934
|
-
} else {
|
|
935
|
-
actionArgs.push(args[index]);
|
|
936
|
-
}
|
|
937
|
-
});
|
|
938
|
-
actionArgs.push(options);
|
|
939
|
-
return command.commandAction.apply(this, actionArgs);
|
|
940
|
-
}
|
|
941
|
-
}
|
|
942
|
-
var cac = (name = "") => new CAC(name);
|
|
943
|
-
var dist_default = cac;
|
|
944
|
-
|
|
945
|
-
// lib/config.ts
|
|
946
|
-
import { existsSync, readFileSync } from "fs";
|
|
947
|
-
import { join } from "path";
|
|
948
|
-
import { homedir } from "os";
|
|
949
|
-
var DEFAULT_CONFIG = {
|
|
950
|
-
ollama: {
|
|
951
|
-
url: "http://localhost:11434",
|
|
952
|
-
defaultModel: "qwen3-coder:30b"
|
|
953
|
-
},
|
|
954
|
-
docker: {
|
|
955
|
-
composeFile: "./docker-compose.yml",
|
|
956
|
-
gpu: true
|
|
957
|
-
},
|
|
958
|
-
claude: {
|
|
959
|
-
extraArgs: []
|
|
960
|
-
}
|
|
961
|
-
};
|
|
962
|
-
function getConfigPaths() {
|
|
963
|
-
const paths = [];
|
|
964
|
-
const projectConfig = join(process.cwd(), ".loclaude", "config.json");
|
|
965
|
-
paths.push(projectConfig);
|
|
966
|
-
const userConfig = join(homedir(), ".config", "loclaude", "config.json");
|
|
967
|
-
paths.push(userConfig);
|
|
968
|
-
return paths;
|
|
969
|
-
}
|
|
970
|
-
function findConfigFile() {
|
|
971
|
-
for (const path of getConfigPaths()) {
|
|
972
|
-
if (existsSync(path)) {
|
|
973
|
-
return path;
|
|
974
|
-
}
|
|
975
|
-
}
|
|
976
|
-
return null;
|
|
977
|
-
}
|
|
978
|
-
function loadConfigFile(path) {
|
|
979
|
-
try {
|
|
980
|
-
const content = readFileSync(path, "utf-8");
|
|
981
|
-
return JSON.parse(content);
|
|
982
|
-
} catch (error) {
|
|
983
|
-
console.warn(`Warning: Failed to parse config file ${path}`);
|
|
984
|
-
return null;
|
|
985
|
-
}
|
|
986
|
-
}
|
|
987
|
-
function loadConfigFiles() {
|
|
988
|
-
const paths = getConfigPaths();
|
|
989
|
-
let merged = {};
|
|
990
|
-
for (const path of paths.reverse()) {
|
|
991
|
-
if (existsSync(path)) {
|
|
992
|
-
const config = loadConfigFile(path);
|
|
993
|
-
if (config) {
|
|
994
|
-
merged = deepMerge(merged, config);
|
|
995
|
-
}
|
|
996
|
-
}
|
|
997
|
-
}
|
|
998
|
-
return merged;
|
|
999
|
-
}
|
|
1000
|
-
function loadEnvConfig() {
|
|
1001
|
-
const config = {};
|
|
1002
|
-
if (process.env.OLLAMA_URL) {
|
|
1003
|
-
config.ollama = config.ollama || {};
|
|
1004
|
-
config.ollama.url = process.env.OLLAMA_URL;
|
|
1005
|
-
}
|
|
1006
|
-
if (process.env.OLLAMA_MODEL) {
|
|
1007
|
-
config.ollama = config.ollama || {};
|
|
1008
|
-
config.ollama.defaultModel = process.env.OLLAMA_MODEL;
|
|
1009
|
-
}
|
|
1010
|
-
if (process.env.LOCLAUDE_COMPOSE_FILE) {
|
|
1011
|
-
config.docker = config.docker || {};
|
|
1012
|
-
config.docker.composeFile = process.env.LOCLAUDE_COMPOSE_FILE;
|
|
1013
|
-
}
|
|
1014
|
-
if (process.env.LOCLAUDE_GPU !== undefined) {
|
|
1015
|
-
config.docker = config.docker || {};
|
|
1016
|
-
config.docker.gpu = process.env.LOCLAUDE_GPU !== "false" && process.env.LOCLAUDE_GPU !== "0";
|
|
1017
|
-
}
|
|
1018
|
-
return config;
|
|
1019
|
-
}
|
|
1020
|
-
function deepMerge(a, b) {
|
|
1021
|
-
const result = { ...a };
|
|
1022
|
-
for (const key in b) {
|
|
1023
|
-
if (Object.prototype.hasOwnProperty.call(b, key)) {
|
|
1024
|
-
const bValue = b[key];
|
|
1025
|
-
const aValue = a[key];
|
|
1026
|
-
if (bValue !== undefined && typeof bValue === "object" && !Array.isArray(bValue) && aValue !== undefined && typeof aValue === "object" && !Array.isArray(aValue)) {
|
|
1027
|
-
result[key] = deepMerge(aValue, bValue);
|
|
1028
|
-
} else if (bValue !== undefined) {
|
|
1029
|
-
result[key] = bValue;
|
|
1030
|
-
}
|
|
1031
|
-
}
|
|
1032
|
-
}
|
|
1033
|
-
return result;
|
|
1034
|
-
}
|
|
1035
|
-
function mergeWithDefaults(partial) {
|
|
1036
|
-
return {
|
|
1037
|
-
ollama: {
|
|
1038
|
-
...DEFAULT_CONFIG.ollama,
|
|
1039
|
-
...partial.ollama
|
|
1040
|
-
},
|
|
1041
|
-
docker: {
|
|
1042
|
-
...DEFAULT_CONFIG.docker,
|
|
1043
|
-
...partial.docker
|
|
1044
|
-
},
|
|
1045
|
-
claude: {
|
|
1046
|
-
...DEFAULT_CONFIG.claude,
|
|
1047
|
-
...partial.claude
|
|
1048
|
-
}
|
|
1049
|
-
};
|
|
1050
|
-
}
|
|
1051
|
-
var cachedConfig = null;
|
|
1052
|
-
function loadConfig() {
|
|
1053
|
-
if (cachedConfig) {
|
|
1054
|
-
return cachedConfig;
|
|
1055
|
-
}
|
|
1056
|
-
const fileConfig = loadConfigFiles();
|
|
1057
|
-
const envConfig = loadEnvConfig();
|
|
1058
|
-
const merged = deepMerge(fileConfig, envConfig);
|
|
1059
|
-
cachedConfig = mergeWithDefaults(merged);
|
|
1060
|
-
return cachedConfig;
|
|
1061
|
-
}
|
|
1062
|
-
function getActiveConfigPath() {
|
|
1063
|
-
return findConfigFile();
|
|
1064
|
-
}
|
|
1065
|
-
function getConfigSearchPaths() {
|
|
1066
|
-
return getConfigPaths();
|
|
1067
|
-
}
|
|
1068
|
-
function getOllamaUrl() {
|
|
1069
|
-
return loadConfig().ollama.url;
|
|
1070
|
-
}
|
|
1071
|
-
function getDefaultModel() {
|
|
1072
|
-
return loadConfig().ollama.defaultModel;
|
|
1073
|
-
}
|
|
1074
|
-
function getComposeFile() {
|
|
1075
|
-
return loadConfig().docker.composeFile;
|
|
1076
|
-
}
|
|
1077
|
-
function getClaudeExtraArgs() {
|
|
1078
|
-
return loadConfig().claude.extraArgs;
|
|
1079
|
-
}
|
|
1080
|
-
|
|
1081
|
-
// lib/constants.ts
|
|
1082
|
-
var OLLAMA_URL = getOllamaUrl();
|
|
1083
|
-
var DEFAULT_MODEL = getDefaultModel();
|
|
1084
|
-
|
|
1085
|
-
// ../../node_modules/.bun/@inquirer+core@11.1.1+b219b5910764fa5c/node_modules/@inquirer/core/dist/lib/key.js
|
|
1086
|
-
var isUpKey = (key, keybindings = []) => key.name === "up" || keybindings.includes("vim") && key.name === "k" || keybindings.includes("emacs") && key.ctrl && key.name === "p";
|
|
1087
|
-
var isDownKey = (key, keybindings = []) => key.name === "down" || keybindings.includes("vim") && key.name === "j" || keybindings.includes("emacs") && key.ctrl && key.name === "n";
|
|
1088
|
-
var isBackspaceKey = (key) => key.name === "backspace";
|
|
1089
|
-
var isNumberKey = (key) => "1234567890".includes(key.name);
|
|
1090
|
-
var isEnterKey = (key) => key.name === "enter" || key.name === "return";
|
|
1091
|
-
// ../../node_modules/.bun/@inquirer+core@11.1.1+b219b5910764fa5c/node_modules/@inquirer/core/dist/lib/errors.js
|
|
1092
|
-
class AbortPromptError extends Error {
|
|
1093
|
-
name = "AbortPromptError";
|
|
1094
|
-
message = "Prompt was aborted";
|
|
1095
|
-
constructor(options) {
|
|
1096
|
-
super();
|
|
1097
|
-
this.cause = options?.cause;
|
|
1098
|
-
}
|
|
1099
|
-
}
|
|
1100
|
-
|
|
1101
|
-
class CancelPromptError extends Error {
|
|
1102
|
-
name = "CancelPromptError";
|
|
1103
|
-
message = "Prompt was canceled";
|
|
1104
|
-
}
|
|
1105
|
-
|
|
1106
|
-
class ExitPromptError extends Error {
|
|
1107
|
-
name = "ExitPromptError";
|
|
1108
|
-
}
|
|
1109
|
-
|
|
1110
|
-
class HookError extends Error {
|
|
1111
|
-
name = "HookError";
|
|
1112
|
-
}
|
|
1113
|
-
|
|
1114
|
-
class ValidationError extends Error {
|
|
1115
|
-
name = "ValidationError";
|
|
1116
|
-
}
|
|
1117
|
-
// ../../node_modules/.bun/@inquirer+core@11.1.1+b219b5910764fa5c/node_modules/@inquirer/core/dist/lib/use-state.js
|
|
1118
|
-
import { AsyncResource as AsyncResource2 } from "async_hooks";
|
|
1119
|
-
|
|
1120
|
-
// ../../node_modules/.bun/@inquirer+core@11.1.1+b219b5910764fa5c/node_modules/@inquirer/core/dist/lib/hook-engine.js
|
|
1121
|
-
import { AsyncLocalStorage, AsyncResource } from "async_hooks";
|
|
1122
|
-
var hookStorage = new AsyncLocalStorage;
|
|
1123
|
-
function createStore(rl) {
|
|
1124
|
-
const store = {
|
|
1125
|
-
rl,
|
|
1126
|
-
hooks: [],
|
|
1127
|
-
hooksCleanup: [],
|
|
1128
|
-
hooksEffect: [],
|
|
1129
|
-
index: 0,
|
|
1130
|
-
handleChange() {}
|
|
1131
|
-
};
|
|
1132
|
-
return store;
|
|
1133
|
-
}
|
|
1134
|
-
function withHooks(rl, cb) {
|
|
1135
|
-
const store = createStore(rl);
|
|
1136
|
-
return hookStorage.run(store, () => {
|
|
1137
|
-
function cycle(render) {
|
|
1138
|
-
store.handleChange = () => {
|
|
1139
|
-
store.index = 0;
|
|
1140
|
-
render();
|
|
1141
|
-
};
|
|
1142
|
-
store.handleChange();
|
|
1143
|
-
}
|
|
1144
|
-
return cb(cycle);
|
|
1145
|
-
});
|
|
1146
|
-
}
|
|
1147
|
-
function getStore() {
|
|
1148
|
-
const store = hookStorage.getStore();
|
|
1149
|
-
if (!store) {
|
|
1150
|
-
throw new HookError("[Inquirer] Hook functions can only be called from within a prompt");
|
|
1151
|
-
}
|
|
1152
|
-
return store;
|
|
1153
|
-
}
|
|
1154
|
-
function readline() {
|
|
1155
|
-
return getStore().rl;
|
|
1156
|
-
}
|
|
1157
|
-
function withUpdates(fn) {
|
|
1158
|
-
const wrapped = (...args) => {
|
|
1159
|
-
const store = getStore();
|
|
1160
|
-
let shouldUpdate = false;
|
|
1161
|
-
const oldHandleChange = store.handleChange;
|
|
1162
|
-
store.handleChange = () => {
|
|
1163
|
-
shouldUpdate = true;
|
|
1164
|
-
};
|
|
1165
|
-
const returnValue = fn(...args);
|
|
1166
|
-
if (shouldUpdate) {
|
|
1167
|
-
oldHandleChange();
|
|
1168
|
-
}
|
|
1169
|
-
store.handleChange = oldHandleChange;
|
|
1170
|
-
return returnValue;
|
|
1171
|
-
};
|
|
1172
|
-
return AsyncResource.bind(wrapped);
|
|
1173
|
-
}
|
|
1174
|
-
function withPointer(cb) {
|
|
1175
|
-
const store = getStore();
|
|
1176
|
-
const { index } = store;
|
|
1177
|
-
const pointer = {
|
|
1178
|
-
get() {
|
|
1179
|
-
return store.hooks[index];
|
|
1180
|
-
},
|
|
1181
|
-
set(value) {
|
|
1182
|
-
store.hooks[index] = value;
|
|
1183
|
-
},
|
|
1184
|
-
initialized: index in store.hooks
|
|
1185
|
-
};
|
|
1186
|
-
const returnValue = cb(pointer);
|
|
1187
|
-
store.index++;
|
|
1188
|
-
return returnValue;
|
|
1189
|
-
}
|
|
1190
|
-
function handleChange() {
|
|
1191
|
-
getStore().handleChange();
|
|
1192
|
-
}
|
|
1193
|
-
var effectScheduler = {
|
|
1194
|
-
queue(cb) {
|
|
1195
|
-
const store = getStore();
|
|
1196
|
-
const { index } = store;
|
|
1197
|
-
store.hooksEffect.push(() => {
|
|
1198
|
-
store.hooksCleanup[index]?.();
|
|
1199
|
-
const cleanFn = cb(readline());
|
|
1200
|
-
if (cleanFn != null && typeof cleanFn !== "function") {
|
|
1201
|
-
throw new ValidationError("useEffect return value must be a cleanup function or nothing.");
|
|
1202
|
-
}
|
|
1203
|
-
store.hooksCleanup[index] = cleanFn;
|
|
1204
|
-
});
|
|
1205
|
-
},
|
|
1206
|
-
run() {
|
|
1207
|
-
const store = getStore();
|
|
1208
|
-
withUpdates(() => {
|
|
1209
|
-
store.hooksEffect.forEach((effect) => {
|
|
1210
|
-
effect();
|
|
1211
|
-
});
|
|
1212
|
-
store.hooksEffect.length = 0;
|
|
1213
|
-
})();
|
|
1214
|
-
},
|
|
1215
|
-
clearAll() {
|
|
1216
|
-
const store = getStore();
|
|
1217
|
-
store.hooksCleanup.forEach((cleanFn) => {
|
|
1218
|
-
cleanFn?.();
|
|
1219
|
-
});
|
|
1220
|
-
store.hooksEffect.length = 0;
|
|
1221
|
-
store.hooksCleanup.length = 0;
|
|
1222
|
-
}
|
|
1223
|
-
};
|
|
1224
|
-
|
|
1225
|
-
// ../../node_modules/.bun/@inquirer+core@11.1.1+b219b5910764fa5c/node_modules/@inquirer/core/dist/lib/use-state.js
|
|
1226
|
-
function useState(defaultValue) {
|
|
1227
|
-
return withPointer((pointer) => {
|
|
1228
|
-
const setState = AsyncResource2.bind(function setState(newValue) {
|
|
1229
|
-
if (pointer.get() !== newValue) {
|
|
1230
|
-
pointer.set(newValue);
|
|
1231
|
-
handleChange();
|
|
1232
|
-
}
|
|
1233
|
-
});
|
|
1234
|
-
if (pointer.initialized) {
|
|
1235
|
-
return [pointer.get(), setState];
|
|
1236
|
-
}
|
|
1237
|
-
const value = typeof defaultValue === "function" ? defaultValue() : defaultValue;
|
|
1238
|
-
pointer.set(value);
|
|
1239
|
-
return [value, setState];
|
|
1240
|
-
});
|
|
1241
|
-
}
|
|
1242
|
-
|
|
1243
|
-
// ../../node_modules/.bun/@inquirer+core@11.1.1+b219b5910764fa5c/node_modules/@inquirer/core/dist/lib/use-effect.js
|
|
1244
|
-
function useEffect(cb, depArray) {
|
|
1245
|
-
withPointer((pointer) => {
|
|
1246
|
-
const oldDeps = pointer.get();
|
|
1247
|
-
const hasChanged = !Array.isArray(oldDeps) || depArray.some((dep, i) => !Object.is(dep, oldDeps[i]));
|
|
1248
|
-
if (hasChanged) {
|
|
1249
|
-
effectScheduler.queue(cb);
|
|
1250
|
-
}
|
|
1251
|
-
pointer.set(depArray);
|
|
1252
|
-
});
|
|
1253
|
-
}
|
|
1254
|
-
|
|
1255
|
-
// ../../node_modules/.bun/@inquirer+core@11.1.1+b219b5910764fa5c/node_modules/@inquirer/core/dist/lib/theme.js
|
|
1256
|
-
import { styleText } from "util";
|
|
1257
|
-
|
|
1258
|
-
// ../../node_modules/.bun/@inquirer+figures@2.0.3/node_modules/@inquirer/figures/dist/index.js
|
|
1259
|
-
import process2 from "process";
|
|
1260
|
-
function isUnicodeSupported() {
|
|
1261
|
-
if (process2.platform !== "win32") {
|
|
1262
|
-
return process2.env["TERM"] !== "linux";
|
|
1263
|
-
}
|
|
1264
|
-
return Boolean(process2.env["WT_SESSION"]) || Boolean(process2.env["TERMINUS_SUBLIME"]) || process2.env["ConEmuTask"] === "{cmd::Cmder}" || process2.env["TERM_PROGRAM"] === "Terminus-Sublime" || process2.env["TERM_PROGRAM"] === "vscode" || process2.env["TERM"] === "xterm-256color" || process2.env["TERM"] === "alacritty" || process2.env["TERMINAL_EMULATOR"] === "JetBrains-JediTerm";
|
|
1265
|
-
}
|
|
1266
|
-
var common = {
|
|
1267
|
-
circleQuestionMark: "(?)",
|
|
1268
|
-
questionMarkPrefix: "(?)",
|
|
1269
|
-
square: "\u2588",
|
|
1270
|
-
squareDarkShade: "\u2593",
|
|
1271
|
-
squareMediumShade: "\u2592",
|
|
1272
|
-
squareLightShade: "\u2591",
|
|
1273
|
-
squareTop: "\u2580",
|
|
1274
|
-
squareBottom: "\u2584",
|
|
1275
|
-
squareLeft: "\u258C",
|
|
1276
|
-
squareRight: "\u2590",
|
|
1277
|
-
squareCenter: "\u25A0",
|
|
1278
|
-
bullet: "\u25CF",
|
|
1279
|
-
dot: "\u2024",
|
|
1280
|
-
ellipsis: "\u2026",
|
|
1281
|
-
pointerSmall: "\u203A",
|
|
1282
|
-
triangleUp: "\u25B2",
|
|
1283
|
-
triangleUpSmall: "\u25B4",
|
|
1284
|
-
triangleDown: "\u25BC",
|
|
1285
|
-
triangleDownSmall: "\u25BE",
|
|
1286
|
-
triangleLeftSmall: "\u25C2",
|
|
1287
|
-
triangleRightSmall: "\u25B8",
|
|
1288
|
-
home: "\u2302",
|
|
1289
|
-
heart: "\u2665",
|
|
1290
|
-
musicNote: "\u266A",
|
|
1291
|
-
musicNoteBeamed: "\u266B",
|
|
1292
|
-
arrowUp: "\u2191",
|
|
1293
|
-
arrowDown: "\u2193",
|
|
1294
|
-
arrowLeft: "\u2190",
|
|
1295
|
-
arrowRight: "\u2192",
|
|
1296
|
-
arrowLeftRight: "\u2194",
|
|
1297
|
-
arrowUpDown: "\u2195",
|
|
1298
|
-
almostEqual: "\u2248",
|
|
1299
|
-
notEqual: "\u2260",
|
|
1300
|
-
lessOrEqual: "\u2264",
|
|
1301
|
-
greaterOrEqual: "\u2265",
|
|
1302
|
-
identical: "\u2261",
|
|
1303
|
-
infinity: "\u221E",
|
|
1304
|
-
subscriptZero: "\u2080",
|
|
1305
|
-
subscriptOne: "\u2081",
|
|
1306
|
-
subscriptTwo: "\u2082",
|
|
1307
|
-
subscriptThree: "\u2083",
|
|
1308
|
-
subscriptFour: "\u2084",
|
|
1309
|
-
subscriptFive: "\u2085",
|
|
1310
|
-
subscriptSix: "\u2086",
|
|
1311
|
-
subscriptSeven: "\u2087",
|
|
1312
|
-
subscriptEight: "\u2088",
|
|
1313
|
-
subscriptNine: "\u2089",
|
|
1314
|
-
oneHalf: "\xBD",
|
|
1315
|
-
oneThird: "\u2153",
|
|
1316
|
-
oneQuarter: "\xBC",
|
|
1317
|
-
oneFifth: "\u2155",
|
|
1318
|
-
oneSixth: "\u2159",
|
|
1319
|
-
oneEighth: "\u215B",
|
|
1320
|
-
twoThirds: "\u2154",
|
|
1321
|
-
twoFifths: "\u2156",
|
|
1322
|
-
threeQuarters: "\xBE",
|
|
1323
|
-
threeFifths: "\u2157",
|
|
1324
|
-
threeEighths: "\u215C",
|
|
1325
|
-
fourFifths: "\u2158",
|
|
1326
|
-
fiveSixths: "\u215A",
|
|
1327
|
-
fiveEighths: "\u215D",
|
|
1328
|
-
sevenEighths: "\u215E",
|
|
1329
|
-
line: "\u2500",
|
|
1330
|
-
lineBold: "\u2501",
|
|
1331
|
-
lineDouble: "\u2550",
|
|
1332
|
-
lineDashed0: "\u2504",
|
|
1333
|
-
lineDashed1: "\u2505",
|
|
1334
|
-
lineDashed2: "\u2508",
|
|
1335
|
-
lineDashed3: "\u2509",
|
|
1336
|
-
lineDashed4: "\u254C",
|
|
1337
|
-
lineDashed5: "\u254D",
|
|
1338
|
-
lineDashed6: "\u2574",
|
|
1339
|
-
lineDashed7: "\u2576",
|
|
1340
|
-
lineDashed8: "\u2578",
|
|
1341
|
-
lineDashed9: "\u257A",
|
|
1342
|
-
lineDashed10: "\u257C",
|
|
1343
|
-
lineDashed11: "\u257E",
|
|
1344
|
-
lineDashed12: "\u2212",
|
|
1345
|
-
lineDashed13: "\u2013",
|
|
1346
|
-
lineDashed14: "\u2010",
|
|
1347
|
-
lineDashed15: "\u2043",
|
|
1348
|
-
lineVertical: "\u2502",
|
|
1349
|
-
lineVerticalBold: "\u2503",
|
|
1350
|
-
lineVerticalDouble: "\u2551",
|
|
1351
|
-
lineVerticalDashed0: "\u2506",
|
|
1352
|
-
lineVerticalDashed1: "\u2507",
|
|
1353
|
-
lineVerticalDashed2: "\u250A",
|
|
1354
|
-
lineVerticalDashed3: "\u250B",
|
|
1355
|
-
lineVerticalDashed4: "\u254E",
|
|
1356
|
-
lineVerticalDashed5: "\u254F",
|
|
1357
|
-
lineVerticalDashed6: "\u2575",
|
|
1358
|
-
lineVerticalDashed7: "\u2577",
|
|
1359
|
-
lineVerticalDashed8: "\u2579",
|
|
1360
|
-
lineVerticalDashed9: "\u257B",
|
|
1361
|
-
lineVerticalDashed10: "\u257D",
|
|
1362
|
-
lineVerticalDashed11: "\u257F",
|
|
1363
|
-
lineDownLeft: "\u2510",
|
|
1364
|
-
lineDownLeftArc: "\u256E",
|
|
1365
|
-
lineDownBoldLeftBold: "\u2513",
|
|
1366
|
-
lineDownBoldLeft: "\u2512",
|
|
1367
|
-
lineDownLeftBold: "\u2511",
|
|
1368
|
-
lineDownDoubleLeftDouble: "\u2557",
|
|
1369
|
-
lineDownDoubleLeft: "\u2556",
|
|
1370
|
-
lineDownLeftDouble: "\u2555",
|
|
1371
|
-
lineDownRight: "\u250C",
|
|
1372
|
-
lineDownRightArc: "\u256D",
|
|
1373
|
-
lineDownBoldRightBold: "\u250F",
|
|
1374
|
-
lineDownBoldRight: "\u250E",
|
|
1375
|
-
lineDownRightBold: "\u250D",
|
|
1376
|
-
lineDownDoubleRightDouble: "\u2554",
|
|
1377
|
-
lineDownDoubleRight: "\u2553",
|
|
1378
|
-
lineDownRightDouble: "\u2552",
|
|
1379
|
-
lineUpLeft: "\u2518",
|
|
1380
|
-
lineUpLeftArc: "\u256F",
|
|
1381
|
-
lineUpBoldLeftBold: "\u251B",
|
|
1382
|
-
lineUpBoldLeft: "\u251A",
|
|
1383
|
-
lineUpLeftBold: "\u2519",
|
|
1384
|
-
lineUpDoubleLeftDouble: "\u255D",
|
|
1385
|
-
lineUpDoubleLeft: "\u255C",
|
|
1386
|
-
lineUpLeftDouble: "\u255B",
|
|
1387
|
-
lineUpRight: "\u2514",
|
|
1388
|
-
lineUpRightArc: "\u2570",
|
|
1389
|
-
lineUpBoldRightBold: "\u2517",
|
|
1390
|
-
lineUpBoldRight: "\u2516",
|
|
1391
|
-
lineUpRightBold: "\u2515",
|
|
1392
|
-
lineUpDoubleRightDouble: "\u255A",
|
|
1393
|
-
lineUpDoubleRight: "\u2559",
|
|
1394
|
-
lineUpRightDouble: "\u2558",
|
|
1395
|
-
lineUpDownLeft: "\u2524",
|
|
1396
|
-
lineUpBoldDownBoldLeftBold: "\u252B",
|
|
1397
|
-
lineUpBoldDownBoldLeft: "\u2528",
|
|
1398
|
-
lineUpDownLeftBold: "\u2525",
|
|
1399
|
-
lineUpBoldDownLeftBold: "\u2529",
|
|
1400
|
-
lineUpDownBoldLeftBold: "\u252A",
|
|
1401
|
-
lineUpDownBoldLeft: "\u2527",
|
|
1402
|
-
lineUpBoldDownLeft: "\u2526",
|
|
1403
|
-
lineUpDoubleDownDoubleLeftDouble: "\u2563",
|
|
1404
|
-
lineUpDoubleDownDoubleLeft: "\u2562",
|
|
1405
|
-
lineUpDownLeftDouble: "\u2561",
|
|
1406
|
-
lineUpDownRight: "\u251C",
|
|
1407
|
-
lineUpBoldDownBoldRightBold: "\u2523",
|
|
1408
|
-
lineUpBoldDownBoldRight: "\u2520",
|
|
1409
|
-
lineUpDownRightBold: "\u251D",
|
|
1410
|
-
lineUpBoldDownRightBold: "\u2521",
|
|
1411
|
-
lineUpDownBoldRightBold: "\u2522",
|
|
1412
|
-
lineUpDownBoldRight: "\u251F",
|
|
1413
|
-
lineUpBoldDownRight: "\u251E",
|
|
1414
|
-
lineUpDoubleDownDoubleRightDouble: "\u2560",
|
|
1415
|
-
lineUpDoubleDownDoubleRight: "\u255F",
|
|
1416
|
-
lineUpDownRightDouble: "\u255E",
|
|
1417
|
-
lineDownLeftRight: "\u252C",
|
|
1418
|
-
lineDownBoldLeftBoldRightBold: "\u2533",
|
|
1419
|
-
lineDownLeftBoldRightBold: "\u252F",
|
|
1420
|
-
lineDownBoldLeftRight: "\u2530",
|
|
1421
|
-
lineDownBoldLeftBoldRight: "\u2531",
|
|
1422
|
-
lineDownBoldLeftRightBold: "\u2532",
|
|
1423
|
-
lineDownLeftRightBold: "\u252E",
|
|
1424
|
-
lineDownLeftBoldRight: "\u252D",
|
|
1425
|
-
lineDownDoubleLeftDoubleRightDouble: "\u2566",
|
|
1426
|
-
lineDownDoubleLeftRight: "\u2565",
|
|
1427
|
-
lineDownLeftDoubleRightDouble: "\u2564",
|
|
1428
|
-
lineUpLeftRight: "\u2534",
|
|
1429
|
-
lineUpBoldLeftBoldRightBold: "\u253B",
|
|
1430
|
-
lineUpLeftBoldRightBold: "\u2537",
|
|
1431
|
-
lineUpBoldLeftRight: "\u2538",
|
|
1432
|
-
lineUpBoldLeftBoldRight: "\u2539",
|
|
1433
|
-
lineUpBoldLeftRightBold: "\u253A",
|
|
1434
|
-
lineUpLeftRightBold: "\u2536",
|
|
1435
|
-
lineUpLeftBoldRight: "\u2535",
|
|
1436
|
-
lineUpDoubleLeftDoubleRightDouble: "\u2569",
|
|
1437
|
-
lineUpDoubleLeftRight: "\u2568",
|
|
1438
|
-
lineUpLeftDoubleRightDouble: "\u2567",
|
|
1439
|
-
lineUpDownLeftRight: "\u253C",
|
|
1440
|
-
lineUpBoldDownBoldLeftBoldRightBold: "\u254B",
|
|
1441
|
-
lineUpDownBoldLeftBoldRightBold: "\u2548",
|
|
1442
|
-
lineUpBoldDownLeftBoldRightBold: "\u2547",
|
|
1443
|
-
lineUpBoldDownBoldLeftRightBold: "\u254A",
|
|
1444
|
-
lineUpBoldDownBoldLeftBoldRight: "\u2549",
|
|
1445
|
-
lineUpBoldDownLeftRight: "\u2540",
|
|
1446
|
-
lineUpDownBoldLeftRight: "\u2541",
|
|
1447
|
-
lineUpDownLeftBoldRight: "\u253D",
|
|
1448
|
-
lineUpDownLeftRightBold: "\u253E",
|
|
1449
|
-
lineUpBoldDownBoldLeftRight: "\u2542",
|
|
1450
|
-
lineUpDownLeftBoldRightBold: "\u253F",
|
|
1451
|
-
lineUpBoldDownLeftBoldRight: "\u2543",
|
|
1452
|
-
lineUpBoldDownLeftRightBold: "\u2544",
|
|
1453
|
-
lineUpDownBoldLeftBoldRight: "\u2545",
|
|
1454
|
-
lineUpDownBoldLeftRightBold: "\u2546",
|
|
1455
|
-
lineUpDoubleDownDoubleLeftDoubleRightDouble: "\u256C",
|
|
1456
|
-
lineUpDoubleDownDoubleLeftRight: "\u256B",
|
|
1457
|
-
lineUpDownLeftDoubleRightDouble: "\u256A",
|
|
1458
|
-
lineCross: "\u2573",
|
|
1459
|
-
lineBackslash: "\u2572",
|
|
1460
|
-
lineSlash: "\u2571"
|
|
1461
|
-
};
|
|
1462
|
-
var specialMainSymbols = {
|
|
1463
|
-
tick: "\u2714",
|
|
1464
|
-
info: "\u2139",
|
|
1465
|
-
warning: "\u26A0",
|
|
1466
|
-
cross: "\u2718",
|
|
1467
|
-
squareSmall: "\u25FB",
|
|
1468
|
-
squareSmallFilled: "\u25FC",
|
|
1469
|
-
circle: "\u25EF",
|
|
1470
|
-
circleFilled: "\u25C9",
|
|
1471
|
-
circleDotted: "\u25CC",
|
|
1472
|
-
circleDouble: "\u25CE",
|
|
1473
|
-
circleCircle: "\u24DE",
|
|
1474
|
-
circleCross: "\u24E7",
|
|
1475
|
-
circlePipe: "\u24BE",
|
|
1476
|
-
radioOn: "\u25C9",
|
|
1477
|
-
radioOff: "\u25EF",
|
|
1478
|
-
checkboxOn: "\u2612",
|
|
1479
|
-
checkboxOff: "\u2610",
|
|
1480
|
-
checkboxCircleOn: "\u24E7",
|
|
1481
|
-
checkboxCircleOff: "\u24BE",
|
|
1482
|
-
pointer: "\u276F",
|
|
1483
|
-
triangleUpOutline: "\u25B3",
|
|
1484
|
-
triangleLeft: "\u25C0",
|
|
1485
|
-
triangleRight: "\u25B6",
|
|
1486
|
-
lozenge: "\u25C6",
|
|
1487
|
-
lozengeOutline: "\u25C7",
|
|
1488
|
-
hamburger: "\u2630",
|
|
1489
|
-
smiley: "\u32E1",
|
|
1490
|
-
mustache: "\u0DF4",
|
|
1491
|
-
star: "\u2605",
|
|
1492
|
-
play: "\u25B6",
|
|
1493
|
-
nodejs: "\u2B22",
|
|
1494
|
-
oneSeventh: "\u2150",
|
|
1495
|
-
oneNinth: "\u2151",
|
|
1496
|
-
oneTenth: "\u2152"
|
|
1497
|
-
};
|
|
1498
|
-
var specialFallbackSymbols = {
|
|
1499
|
-
tick: "\u221A",
|
|
1500
|
-
info: "i",
|
|
1501
|
-
warning: "\u203C",
|
|
1502
|
-
cross: "\xD7",
|
|
1503
|
-
squareSmall: "\u25A1",
|
|
1504
|
-
squareSmallFilled: "\u25A0",
|
|
1505
|
-
circle: "( )",
|
|
1506
|
-
circleFilled: "(*)",
|
|
1507
|
-
circleDotted: "( )",
|
|
1508
|
-
circleDouble: "( )",
|
|
1509
|
-
circleCircle: "(\u25CB)",
|
|
1510
|
-
circleCross: "(\xD7)",
|
|
1511
|
-
circlePipe: "(\u2502)",
|
|
1512
|
-
radioOn: "(*)",
|
|
1513
|
-
radioOff: "( )",
|
|
1514
|
-
checkboxOn: "[\xD7]",
|
|
1515
|
-
checkboxOff: "[ ]",
|
|
1516
|
-
checkboxCircleOn: "(\xD7)",
|
|
1517
|
-
checkboxCircleOff: "( )",
|
|
1518
|
-
pointer: ">",
|
|
1519
|
-
triangleUpOutline: "\u2206",
|
|
1520
|
-
triangleLeft: "\u25C4",
|
|
1521
|
-
triangleRight: "\u25BA",
|
|
1522
|
-
lozenge: "\u2666",
|
|
1523
|
-
lozengeOutline: "\u25CA",
|
|
1524
|
-
hamburger: "\u2261",
|
|
1525
|
-
smiley: "\u263A",
|
|
1526
|
-
mustache: "\u250C\u2500\u2510",
|
|
1527
|
-
star: "\u2736",
|
|
1528
|
-
play: "\u25BA",
|
|
1529
|
-
nodejs: "\u2666",
|
|
1530
|
-
oneSeventh: "1/7",
|
|
1531
|
-
oneNinth: "1/9",
|
|
1532
|
-
oneTenth: "1/10"
|
|
1533
|
-
};
|
|
1534
|
-
var mainSymbols = {
|
|
1535
|
-
...common,
|
|
1536
|
-
...specialMainSymbols
|
|
1537
|
-
};
|
|
1538
|
-
var fallbackSymbols = {
|
|
1539
|
-
...common,
|
|
1540
|
-
...specialFallbackSymbols
|
|
1541
|
-
};
|
|
1542
|
-
var shouldUseMain = isUnicodeSupported();
|
|
1543
|
-
var figures = shouldUseMain ? mainSymbols : fallbackSymbols;
|
|
1544
|
-
var dist_default2 = figures;
|
|
1545
|
-
var replacements = Object.entries(specialMainSymbols);
|
|
1546
|
-
|
|
1547
|
-
// ../../node_modules/.bun/@inquirer+core@11.1.1+b219b5910764fa5c/node_modules/@inquirer/core/dist/lib/theme.js
|
|
1548
|
-
var defaultTheme = {
|
|
1549
|
-
prefix: {
|
|
1550
|
-
idle: styleText("blue", "?"),
|
|
1551
|
-
done: styleText("green", dist_default2.tick)
|
|
1552
|
-
},
|
|
1553
|
-
spinner: {
|
|
1554
|
-
interval: 80,
|
|
1555
|
-
frames: ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"].map((frame) => styleText("yellow", frame))
|
|
1556
|
-
},
|
|
1557
|
-
style: {
|
|
1558
|
-
answer: (text) => styleText("cyan", text),
|
|
1559
|
-
message: (text) => styleText("bold", text),
|
|
1560
|
-
error: (text) => styleText("red", `> ${text}`),
|
|
1561
|
-
defaultAnswer: (text) => styleText("dim", `(${text})`),
|
|
1562
|
-
help: (text) => styleText("dim", text),
|
|
1563
|
-
highlight: (text) => styleText("cyan", text),
|
|
1564
|
-
key: (text) => styleText("cyan", styleText("bold", `<${text}>`))
|
|
1565
|
-
}
|
|
1566
|
-
};
|
|
1567
|
-
|
|
1568
|
-
// ../../node_modules/.bun/@inquirer+core@11.1.1+b219b5910764fa5c/node_modules/@inquirer/core/dist/lib/make-theme.js
|
|
1569
|
-
function isPlainObject(value) {
|
|
1570
|
-
if (typeof value !== "object" || value === null)
|
|
1571
|
-
return false;
|
|
1572
|
-
let proto = value;
|
|
1573
|
-
while (Object.getPrototypeOf(proto) !== null) {
|
|
1574
|
-
proto = Object.getPrototypeOf(proto);
|
|
1575
|
-
}
|
|
1576
|
-
return Object.getPrototypeOf(value) === proto;
|
|
1577
|
-
}
|
|
1578
|
-
function deepMerge2(...objects) {
|
|
1579
|
-
const output = {};
|
|
1580
|
-
for (const obj of objects) {
|
|
1581
|
-
for (const [key, value] of Object.entries(obj)) {
|
|
1582
|
-
const prevValue = output[key];
|
|
1583
|
-
output[key] = isPlainObject(prevValue) && isPlainObject(value) ? deepMerge2(prevValue, value) : value;
|
|
1584
|
-
}
|
|
1585
|
-
}
|
|
1586
|
-
return output;
|
|
1587
|
-
}
|
|
1588
|
-
function makeTheme(...themes) {
|
|
1589
|
-
const themesToMerge = [
|
|
1590
|
-
defaultTheme,
|
|
1591
|
-
...themes.filter((theme) => theme != null)
|
|
1592
|
-
];
|
|
1593
|
-
return deepMerge2(...themesToMerge);
|
|
1594
|
-
}
|
|
1595
|
-
|
|
1596
|
-
// ../../node_modules/.bun/@inquirer+core@11.1.1+b219b5910764fa5c/node_modules/@inquirer/core/dist/lib/use-prefix.js
|
|
1597
|
-
function usePrefix({ status = "idle", theme }) {
|
|
1598
|
-
const [showLoader, setShowLoader] = useState(false);
|
|
1599
|
-
const [tick, setTick] = useState(0);
|
|
1600
|
-
const { prefix, spinner } = makeTheme(theme);
|
|
1601
|
-
useEffect(() => {
|
|
1602
|
-
if (status === "loading") {
|
|
1603
|
-
let tickInterval;
|
|
1604
|
-
let inc = -1;
|
|
1605
|
-
const delayTimeout = setTimeout(() => {
|
|
1606
|
-
setShowLoader(true);
|
|
1607
|
-
tickInterval = setInterval(() => {
|
|
1608
|
-
inc = inc + 1;
|
|
1609
|
-
setTick(inc % spinner.frames.length);
|
|
1610
|
-
}, spinner.interval);
|
|
1611
|
-
}, 300);
|
|
1612
|
-
return () => {
|
|
1613
|
-
clearTimeout(delayTimeout);
|
|
1614
|
-
clearInterval(tickInterval);
|
|
1615
|
-
};
|
|
1616
|
-
} else {
|
|
1617
|
-
setShowLoader(false);
|
|
1618
|
-
}
|
|
1619
|
-
}, [status]);
|
|
1620
|
-
if (showLoader) {
|
|
1621
|
-
return spinner.frames[tick];
|
|
1622
|
-
}
|
|
1623
|
-
const iconName = status === "loading" ? "idle" : status;
|
|
1624
|
-
return typeof prefix === "string" ? prefix : prefix[iconName] ?? prefix["idle"];
|
|
1625
|
-
}
|
|
1626
|
-
// ../../node_modules/.bun/@inquirer+core@11.1.1+b219b5910764fa5c/node_modules/@inquirer/core/dist/lib/use-memo.js
|
|
1627
|
-
function useMemo(fn, dependencies) {
|
|
1628
|
-
return withPointer((pointer) => {
|
|
1629
|
-
const prev = pointer.get();
|
|
1630
|
-
if (!prev || prev.dependencies.length !== dependencies.length || prev.dependencies.some((dep, i) => dep !== dependencies[i])) {
|
|
1631
|
-
const value = fn();
|
|
1632
|
-
pointer.set({ value, dependencies });
|
|
1633
|
-
return value;
|
|
1634
|
-
}
|
|
1635
|
-
return prev.value;
|
|
1636
|
-
});
|
|
1637
|
-
}
|
|
1638
|
-
// ../../node_modules/.bun/@inquirer+core@11.1.1+b219b5910764fa5c/node_modules/@inquirer/core/dist/lib/use-ref.js
|
|
1639
|
-
function useRef(val) {
|
|
1640
|
-
return useState({ current: val })[0];
|
|
1641
|
-
}
|
|
1642
|
-
// ../../node_modules/.bun/@inquirer+core@11.1.1+b219b5910764fa5c/node_modules/@inquirer/core/dist/lib/use-keypress.js
|
|
1643
|
-
function useKeypress(userHandler) {
|
|
1644
|
-
const signal = useRef(userHandler);
|
|
1645
|
-
signal.current = userHandler;
|
|
1646
|
-
useEffect((rl) => {
|
|
1647
|
-
let ignore = false;
|
|
1648
|
-
const handler = withUpdates((_input, event) => {
|
|
1649
|
-
if (ignore)
|
|
1650
|
-
return;
|
|
1651
|
-
signal.current(event, rl);
|
|
1652
|
-
});
|
|
1653
|
-
rl.input.on("keypress", handler);
|
|
1654
|
-
return () => {
|
|
1655
|
-
ignore = true;
|
|
1656
|
-
rl.input.removeListener("keypress", handler);
|
|
1657
|
-
};
|
|
1658
|
-
}, []);
|
|
1659
|
-
}
|
|
1660
|
-
// ../../node_modules/.bun/@inquirer+core@11.1.1+b219b5910764fa5c/node_modules/@inquirer/core/dist/lib/utils.js
|
|
1661
|
-
var import_cli_width = __toESM(require_cli_width(), 1);
|
|
1662
|
-
|
|
1663
|
-
// ../../node_modules/.bun/ansi-regex@6.2.2/node_modules/ansi-regex/index.js
|
|
1664
|
-
function ansiRegex({ onlyFirst = false } = {}) {
|
|
1665
|
-
const ST = "(?:\\u0007|\\u001B\\u005C|\\u009C)";
|
|
1666
|
-
const osc = `(?:\\u001B\\][\\s\\S]*?${ST})`;
|
|
1667
|
-
const csi = "[\\u001B\\u009B][[\\]()#;?]*(?:\\d{1,4}(?:[;:]\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]";
|
|
1668
|
-
const pattern = `${osc}|${csi}`;
|
|
1669
|
-
return new RegExp(pattern, onlyFirst ? undefined : "g");
|
|
1670
|
-
}
|
|
1671
|
-
|
|
1672
|
-
// ../../node_modules/.bun/strip-ansi@7.1.2/node_modules/strip-ansi/index.js
|
|
1673
|
-
var regex = ansiRegex();
|
|
1674
|
-
function stripAnsi(string) {
|
|
1675
|
-
if (typeof string !== "string") {
|
|
1676
|
-
throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``);
|
|
1677
|
-
}
|
|
1678
|
-
return string.replace(regex, "");
|
|
1679
|
-
}
|
|
1680
|
-
|
|
1681
|
-
// ../../node_modules/.bun/get-east-asian-width@1.4.0/node_modules/get-east-asian-width/lookup.js
|
|
1682
|
-
function isAmbiguous(x) {
|
|
1683
|
-
return x === 161 || x === 164 || x === 167 || x === 168 || x === 170 || x === 173 || x === 174 || x >= 176 && x <= 180 || x >= 182 && x <= 186 || x >= 188 && x <= 191 || x === 198 || x === 208 || x === 215 || x === 216 || x >= 222 && x <= 225 || x === 230 || x >= 232 && x <= 234 || x === 236 || x === 237 || x === 240 || x === 242 || x === 243 || x >= 247 && x <= 250 || x === 252 || x === 254 || x === 257 || x === 273 || x === 275 || x === 283 || x === 294 || x === 295 || x === 299 || x >= 305 && x <= 307 || x === 312 || x >= 319 && x <= 322 || x === 324 || x >= 328 && x <= 331 || x === 333 || x === 338 || x === 339 || x === 358 || x === 359 || x === 363 || x === 462 || x === 464 || x === 466 || x === 468 || x === 470 || x === 472 || x === 474 || x === 476 || x === 593 || x === 609 || x === 708 || x === 711 || x >= 713 && x <= 715 || x === 717 || x === 720 || x >= 728 && x <= 731 || x === 733 || x === 735 || x >= 768 && x <= 879 || x >= 913 && x <= 929 || x >= 931 && x <= 937 || x >= 945 && x <= 961 || x >= 963 && x <= 969 || x === 1025 || x >= 1040 && x <= 1103 || x === 1105 || x === 8208 || x >= 8211 && x <= 8214 || x === 8216 || x === 8217 || x === 8220 || x === 8221 || x >= 8224 && x <= 8226 || x >= 8228 && x <= 8231 || x === 8240 || x === 8242 || x === 8243 || x === 8245 || x === 8251 || x === 8254 || x === 8308 || x === 8319 || x >= 8321 && x <= 8324 || x === 8364 || x === 8451 || x === 8453 || x === 8457 || x === 8467 || x === 8470 || x === 8481 || x === 8482 || x === 8486 || x === 8491 || x === 8531 || x === 8532 || x >= 8539 && x <= 8542 || x >= 8544 && x <= 8555 || x >= 8560 && x <= 8569 || x === 8585 || x >= 8592 && x <= 8601 || x === 8632 || x === 8633 || x === 8658 || x === 8660 || x === 8679 || x === 8704 || x === 8706 || x === 8707 || x === 8711 || x === 8712 || x === 8715 || x === 8719 || x === 8721 || x === 8725 || x === 8730 || x >= 8733 && x <= 8736 || x === 8739 || x === 8741 || x >= 8743 && x <= 8748 || x === 8750 || x >= 8756 && x <= 8759 || x === 8764 || x === 8765 || x === 8776 || x === 8780 || x === 8786 || x === 8800 || x === 8801 || x >= 8804 && x <= 8807 || x === 8810 || x === 8811 || x === 8814 || x === 8815 || x === 8834 || x === 8835 || x === 8838 || x === 8839 || x === 8853 || x === 8857 || x === 8869 || x === 8895 || x === 8978 || x >= 9312 && x <= 9449 || x >= 9451 && x <= 9547 || x >= 9552 && x <= 9587 || x >= 9600 && x <= 9615 || x >= 9618 && x <= 9621 || x === 9632 || x === 9633 || x >= 9635 && x <= 9641 || x === 9650 || x === 9651 || x === 9654 || x === 9655 || x === 9660 || x === 9661 || x === 9664 || x === 9665 || x >= 9670 && x <= 9672 || x === 9675 || x >= 9678 && x <= 9681 || x >= 9698 && x <= 9701 || x === 9711 || x === 9733 || x === 9734 || x === 9737 || x === 9742 || x === 9743 || x === 9756 || x === 9758 || x === 9792 || x === 9794 || x === 9824 || x === 9825 || x >= 9827 && x <= 9829 || x >= 9831 && x <= 9834 || x === 9836 || x === 9837 || x === 9839 || x === 9886 || x === 9887 || x === 9919 || x >= 9926 && x <= 9933 || x >= 9935 && x <= 9939 || x >= 9941 && x <= 9953 || x === 9955 || x === 9960 || x === 9961 || x >= 9963 && x <= 9969 || x === 9972 || x >= 9974 && x <= 9977 || x === 9979 || x === 9980 || x === 9982 || x === 9983 || x === 10045 || x >= 10102 && x <= 10111 || x >= 11094 && x <= 11097 || x >= 12872 && x <= 12879 || x >= 57344 && x <= 63743 || x >= 65024 && x <= 65039 || x === 65533 || x >= 127232 && x <= 127242 || x >= 127248 && x <= 127277 || x >= 127280 && x <= 127337 || x >= 127344 && x <= 127373 || x === 127375 || x === 127376 || x >= 127387 && x <= 127404 || x >= 917760 && x <= 917999 || x >= 983040 && x <= 1048573 || x >= 1048576 && x <= 1114109;
|
|
1684
|
-
}
|
|
1685
|
-
function isFullWidth(x) {
|
|
1686
|
-
return x === 12288 || x >= 65281 && x <= 65376 || x >= 65504 && x <= 65510;
|
|
1687
|
-
}
|
|
1688
|
-
function isWide(x) {
|
|
1689
|
-
return x >= 4352 && x <= 4447 || x === 8986 || x === 8987 || x === 9001 || x === 9002 || x >= 9193 && x <= 9196 || x === 9200 || x === 9203 || x === 9725 || x === 9726 || x === 9748 || x === 9749 || x >= 9776 && x <= 9783 || x >= 9800 && x <= 9811 || x === 9855 || x >= 9866 && x <= 9871 || x === 9875 || x === 9889 || x === 9898 || x === 9899 || x === 9917 || x === 9918 || x === 9924 || x === 9925 || x === 9934 || x === 9940 || x === 9962 || x === 9970 || x === 9971 || x === 9973 || x === 9978 || x === 9981 || x === 9989 || x === 9994 || x === 9995 || x === 10024 || x === 10060 || x === 10062 || x >= 10067 && x <= 10069 || x === 10071 || x >= 10133 && x <= 10135 || x === 10160 || x === 10175 || x === 11035 || x === 11036 || x === 11088 || x === 11093 || x >= 11904 && x <= 11929 || x >= 11931 && x <= 12019 || x >= 12032 && x <= 12245 || x >= 12272 && x <= 12287 || x >= 12289 && x <= 12350 || x >= 12353 && x <= 12438 || x >= 12441 && x <= 12543 || x >= 12549 && x <= 12591 || x >= 12593 && x <= 12686 || x >= 12688 && x <= 12773 || x >= 12783 && x <= 12830 || x >= 12832 && x <= 12871 || x >= 12880 && x <= 42124 || x >= 42128 && x <= 42182 || x >= 43360 && x <= 43388 || x >= 44032 && x <= 55203 || x >= 63744 && x <= 64255 || x >= 65040 && x <= 65049 || x >= 65072 && x <= 65106 || x >= 65108 && x <= 65126 || x >= 65128 && x <= 65131 || x >= 94176 && x <= 94180 || x >= 94192 && x <= 94198 || x >= 94208 && x <= 101589 || x >= 101631 && x <= 101662 || x >= 101760 && x <= 101874 || x >= 110576 && x <= 110579 || x >= 110581 && x <= 110587 || x === 110589 || x === 110590 || x >= 110592 && x <= 110882 || x === 110898 || x >= 110928 && x <= 110930 || x === 110933 || x >= 110948 && x <= 110951 || x >= 110960 && x <= 111355 || x >= 119552 && x <= 119638 || x >= 119648 && x <= 119670 || x === 126980 || x === 127183 || x === 127374 || x >= 127377 && x <= 127386 || x >= 127488 && x <= 127490 || x >= 127504 && x <= 127547 || x >= 127552 && x <= 127560 || x === 127568 || x === 127569 || x >= 127584 && x <= 127589 || x >= 127744 && x <= 127776 || x >= 127789 && x <= 127797 || x >= 127799 && x <= 127868 || x >= 127870 && x <= 127891 || x >= 127904 && x <= 127946 || x >= 127951 && x <= 127955 || x >= 127968 && x <= 127984 || x === 127988 || x >= 127992 && x <= 128062 || x === 128064 || x >= 128066 && x <= 128252 || x >= 128255 && x <= 128317 || x >= 128331 && x <= 128334 || x >= 128336 && x <= 128359 || x === 128378 || x === 128405 || x === 128406 || x === 128420 || x >= 128507 && x <= 128591 || x >= 128640 && x <= 128709 || x === 128716 || x >= 128720 && x <= 128722 || x >= 128725 && x <= 128728 || x >= 128732 && x <= 128735 || x === 128747 || x === 128748 || x >= 128756 && x <= 128764 || x >= 128992 && x <= 129003 || x === 129008 || x >= 129292 && x <= 129338 || x >= 129340 && x <= 129349 || x >= 129351 && x <= 129535 || x >= 129648 && x <= 129660 || x >= 129664 && x <= 129674 || x >= 129678 && x <= 129734 || x === 129736 || x >= 129741 && x <= 129756 || x >= 129759 && x <= 129770 || x >= 129775 && x <= 129784 || x >= 131072 && x <= 196605 || x >= 196608 && x <= 262141;
|
|
1690
|
-
}
|
|
1691
|
-
|
|
1692
|
-
// ../../node_modules/.bun/get-east-asian-width@1.4.0/node_modules/get-east-asian-width/index.js
|
|
1693
|
-
function validate(codePoint) {
|
|
1694
|
-
if (!Number.isSafeInteger(codePoint)) {
|
|
1695
|
-
throw new TypeError(`Expected a code point, got \`${typeof codePoint}\`.`);
|
|
1696
|
-
}
|
|
1697
|
-
}
|
|
1698
|
-
function eastAsianWidth(codePoint, { ambiguousAsWide = false } = {}) {
|
|
1699
|
-
validate(codePoint);
|
|
1700
|
-
if (isFullWidth(codePoint) || isWide(codePoint) || ambiguousAsWide && isAmbiguous(codePoint)) {
|
|
1701
|
-
return 2;
|
|
1702
|
-
}
|
|
1703
|
-
return 1;
|
|
1704
|
-
}
|
|
1705
|
-
|
|
1706
|
-
// ../../node_modules/.bun/emoji-regex@10.6.0/node_modules/emoji-regex/index.mjs
|
|
1707
|
-
var emoji_regex_default = () => {
|
|
1708
|
-
return /[#*0-9]\uFE0F?\u20E3|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26AA\u26B0\u26B1\u26BD\u26BE\u26C4\u26C8\u26CF\u26D1\u26E9\u26F0-\u26F5\u26F7\u26F8\u26FA\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B55\u3030\u303D\u3297\u3299]\uFE0F?|[\u261D\u270C\u270D](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|[\u270A\u270B](?:\uD83C[\uDFFB-\uDFFF])?|[\u23E9-\u23EC\u23F0\u23F3\u25FD\u2693\u26A1\u26AB\u26C5\u26CE\u26D4\u26EA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2795-\u2797\u27B0\u27BF\u2B50]|\u26D3\uFE0F?(?:\u200D\uD83D\uDCA5)?|\u26F9(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|\u2764\uFE0F?(?:\u200D(?:\uD83D\uDD25|\uD83E\uDE79))?|\uD83C(?:[\uDC04\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]\uFE0F?|[\uDF85\uDFC2\uDFC7](?:\uD83C[\uDFFB-\uDFFF])?|[\uDFC4\uDFCA](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDFCB\uDFCC](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF43\uDF45-\uDF4A\uDF4C-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uDDE6\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF]|\uDDE7\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF]|\uDDE8\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF7\uDDFA-\uDDFF]|\uDDE9\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF]|\uDDEA\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA]|\uDDEB\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7]|\uDDEC\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE]|\uDDED\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA]|\uDDEE\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9]|\uDDEF\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5]|\uDDF0\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF]|\uDDF1\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE]|\uDDF2\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF]|\uDDF3\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF]|\uDDF4\uD83C\uDDF2|\uDDF5\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE]|\uDDF6\uD83C\uDDE6|\uDDF7\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC]|\uDDF8\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF]|\uDDF9\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF]|\uDDFA\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF]|\uDDFB\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA]|\uDDFC\uD83C[\uDDEB\uDDF8]|\uDDFD\uD83C\uDDF0|\uDDFE\uD83C[\uDDEA\uDDF9]|\uDDFF\uD83C[\uDDE6\uDDF2\uDDFC]|\uDF44(?:\u200D\uD83D\uDFEB)?|\uDF4B(?:\u200D\uD83D\uDFE9)?|\uDFC3(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDFF3\uFE0F?(?:\u200D(?:\u26A7\uFE0F?|\uD83C\uDF08))?|\uDFF4(?:\u200D\u2620\uFE0F?|\uDB40\uDC67\uDB40\uDC62\uDB40(?:\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDC73\uDB40\uDC63\uDB40\uDC74|\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F)?)|\uD83D(?:[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3]\uFE0F?|[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC](?:\uD83C[\uDFFB-\uDFFF])?|[\uDC6E-\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4\uDEB5](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD74\uDD90](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC25\uDC27-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE41\uDE43\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED8\uDEDC-\uDEDF\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB\uDFF0]|\uDC08(?:\u200D\u2B1B)?|\uDC15(?:\u200D\uD83E\uDDBA)?|\uDC26(?:\u200D(?:\u2B1B|\uD83D\uDD25))?|\uDC3B(?:\u200D\u2744\uFE0F?)?|\uDC41\uFE0F?(?:\u200D\uD83D\uDDE8\uFE0F?)?|\uDC68(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDC68\uDC69]\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFC-\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFC-\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFD-\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFD\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFE])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFE]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?))?|\uDC69(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?[\uDC68\uDC69]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?|\uDC69\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?))|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFC-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFC-\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFD-\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFD\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFE])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFE]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFE])))?))?|\uDD75(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|\uDE2E(?:\u200D\uD83D\uDCA8)?|\uDE35(?:\u200D\uD83D\uDCAB)?|\uDE36(?:\u200D\uD83C\uDF2B\uFE0F?)?|\uDE42(?:\u200D[\u2194\u2195]\uFE0F?)?|\uDEB6(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?)|\uD83E(?:[\uDD0C\uDD0F\uDD18-\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5\uDEC3-\uDEC5\uDEF0\uDEF2-\uDEF8](?:\uD83C[\uDFFB-\uDFFF])?|[\uDD26\uDD35\uDD37-\uDD39\uDD3C-\uDD3E\uDDB8\uDDB9\uDDCD\uDDCF\uDDD4\uDDD6-\uDDDD](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDDDE\uDDDF](?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD0D\uDD0E\uDD10-\uDD17\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCC\uDDD0\uDDE0-\uDDFF\uDE70-\uDE7C\uDE80-\uDE8A\uDE8E-\uDEC2\uDEC6\uDEC8\uDECD-\uDEDC\uDEDF-\uDEEA\uDEEF]|\uDDCE(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDDD1(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1|\uDDD1\u200D\uD83E\uDDD2(?:\u200D\uD83E\uDDD2)?|\uDDD2(?:\u200D\uD83E\uDDD2)?))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE])))?))?|\uDEF1(?:\uD83C(?:\uDFFB(?:\u200D\uD83E\uDEF2\uD83C[\uDFFC-\uDFFF])?|\uDFFC(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFD-\uDFFF])?|\uDFFD(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])?|\uDFFE(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFD\uDFFF])?|\uDFFF(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFE])?))?)/g;
|
|
1709
|
-
};
|
|
1710
|
-
|
|
1711
|
-
// ../../node_modules/.bun/string-width@7.2.0/node_modules/string-width/index.js
|
|
1712
|
-
var segmenter = new Intl.Segmenter;
|
|
1713
|
-
var defaultIgnorableCodePointRegex = /^\p{Default_Ignorable_Code_Point}$/u;
|
|
1714
|
-
function stringWidth(string, options = {}) {
|
|
1715
|
-
if (typeof string !== "string" || string.length === 0) {
|
|
1716
|
-
return 0;
|
|
1717
|
-
}
|
|
1718
|
-
const {
|
|
1719
|
-
ambiguousIsNarrow = true,
|
|
1720
|
-
countAnsiEscapeCodes = false
|
|
1721
|
-
} = options;
|
|
1722
|
-
if (!countAnsiEscapeCodes) {
|
|
1723
|
-
string = stripAnsi(string);
|
|
1724
|
-
}
|
|
1725
|
-
if (string.length === 0) {
|
|
1726
|
-
return 0;
|
|
1727
|
-
}
|
|
1728
|
-
let width = 0;
|
|
1729
|
-
const eastAsianWidthOptions = { ambiguousAsWide: !ambiguousIsNarrow };
|
|
1730
|
-
for (const { segment: character } of segmenter.segment(string)) {
|
|
1731
|
-
const codePoint = character.codePointAt(0);
|
|
1732
|
-
if (codePoint <= 31 || codePoint >= 127 && codePoint <= 159) {
|
|
1733
|
-
continue;
|
|
1734
|
-
}
|
|
1735
|
-
if (codePoint >= 8203 && codePoint <= 8207 || codePoint === 65279) {
|
|
1736
|
-
continue;
|
|
1737
|
-
}
|
|
1738
|
-
if (codePoint >= 768 && codePoint <= 879 || codePoint >= 6832 && codePoint <= 6911 || codePoint >= 7616 && codePoint <= 7679 || codePoint >= 8400 && codePoint <= 8447 || codePoint >= 65056 && codePoint <= 65071) {
|
|
1739
|
-
continue;
|
|
1740
|
-
}
|
|
1741
|
-
if (codePoint >= 55296 && codePoint <= 57343) {
|
|
1742
|
-
continue;
|
|
1743
|
-
}
|
|
1744
|
-
if (codePoint >= 65024 && codePoint <= 65039) {
|
|
1745
|
-
continue;
|
|
1746
|
-
}
|
|
1747
|
-
if (defaultIgnorableCodePointRegex.test(character)) {
|
|
1748
|
-
continue;
|
|
1749
|
-
}
|
|
1750
|
-
if (emoji_regex_default().test(character)) {
|
|
1751
|
-
width += 2;
|
|
1752
|
-
continue;
|
|
1753
|
-
}
|
|
1754
|
-
width += eastAsianWidth(codePoint, eastAsianWidthOptions);
|
|
1755
|
-
}
|
|
1756
|
-
return width;
|
|
1757
|
-
}
|
|
1758
|
-
|
|
1759
|
-
// ../../node_modules/.bun/ansi-styles@6.2.3/node_modules/ansi-styles/index.js
|
|
1760
|
-
var ANSI_BACKGROUND_OFFSET = 10;
|
|
1761
|
-
var wrapAnsi16 = (offset = 0) => (code) => `\x1B[${code + offset}m`;
|
|
1762
|
-
var wrapAnsi256 = (offset = 0) => (code) => `\x1B[${38 + offset};5;${code}m`;
|
|
1763
|
-
var wrapAnsi16m = (offset = 0) => (red, green, blue) => `\x1B[${38 + offset};2;${red};${green};${blue}m`;
|
|
1764
|
-
var styles = {
|
|
1765
|
-
modifier: {
|
|
1766
|
-
reset: [0, 0],
|
|
1767
|
-
bold: [1, 22],
|
|
1768
|
-
dim: [2, 22],
|
|
1769
|
-
italic: [3, 23],
|
|
1770
|
-
underline: [4, 24],
|
|
1771
|
-
overline: [53, 55],
|
|
1772
|
-
inverse: [7, 27],
|
|
1773
|
-
hidden: [8, 28],
|
|
1774
|
-
strikethrough: [9, 29]
|
|
1775
|
-
},
|
|
1776
|
-
color: {
|
|
1777
|
-
black: [30, 39],
|
|
1778
|
-
red: [31, 39],
|
|
1779
|
-
green: [32, 39],
|
|
1780
|
-
yellow: [33, 39],
|
|
1781
|
-
blue: [34, 39],
|
|
1782
|
-
magenta: [35, 39],
|
|
1783
|
-
cyan: [36, 39],
|
|
1784
|
-
white: [37, 39],
|
|
1785
|
-
blackBright: [90, 39],
|
|
1786
|
-
gray: [90, 39],
|
|
1787
|
-
grey: [90, 39],
|
|
1788
|
-
redBright: [91, 39],
|
|
1789
|
-
greenBright: [92, 39],
|
|
1790
|
-
yellowBright: [93, 39],
|
|
1791
|
-
blueBright: [94, 39],
|
|
1792
|
-
magentaBright: [95, 39],
|
|
1793
|
-
cyanBright: [96, 39],
|
|
1794
|
-
whiteBright: [97, 39]
|
|
1795
|
-
},
|
|
1796
|
-
bgColor: {
|
|
1797
|
-
bgBlack: [40, 49],
|
|
1798
|
-
bgRed: [41, 49],
|
|
1799
|
-
bgGreen: [42, 49],
|
|
1800
|
-
bgYellow: [43, 49],
|
|
1801
|
-
bgBlue: [44, 49],
|
|
1802
|
-
bgMagenta: [45, 49],
|
|
1803
|
-
bgCyan: [46, 49],
|
|
1804
|
-
bgWhite: [47, 49],
|
|
1805
|
-
bgBlackBright: [100, 49],
|
|
1806
|
-
bgGray: [100, 49],
|
|
1807
|
-
bgGrey: [100, 49],
|
|
1808
|
-
bgRedBright: [101, 49],
|
|
1809
|
-
bgGreenBright: [102, 49],
|
|
1810
|
-
bgYellowBright: [103, 49],
|
|
1811
|
-
bgBlueBright: [104, 49],
|
|
1812
|
-
bgMagentaBright: [105, 49],
|
|
1813
|
-
bgCyanBright: [106, 49],
|
|
1814
|
-
bgWhiteBright: [107, 49]
|
|
1815
|
-
}
|
|
1816
|
-
};
|
|
1817
|
-
var modifierNames = Object.keys(styles.modifier);
|
|
1818
|
-
var foregroundColorNames = Object.keys(styles.color);
|
|
1819
|
-
var backgroundColorNames = Object.keys(styles.bgColor);
|
|
1820
|
-
var colorNames = [...foregroundColorNames, ...backgroundColorNames];
|
|
1821
|
-
function assembleStyles() {
|
|
1822
|
-
const codes = new Map;
|
|
1823
|
-
for (const [groupName, group] of Object.entries(styles)) {
|
|
1824
|
-
for (const [styleName, style] of Object.entries(group)) {
|
|
1825
|
-
styles[styleName] = {
|
|
1826
|
-
open: `\x1B[${style[0]}m`,
|
|
1827
|
-
close: `\x1B[${style[1]}m`
|
|
1828
|
-
};
|
|
1829
|
-
group[styleName] = styles[styleName];
|
|
1830
|
-
codes.set(style[0], style[1]);
|
|
1831
|
-
}
|
|
1832
|
-
Object.defineProperty(styles, groupName, {
|
|
1833
|
-
value: group,
|
|
1834
|
-
enumerable: false
|
|
1835
|
-
});
|
|
1836
|
-
}
|
|
1837
|
-
Object.defineProperty(styles, "codes", {
|
|
1838
|
-
value: codes,
|
|
1839
|
-
enumerable: false
|
|
1840
|
-
});
|
|
1841
|
-
styles.color.close = "\x1B[39m";
|
|
1842
|
-
styles.bgColor.close = "\x1B[49m";
|
|
1843
|
-
styles.color.ansi = wrapAnsi16();
|
|
1844
|
-
styles.color.ansi256 = wrapAnsi256();
|
|
1845
|
-
styles.color.ansi16m = wrapAnsi16m();
|
|
1846
|
-
styles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET);
|
|
1847
|
-
styles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET);
|
|
1848
|
-
styles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET);
|
|
1849
|
-
Object.defineProperties(styles, {
|
|
1850
|
-
rgbToAnsi256: {
|
|
1851
|
-
value(red, green, blue) {
|
|
1852
|
-
if (red === green && green === blue) {
|
|
1853
|
-
if (red < 8) {
|
|
1854
|
-
return 16;
|
|
1855
|
-
}
|
|
1856
|
-
if (red > 248) {
|
|
1857
|
-
return 231;
|
|
1858
|
-
}
|
|
1859
|
-
return Math.round((red - 8) / 247 * 24) + 232;
|
|
1860
|
-
}
|
|
1861
|
-
return 16 + 36 * Math.round(red / 255 * 5) + 6 * Math.round(green / 255 * 5) + Math.round(blue / 255 * 5);
|
|
1862
|
-
},
|
|
1863
|
-
enumerable: false
|
|
1864
|
-
},
|
|
1865
|
-
hexToRgb: {
|
|
1866
|
-
value(hex) {
|
|
1867
|
-
const matches = /[a-f\d]{6}|[a-f\d]{3}/i.exec(hex.toString(16));
|
|
1868
|
-
if (!matches) {
|
|
1869
|
-
return [0, 0, 0];
|
|
1870
|
-
}
|
|
1871
|
-
let [colorString] = matches;
|
|
1872
|
-
if (colorString.length === 3) {
|
|
1873
|
-
colorString = [...colorString].map((character) => character + character).join("");
|
|
1874
|
-
}
|
|
1875
|
-
const integer = Number.parseInt(colorString, 16);
|
|
1876
|
-
return [
|
|
1877
|
-
integer >> 16 & 255,
|
|
1878
|
-
integer >> 8 & 255,
|
|
1879
|
-
integer & 255
|
|
1880
|
-
];
|
|
1881
|
-
},
|
|
1882
|
-
enumerable: false
|
|
1883
|
-
},
|
|
1884
|
-
hexToAnsi256: {
|
|
1885
|
-
value: (hex) => styles.rgbToAnsi256(...styles.hexToRgb(hex)),
|
|
1886
|
-
enumerable: false
|
|
1887
|
-
},
|
|
1888
|
-
ansi256ToAnsi: {
|
|
1889
|
-
value(code) {
|
|
1890
|
-
if (code < 8) {
|
|
1891
|
-
return 30 + code;
|
|
1892
|
-
}
|
|
1893
|
-
if (code < 16) {
|
|
1894
|
-
return 90 + (code - 8);
|
|
1895
|
-
}
|
|
1896
|
-
let red;
|
|
1897
|
-
let green;
|
|
1898
|
-
let blue;
|
|
1899
|
-
if (code >= 232) {
|
|
1900
|
-
red = ((code - 232) * 10 + 8) / 255;
|
|
1901
|
-
green = red;
|
|
1902
|
-
blue = red;
|
|
1903
|
-
} else {
|
|
1904
|
-
code -= 16;
|
|
1905
|
-
const remainder = code % 36;
|
|
1906
|
-
red = Math.floor(code / 36) / 5;
|
|
1907
|
-
green = Math.floor(remainder / 6) / 5;
|
|
1908
|
-
blue = remainder % 6 / 5;
|
|
1909
|
-
}
|
|
1910
|
-
const value = Math.max(red, green, blue) * 2;
|
|
1911
|
-
if (value === 0) {
|
|
1912
|
-
return 30;
|
|
1913
|
-
}
|
|
1914
|
-
let result = 30 + (Math.round(blue) << 2 | Math.round(green) << 1 | Math.round(red));
|
|
1915
|
-
if (value === 2) {
|
|
1916
|
-
result += 60;
|
|
1917
|
-
}
|
|
1918
|
-
return result;
|
|
1919
|
-
},
|
|
1920
|
-
enumerable: false
|
|
1921
|
-
},
|
|
1922
|
-
rgbToAnsi: {
|
|
1923
|
-
value: (red, green, blue) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)),
|
|
1924
|
-
enumerable: false
|
|
1925
|
-
},
|
|
1926
|
-
hexToAnsi: {
|
|
1927
|
-
value: (hex) => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)),
|
|
1928
|
-
enumerable: false
|
|
1929
|
-
}
|
|
1930
|
-
});
|
|
1931
|
-
return styles;
|
|
1932
|
-
}
|
|
1933
|
-
var ansiStyles = assembleStyles();
|
|
1934
|
-
var ansi_styles_default = ansiStyles;
|
|
1935
|
-
|
|
1936
|
-
// ../../node_modules/.bun/wrap-ansi@9.0.2/node_modules/wrap-ansi/index.js
|
|
1937
|
-
var ESCAPES = new Set([
|
|
1938
|
-
"\x1B",
|
|
1939
|
-
"\x9B"
|
|
1940
|
-
]);
|
|
1941
|
-
var END_CODE = 39;
|
|
1942
|
-
var ANSI_ESCAPE_BELL = "\x07";
|
|
1943
|
-
var ANSI_CSI = "[";
|
|
1944
|
-
var ANSI_OSC = "]";
|
|
1945
|
-
var ANSI_SGR_TERMINATOR = "m";
|
|
1946
|
-
var ANSI_ESCAPE_LINK = `${ANSI_OSC}8;;`;
|
|
1947
|
-
var wrapAnsiCode = (code) => `${ESCAPES.values().next().value}${ANSI_CSI}${code}${ANSI_SGR_TERMINATOR}`;
|
|
1948
|
-
var wrapAnsiHyperlink = (url) => `${ESCAPES.values().next().value}${ANSI_ESCAPE_LINK}${url}${ANSI_ESCAPE_BELL}`;
|
|
1949
|
-
var wordLengths = (string) => string.split(" ").map((character) => stringWidth(character));
|
|
1950
|
-
var wrapWord = (rows, word, columns) => {
|
|
1951
|
-
const characters = [...word];
|
|
1952
|
-
let isInsideEscape = false;
|
|
1953
|
-
let isInsideLinkEscape = false;
|
|
1954
|
-
let visible = stringWidth(stripAnsi(rows.at(-1)));
|
|
1955
|
-
for (const [index, character] of characters.entries()) {
|
|
1956
|
-
const characterLength = stringWidth(character);
|
|
1957
|
-
if (visible + characterLength <= columns) {
|
|
1958
|
-
rows[rows.length - 1] += character;
|
|
1959
|
-
} else {
|
|
1960
|
-
rows.push(character);
|
|
1961
|
-
visible = 0;
|
|
1962
|
-
}
|
|
1963
|
-
if (ESCAPES.has(character)) {
|
|
1964
|
-
isInsideEscape = true;
|
|
1965
|
-
const ansiEscapeLinkCandidate = characters.slice(index + 1, index + 1 + ANSI_ESCAPE_LINK.length).join("");
|
|
1966
|
-
isInsideLinkEscape = ansiEscapeLinkCandidate === ANSI_ESCAPE_LINK;
|
|
1967
|
-
}
|
|
1968
|
-
if (isInsideEscape) {
|
|
1969
|
-
if (isInsideLinkEscape) {
|
|
1970
|
-
if (character === ANSI_ESCAPE_BELL) {
|
|
1971
|
-
isInsideEscape = false;
|
|
1972
|
-
isInsideLinkEscape = false;
|
|
1973
|
-
}
|
|
1974
|
-
} else if (character === ANSI_SGR_TERMINATOR) {
|
|
1975
|
-
isInsideEscape = false;
|
|
1976
|
-
}
|
|
1977
|
-
continue;
|
|
1978
|
-
}
|
|
1979
|
-
visible += characterLength;
|
|
1980
|
-
if (visible === columns && index < characters.length - 1) {
|
|
1981
|
-
rows.push("");
|
|
1982
|
-
visible = 0;
|
|
1983
|
-
}
|
|
1984
|
-
}
|
|
1985
|
-
if (!visible && rows.at(-1).length > 0 && rows.length > 1) {
|
|
1986
|
-
rows[rows.length - 2] += rows.pop();
|
|
1987
|
-
}
|
|
1988
|
-
};
|
|
1989
|
-
var stringVisibleTrimSpacesRight = (string) => {
|
|
1990
|
-
const words = string.split(" ");
|
|
1991
|
-
let last = words.length;
|
|
1992
|
-
while (last > 0) {
|
|
1993
|
-
if (stringWidth(words[last - 1]) > 0) {
|
|
1994
|
-
break;
|
|
1995
|
-
}
|
|
1996
|
-
last--;
|
|
1997
|
-
}
|
|
1998
|
-
if (last === words.length) {
|
|
1999
|
-
return string;
|
|
2000
|
-
}
|
|
2001
|
-
return words.slice(0, last).join(" ") + words.slice(last).join("");
|
|
2002
|
-
};
|
|
2003
|
-
var exec = (string, columns, options = {}) => {
|
|
2004
|
-
if (options.trim !== false && string.trim() === "") {
|
|
2005
|
-
return "";
|
|
2006
|
-
}
|
|
2007
|
-
let returnValue = "";
|
|
2008
|
-
let escapeCode;
|
|
2009
|
-
let escapeUrl;
|
|
2010
|
-
const lengths = wordLengths(string);
|
|
2011
|
-
let rows = [""];
|
|
2012
|
-
for (const [index, word] of string.split(" ").entries()) {
|
|
2013
|
-
if (options.trim !== false) {
|
|
2014
|
-
rows[rows.length - 1] = rows.at(-1).trimStart();
|
|
2015
|
-
}
|
|
2016
|
-
let rowLength = stringWidth(rows.at(-1));
|
|
2017
|
-
if (index !== 0) {
|
|
2018
|
-
if (rowLength >= columns && (options.wordWrap === false || options.trim === false)) {
|
|
2019
|
-
rows.push("");
|
|
2020
|
-
rowLength = 0;
|
|
2021
|
-
}
|
|
2022
|
-
if (rowLength > 0 || options.trim === false) {
|
|
2023
|
-
rows[rows.length - 1] += " ";
|
|
2024
|
-
rowLength++;
|
|
2025
|
-
}
|
|
2026
|
-
}
|
|
2027
|
-
if (options.hard && lengths[index] > columns) {
|
|
2028
|
-
const remainingColumns = columns - rowLength;
|
|
2029
|
-
const breaksStartingThisLine = 1 + Math.floor((lengths[index] - remainingColumns - 1) / columns);
|
|
2030
|
-
const breaksStartingNextLine = Math.floor((lengths[index] - 1) / columns);
|
|
2031
|
-
if (breaksStartingNextLine < breaksStartingThisLine) {
|
|
2032
|
-
rows.push("");
|
|
2033
|
-
}
|
|
2034
|
-
wrapWord(rows, word, columns);
|
|
2035
|
-
continue;
|
|
2036
|
-
}
|
|
2037
|
-
if (rowLength + lengths[index] > columns && rowLength > 0 && lengths[index] > 0) {
|
|
2038
|
-
if (options.wordWrap === false && rowLength < columns) {
|
|
2039
|
-
wrapWord(rows, word, columns);
|
|
2040
|
-
continue;
|
|
2041
|
-
}
|
|
2042
|
-
rows.push("");
|
|
2043
|
-
}
|
|
2044
|
-
if (rowLength + lengths[index] > columns && options.wordWrap === false) {
|
|
2045
|
-
wrapWord(rows, word, columns);
|
|
2046
|
-
continue;
|
|
2047
|
-
}
|
|
2048
|
-
rows[rows.length - 1] += word;
|
|
2049
|
-
}
|
|
2050
|
-
if (options.trim !== false) {
|
|
2051
|
-
rows = rows.map((row) => stringVisibleTrimSpacesRight(row));
|
|
2052
|
-
}
|
|
2053
|
-
const preString = rows.join(`
|
|
2054
|
-
`);
|
|
2055
|
-
const pre = [...preString];
|
|
2056
|
-
let preStringIndex = 0;
|
|
2057
|
-
for (const [index, character] of pre.entries()) {
|
|
2058
|
-
returnValue += character;
|
|
2059
|
-
if (ESCAPES.has(character)) {
|
|
2060
|
-
const { groups } = new RegExp(`(?:\\${ANSI_CSI}(?<code>\\d+)m|\\${ANSI_ESCAPE_LINK}(?<uri>.*)${ANSI_ESCAPE_BELL})`).exec(preString.slice(preStringIndex)) || { groups: {} };
|
|
2061
|
-
if (groups.code !== undefined) {
|
|
2062
|
-
const code2 = Number.parseFloat(groups.code);
|
|
2063
|
-
escapeCode = code2 === END_CODE ? undefined : code2;
|
|
2064
|
-
} else if (groups.uri !== undefined) {
|
|
2065
|
-
escapeUrl = groups.uri.length === 0 ? undefined : groups.uri;
|
|
2066
|
-
}
|
|
2067
|
-
}
|
|
2068
|
-
const code = ansi_styles_default.codes.get(Number(escapeCode));
|
|
2069
|
-
if (pre[index + 1] === `
|
|
2070
|
-
`) {
|
|
2071
|
-
if (escapeUrl) {
|
|
2072
|
-
returnValue += wrapAnsiHyperlink("");
|
|
2073
|
-
}
|
|
2074
|
-
if (escapeCode && code) {
|
|
2075
|
-
returnValue += wrapAnsiCode(code);
|
|
2076
|
-
}
|
|
2077
|
-
} else if (character === `
|
|
2078
|
-
`) {
|
|
2079
|
-
if (escapeCode && code) {
|
|
2080
|
-
returnValue += wrapAnsiCode(escapeCode);
|
|
2081
|
-
}
|
|
2082
|
-
if (escapeUrl) {
|
|
2083
|
-
returnValue += wrapAnsiHyperlink(escapeUrl);
|
|
2084
|
-
}
|
|
2085
|
-
}
|
|
2086
|
-
preStringIndex += character.length;
|
|
2087
|
-
}
|
|
2088
|
-
return returnValue;
|
|
2089
|
-
};
|
|
2090
|
-
function wrapAnsi(string, columns, options) {
|
|
2091
|
-
return String(string).normalize().replaceAll(`\r
|
|
2092
|
-
`, `
|
|
2093
|
-
`).split(`
|
|
2094
|
-
`).map((line) => exec(line, columns, options)).join(`
|
|
2095
|
-
`);
|
|
2096
|
-
}
|
|
2097
|
-
|
|
2098
|
-
// ../../node_modules/.bun/@inquirer+core@11.1.1+b219b5910764fa5c/node_modules/@inquirer/core/dist/lib/utils.js
|
|
2099
|
-
function breakLines(content, width) {
|
|
2100
|
-
return content.split(`
|
|
2101
|
-
`).flatMap((line) => wrapAnsi(line, width, { trim: false, hard: true }).split(`
|
|
2102
|
-
`).map((str) => str.trimEnd())).join(`
|
|
2103
|
-
`);
|
|
2104
|
-
}
|
|
2105
|
-
function readlineWidth() {
|
|
2106
|
-
return import_cli_width.default({ defaultWidth: 80, output: readline().output });
|
|
2107
|
-
}
|
|
2108
|
-
|
|
2109
|
-
// ../../node_modules/.bun/@inquirer+core@11.1.1+b219b5910764fa5c/node_modules/@inquirer/core/dist/lib/pagination/use-pagination.js
|
|
2110
|
-
function usePointerPosition({ active, renderedItems, pageSize, loop }) {
|
|
2111
|
-
const state = useRef({
|
|
2112
|
-
lastPointer: active,
|
|
2113
|
-
lastActive: undefined
|
|
2114
|
-
});
|
|
2115
|
-
const { lastPointer, lastActive } = state.current;
|
|
2116
|
-
const middle = Math.floor(pageSize / 2);
|
|
2117
|
-
const renderedLength = renderedItems.reduce((acc, item) => acc + item.length, 0);
|
|
2118
|
-
const defaultPointerPosition = renderedItems.slice(0, active).reduce((acc, item) => acc + item.length, 0);
|
|
2119
|
-
let pointer = defaultPointerPosition;
|
|
2120
|
-
if (renderedLength > pageSize) {
|
|
2121
|
-
if (loop) {
|
|
2122
|
-
pointer = lastPointer;
|
|
2123
|
-
if (lastActive != null && lastActive < active && active - lastActive < pageSize) {
|
|
2124
|
-
pointer = Math.min(middle, Math.abs(active - lastActive) === 1 ? Math.min(lastPointer + (renderedItems[lastActive]?.length ?? 0), Math.max(defaultPointerPosition, lastPointer)) : lastPointer + active - lastActive);
|
|
2125
|
-
}
|
|
2126
|
-
} else {
|
|
2127
|
-
const spaceUnderActive = renderedItems.slice(active).reduce((acc, item) => acc + item.length, 0);
|
|
2128
|
-
pointer = spaceUnderActive < pageSize - middle ? pageSize - spaceUnderActive : Math.min(defaultPointerPosition, middle);
|
|
2129
|
-
}
|
|
2130
|
-
}
|
|
2131
|
-
state.current.lastPointer = pointer;
|
|
2132
|
-
state.current.lastActive = active;
|
|
2133
|
-
return pointer;
|
|
2134
|
-
}
|
|
2135
|
-
function usePagination({ items, active, renderItem, pageSize, loop = true }) {
|
|
2136
|
-
const width = readlineWidth();
|
|
2137
|
-
const bound = (num) => (num % items.length + items.length) % items.length;
|
|
2138
|
-
const renderedItems = items.map((item, index) => {
|
|
2139
|
-
if (item == null)
|
|
2140
|
-
return [];
|
|
2141
|
-
return breakLines(renderItem({ item, index, isActive: index === active }), width).split(`
|
|
2142
|
-
`);
|
|
2143
|
-
});
|
|
2144
|
-
const renderedLength = renderedItems.reduce((acc, item) => acc + item.length, 0);
|
|
2145
|
-
const renderItemAtIndex = (index) => renderedItems[index] ?? [];
|
|
2146
|
-
const pointer = usePointerPosition({ active, renderedItems, pageSize, loop });
|
|
2147
|
-
const activeItem = renderItemAtIndex(active).slice(0, pageSize);
|
|
2148
|
-
const activeItemPosition = pointer + activeItem.length <= pageSize ? pointer : pageSize - activeItem.length;
|
|
2149
|
-
const pageBuffer = Array.from({ length: pageSize });
|
|
2150
|
-
pageBuffer.splice(activeItemPosition, activeItem.length, ...activeItem);
|
|
2151
|
-
const itemVisited = new Set([active]);
|
|
2152
|
-
let bufferPointer = activeItemPosition + activeItem.length;
|
|
2153
|
-
let itemPointer = bound(active + 1);
|
|
2154
|
-
while (bufferPointer < pageSize && !itemVisited.has(itemPointer) && (loop && renderedLength > pageSize ? itemPointer !== active : itemPointer > active)) {
|
|
2155
|
-
const lines = renderItemAtIndex(itemPointer);
|
|
2156
|
-
const linesToAdd = lines.slice(0, pageSize - bufferPointer);
|
|
2157
|
-
pageBuffer.splice(bufferPointer, linesToAdd.length, ...linesToAdd);
|
|
2158
|
-
itemVisited.add(itemPointer);
|
|
2159
|
-
bufferPointer += linesToAdd.length;
|
|
2160
|
-
itemPointer = bound(itemPointer + 1);
|
|
2161
|
-
}
|
|
2162
|
-
bufferPointer = activeItemPosition - 1;
|
|
2163
|
-
itemPointer = bound(active - 1);
|
|
2164
|
-
while (bufferPointer >= 0 && !itemVisited.has(itemPointer) && (loop && renderedLength > pageSize ? itemPointer !== active : itemPointer < active)) {
|
|
2165
|
-
const lines = renderItemAtIndex(itemPointer);
|
|
2166
|
-
const linesToAdd = lines.slice(Math.max(0, lines.length - bufferPointer - 1));
|
|
2167
|
-
pageBuffer.splice(bufferPointer - linesToAdd.length + 1, linesToAdd.length, ...linesToAdd);
|
|
2168
|
-
itemVisited.add(itemPointer);
|
|
2169
|
-
bufferPointer -= linesToAdd.length;
|
|
2170
|
-
itemPointer = bound(itemPointer - 1);
|
|
2171
|
-
}
|
|
2172
|
-
return pageBuffer.filter((line) => typeof line === "string").join(`
|
|
2173
|
-
`);
|
|
2174
|
-
}
|
|
2175
|
-
// ../../node_modules/.bun/@inquirer+core@11.1.1+b219b5910764fa5c/node_modules/@inquirer/core/dist/lib/create-prompt.js
|
|
2176
|
-
var import_mute_stream = __toESM(require_lib(), 1);
|
|
2177
|
-
import * as readline2 from "readline";
|
|
2178
|
-
import { AsyncResource as AsyncResource3 } from "async_hooks";
|
|
2179
|
-
|
|
2180
|
-
// ../../node_modules/.bun/signal-exit@4.1.0/node_modules/signal-exit/dist/mjs/signals.js
|
|
2181
|
-
var signals = [];
|
|
2182
|
-
signals.push("SIGHUP", "SIGINT", "SIGTERM");
|
|
2183
|
-
if (process.platform !== "win32") {
|
|
2184
|
-
signals.push("SIGALRM", "SIGABRT", "SIGVTALRM", "SIGXCPU", "SIGXFSZ", "SIGUSR2", "SIGTRAP", "SIGSYS", "SIGQUIT", "SIGIOT");
|
|
2185
|
-
}
|
|
2186
|
-
if (process.platform === "linux") {
|
|
2187
|
-
signals.push("SIGIO", "SIGPOLL", "SIGPWR", "SIGSTKFLT");
|
|
2188
|
-
}
|
|
2189
|
-
|
|
2190
|
-
// ../../node_modules/.bun/signal-exit@4.1.0/node_modules/signal-exit/dist/mjs/index.js
|
|
2191
|
-
var processOk = (process3) => !!process3 && typeof process3 === "object" && typeof process3.removeListener === "function" && typeof process3.emit === "function" && typeof process3.reallyExit === "function" && typeof process3.listeners === "function" && typeof process3.kill === "function" && typeof process3.pid === "number" && typeof process3.on === "function";
|
|
2192
|
-
var kExitEmitter = Symbol.for("signal-exit emitter");
|
|
2193
|
-
var global = globalThis;
|
|
2194
|
-
var ObjectDefineProperty = Object.defineProperty.bind(Object);
|
|
2195
|
-
|
|
2196
|
-
class Emitter {
|
|
2197
|
-
emitted = {
|
|
2198
|
-
afterExit: false,
|
|
2199
|
-
exit: false
|
|
2200
|
-
};
|
|
2201
|
-
listeners = {
|
|
2202
|
-
afterExit: [],
|
|
2203
|
-
exit: []
|
|
2204
|
-
};
|
|
2205
|
-
count = 0;
|
|
2206
|
-
id = Math.random();
|
|
2207
|
-
constructor() {
|
|
2208
|
-
if (global[kExitEmitter]) {
|
|
2209
|
-
return global[kExitEmitter];
|
|
2210
|
-
}
|
|
2211
|
-
ObjectDefineProperty(global, kExitEmitter, {
|
|
2212
|
-
value: this,
|
|
2213
|
-
writable: false,
|
|
2214
|
-
enumerable: false,
|
|
2215
|
-
configurable: false
|
|
2216
|
-
});
|
|
2217
|
-
}
|
|
2218
|
-
on(ev, fn) {
|
|
2219
|
-
this.listeners[ev].push(fn);
|
|
2220
|
-
}
|
|
2221
|
-
removeListener(ev, fn) {
|
|
2222
|
-
const list = this.listeners[ev];
|
|
2223
|
-
const i = list.indexOf(fn);
|
|
2224
|
-
if (i === -1) {
|
|
2225
|
-
return;
|
|
2226
|
-
}
|
|
2227
|
-
if (i === 0 && list.length === 1) {
|
|
2228
|
-
list.length = 0;
|
|
2229
|
-
} else {
|
|
2230
|
-
list.splice(i, 1);
|
|
2231
|
-
}
|
|
2232
|
-
}
|
|
2233
|
-
emit(ev, code, signal) {
|
|
2234
|
-
if (this.emitted[ev]) {
|
|
2235
|
-
return false;
|
|
2236
|
-
}
|
|
2237
|
-
this.emitted[ev] = true;
|
|
2238
|
-
let ret = false;
|
|
2239
|
-
for (const fn of this.listeners[ev]) {
|
|
2240
|
-
ret = fn(code, signal) === true || ret;
|
|
2241
|
-
}
|
|
2242
|
-
if (ev === "exit") {
|
|
2243
|
-
ret = this.emit("afterExit", code, signal) || ret;
|
|
2244
|
-
}
|
|
2245
|
-
return ret;
|
|
2246
|
-
}
|
|
2247
|
-
}
|
|
2248
|
-
|
|
2249
|
-
class SignalExitBase {
|
|
2250
|
-
}
|
|
2251
|
-
var signalExitWrap = (handler) => {
|
|
2252
|
-
return {
|
|
2253
|
-
onExit(cb, opts) {
|
|
2254
|
-
return handler.onExit(cb, opts);
|
|
2255
|
-
},
|
|
2256
|
-
load() {
|
|
2257
|
-
return handler.load();
|
|
2258
|
-
},
|
|
2259
|
-
unload() {
|
|
2260
|
-
return handler.unload();
|
|
2261
|
-
}
|
|
2262
|
-
};
|
|
2263
|
-
};
|
|
2264
|
-
|
|
2265
|
-
class SignalExitFallback extends SignalExitBase {
|
|
2266
|
-
onExit() {
|
|
2267
|
-
return () => {};
|
|
2268
|
-
}
|
|
2269
|
-
load() {}
|
|
2270
|
-
unload() {}
|
|
2271
|
-
}
|
|
2272
|
-
|
|
2273
|
-
class SignalExit extends SignalExitBase {
|
|
2274
|
-
#hupSig = process3.platform === "win32" ? "SIGINT" : "SIGHUP";
|
|
2275
|
-
#emitter = new Emitter;
|
|
2276
|
-
#process;
|
|
2277
|
-
#originalProcessEmit;
|
|
2278
|
-
#originalProcessReallyExit;
|
|
2279
|
-
#sigListeners = {};
|
|
2280
|
-
#loaded = false;
|
|
2281
|
-
constructor(process3) {
|
|
2282
|
-
super();
|
|
2283
|
-
this.#process = process3;
|
|
2284
|
-
this.#sigListeners = {};
|
|
2285
|
-
for (const sig of signals) {
|
|
2286
|
-
this.#sigListeners[sig] = () => {
|
|
2287
|
-
const listeners = this.#process.listeners(sig);
|
|
2288
|
-
let { count } = this.#emitter;
|
|
2289
|
-
const p = process3;
|
|
2290
|
-
if (typeof p.__signal_exit_emitter__ === "object" && typeof p.__signal_exit_emitter__.count === "number") {
|
|
2291
|
-
count += p.__signal_exit_emitter__.count;
|
|
2292
|
-
}
|
|
2293
|
-
if (listeners.length === count) {
|
|
2294
|
-
this.unload();
|
|
2295
|
-
const ret = this.#emitter.emit("exit", null, sig);
|
|
2296
|
-
const s = sig === "SIGHUP" ? this.#hupSig : sig;
|
|
2297
|
-
if (!ret)
|
|
2298
|
-
process3.kill(process3.pid, s);
|
|
2299
|
-
}
|
|
2300
|
-
};
|
|
2301
|
-
}
|
|
2302
|
-
this.#originalProcessReallyExit = process3.reallyExit;
|
|
2303
|
-
this.#originalProcessEmit = process3.emit;
|
|
2304
|
-
}
|
|
2305
|
-
onExit(cb, opts) {
|
|
2306
|
-
if (!processOk(this.#process)) {
|
|
2307
|
-
return () => {};
|
|
2308
|
-
}
|
|
2309
|
-
if (this.#loaded === false) {
|
|
2310
|
-
this.load();
|
|
2311
|
-
}
|
|
2312
|
-
const ev = opts?.alwaysLast ? "afterExit" : "exit";
|
|
2313
|
-
this.#emitter.on(ev, cb);
|
|
2314
|
-
return () => {
|
|
2315
|
-
this.#emitter.removeListener(ev, cb);
|
|
2316
|
-
if (this.#emitter.listeners["exit"].length === 0 && this.#emitter.listeners["afterExit"].length === 0) {
|
|
2317
|
-
this.unload();
|
|
2318
|
-
}
|
|
2319
|
-
};
|
|
2320
|
-
}
|
|
2321
|
-
load() {
|
|
2322
|
-
if (this.#loaded) {
|
|
2323
|
-
return;
|
|
2324
|
-
}
|
|
2325
|
-
this.#loaded = true;
|
|
2326
|
-
this.#emitter.count += 1;
|
|
2327
|
-
for (const sig of signals) {
|
|
2328
|
-
try {
|
|
2329
|
-
const fn = this.#sigListeners[sig];
|
|
2330
|
-
if (fn)
|
|
2331
|
-
this.#process.on(sig, fn);
|
|
2332
|
-
} catch (_) {}
|
|
2333
|
-
}
|
|
2334
|
-
this.#process.emit = (ev, ...a) => {
|
|
2335
|
-
return this.#processEmit(ev, ...a);
|
|
2336
|
-
};
|
|
2337
|
-
this.#process.reallyExit = (code) => {
|
|
2338
|
-
return this.#processReallyExit(code);
|
|
2339
|
-
};
|
|
2340
|
-
}
|
|
2341
|
-
unload() {
|
|
2342
|
-
if (!this.#loaded) {
|
|
2343
|
-
return;
|
|
2344
|
-
}
|
|
2345
|
-
this.#loaded = false;
|
|
2346
|
-
signals.forEach((sig) => {
|
|
2347
|
-
const listener = this.#sigListeners[sig];
|
|
2348
|
-
if (!listener) {
|
|
2349
|
-
throw new Error("Listener not defined for signal: " + sig);
|
|
2350
|
-
}
|
|
2351
|
-
try {
|
|
2352
|
-
this.#process.removeListener(sig, listener);
|
|
2353
|
-
} catch (_) {}
|
|
2354
|
-
});
|
|
2355
|
-
this.#process.emit = this.#originalProcessEmit;
|
|
2356
|
-
this.#process.reallyExit = this.#originalProcessReallyExit;
|
|
2357
|
-
this.#emitter.count -= 1;
|
|
2358
|
-
}
|
|
2359
|
-
#processReallyExit(code) {
|
|
2360
|
-
if (!processOk(this.#process)) {
|
|
2361
|
-
return 0;
|
|
2362
|
-
}
|
|
2363
|
-
this.#process.exitCode = code || 0;
|
|
2364
|
-
this.#emitter.emit("exit", this.#process.exitCode, null);
|
|
2365
|
-
return this.#originalProcessReallyExit.call(this.#process, this.#process.exitCode);
|
|
2366
|
-
}
|
|
2367
|
-
#processEmit(ev, ...args) {
|
|
2368
|
-
const og = this.#originalProcessEmit;
|
|
2369
|
-
if (ev === "exit" && processOk(this.#process)) {
|
|
2370
|
-
if (typeof args[0] === "number") {
|
|
2371
|
-
this.#process.exitCode = args[0];
|
|
2372
|
-
}
|
|
2373
|
-
const ret = og.call(this.#process, ev, ...args);
|
|
2374
|
-
this.#emitter.emit("exit", this.#process.exitCode, null);
|
|
2375
|
-
return ret;
|
|
2376
|
-
} else {
|
|
2377
|
-
return og.call(this.#process, ev, ...args);
|
|
2378
|
-
}
|
|
2379
|
-
}
|
|
2380
|
-
}
|
|
2381
|
-
var process3 = globalThis.process;
|
|
2382
|
-
var {
|
|
2383
|
-
onExit,
|
|
2384
|
-
load,
|
|
2385
|
-
unload
|
|
2386
|
-
} = signalExitWrap(processOk(process3) ? new SignalExit(process3) : new SignalExitFallback);
|
|
2387
|
-
|
|
2388
|
-
// ../../node_modules/.bun/@inquirer+core@11.1.1+b219b5910764fa5c/node_modules/@inquirer/core/dist/lib/screen-manager.js
|
|
2389
|
-
import { stripVTControlCharacters } from "util";
|
|
2390
|
-
|
|
2391
|
-
// ../../node_modules/.bun/@inquirer+ansi@2.0.3/node_modules/@inquirer/ansi/dist/index.js
|
|
2392
|
-
var ESC = "\x1B[";
|
|
2393
|
-
var cursorLeft = ESC + "G";
|
|
2394
|
-
var cursorHide = ESC + "?25l";
|
|
2395
|
-
var cursorShow = ESC + "?25h";
|
|
2396
|
-
var cursorUp = (rows = 1) => rows > 0 ? `${ESC}${rows}A` : "";
|
|
2397
|
-
var cursorDown = (rows = 1) => rows > 0 ? `${ESC}${rows}B` : "";
|
|
2398
|
-
var cursorTo = (x, y) => {
|
|
2399
|
-
if (typeof y === "number" && !Number.isNaN(y)) {
|
|
2400
|
-
return `${ESC}${y + 1};${x + 1}H`;
|
|
2401
|
-
}
|
|
2402
|
-
return `${ESC}${x + 1}G`;
|
|
2403
|
-
};
|
|
2404
|
-
var eraseLine = ESC + "2K";
|
|
2405
|
-
var eraseLines = (lines) => lines > 0 ? (eraseLine + cursorUp(1)).repeat(lines - 1) + eraseLine + cursorLeft : "";
|
|
2406
|
-
|
|
2407
|
-
// ../../node_modules/.bun/@inquirer+core@11.1.1+b219b5910764fa5c/node_modules/@inquirer/core/dist/lib/screen-manager.js
|
|
2408
|
-
var height = (content) => content.split(`
|
|
2409
|
-
`).length;
|
|
2410
|
-
var lastLine = (content) => content.split(`
|
|
2411
|
-
`).pop() ?? "";
|
|
2412
|
-
|
|
2413
|
-
class ScreenManager {
|
|
2414
|
-
height = 0;
|
|
2415
|
-
extraLinesUnderPrompt = 0;
|
|
2416
|
-
cursorPos;
|
|
2417
|
-
rl;
|
|
2418
|
-
constructor(rl) {
|
|
2419
|
-
this.rl = rl;
|
|
2420
|
-
this.cursorPos = rl.getCursorPos();
|
|
2421
|
-
}
|
|
2422
|
-
write(content) {
|
|
2423
|
-
this.rl.output.unmute();
|
|
2424
|
-
this.rl.output.write(content);
|
|
2425
|
-
this.rl.output.mute();
|
|
2426
|
-
}
|
|
2427
|
-
render(content, bottomContent = "") {
|
|
2428
|
-
const promptLine = lastLine(content);
|
|
2429
|
-
const rawPromptLine = stripVTControlCharacters(promptLine);
|
|
2430
|
-
let prompt = rawPromptLine;
|
|
2431
|
-
if (this.rl.line.length > 0) {
|
|
2432
|
-
prompt = prompt.slice(0, -this.rl.line.length);
|
|
2433
|
-
}
|
|
2434
|
-
this.rl.setPrompt(prompt);
|
|
2435
|
-
this.cursorPos = this.rl.getCursorPos();
|
|
2436
|
-
const width = readlineWidth();
|
|
2437
|
-
content = breakLines(content, width);
|
|
2438
|
-
bottomContent = breakLines(bottomContent, width);
|
|
2439
|
-
if (rawPromptLine.length % width === 0) {
|
|
2440
|
-
content += `
|
|
2441
|
-
`;
|
|
2442
|
-
}
|
|
2443
|
-
let output = content + (bottomContent ? `
|
|
2444
|
-
` + bottomContent : "");
|
|
2445
|
-
const promptLineUpDiff = Math.floor(rawPromptLine.length / width) - this.cursorPos.rows;
|
|
2446
|
-
const bottomContentHeight = promptLineUpDiff + (bottomContent ? height(bottomContent) : 0);
|
|
2447
|
-
if (bottomContentHeight > 0)
|
|
2448
|
-
output += cursorUp(bottomContentHeight);
|
|
2449
|
-
output += cursorTo(this.cursorPos.cols);
|
|
2450
|
-
this.write(cursorDown(this.extraLinesUnderPrompt) + eraseLines(this.height) + output);
|
|
2451
|
-
this.extraLinesUnderPrompt = bottomContentHeight;
|
|
2452
|
-
this.height = height(output);
|
|
2453
|
-
}
|
|
2454
|
-
checkCursorPos() {
|
|
2455
|
-
const cursorPos = this.rl.getCursorPos();
|
|
2456
|
-
if (cursorPos.cols !== this.cursorPos.cols) {
|
|
2457
|
-
this.write(cursorTo(cursorPos.cols));
|
|
2458
|
-
this.cursorPos = cursorPos;
|
|
2459
|
-
}
|
|
2460
|
-
}
|
|
2461
|
-
done({ clearContent }) {
|
|
2462
|
-
this.rl.setPrompt("");
|
|
2463
|
-
let output = cursorDown(this.extraLinesUnderPrompt);
|
|
2464
|
-
output += clearContent ? eraseLines(this.height) : `
|
|
2465
|
-
`;
|
|
2466
|
-
output += cursorShow;
|
|
2467
|
-
this.write(output);
|
|
2468
|
-
this.rl.close();
|
|
2469
|
-
}
|
|
2470
|
-
}
|
|
2471
|
-
|
|
2472
|
-
// ../../node_modules/.bun/@inquirer+core@11.1.1+b219b5910764fa5c/node_modules/@inquirer/core/dist/lib/promise-polyfill.js
|
|
2473
|
-
class PromisePolyfill extends Promise {
|
|
2474
|
-
static withResolver() {
|
|
2475
|
-
let resolve;
|
|
2476
|
-
let reject;
|
|
2477
|
-
const promise = new Promise((res, rej) => {
|
|
2478
|
-
resolve = res;
|
|
2479
|
-
reject = rej;
|
|
2480
|
-
});
|
|
2481
|
-
return { promise, resolve, reject };
|
|
2482
|
-
}
|
|
2483
|
-
}
|
|
2484
|
-
|
|
2485
|
-
// ../../node_modules/.bun/@inquirer+core@11.1.1+b219b5910764fa5c/node_modules/@inquirer/core/dist/lib/create-prompt.js
|
|
2486
|
-
function getCallSites() {
|
|
2487
|
-
const _prepareStackTrace = Error.prepareStackTrace;
|
|
2488
|
-
let result = [];
|
|
2489
|
-
try {
|
|
2490
|
-
Error.prepareStackTrace = (_, callSites) => {
|
|
2491
|
-
const callSitesWithoutCurrent = callSites.slice(1);
|
|
2492
|
-
result = callSitesWithoutCurrent;
|
|
2493
|
-
return callSitesWithoutCurrent;
|
|
2494
|
-
};
|
|
2495
|
-
new Error().stack;
|
|
2496
|
-
} catch {
|
|
2497
|
-
return result;
|
|
2498
|
-
}
|
|
2499
|
-
Error.prepareStackTrace = _prepareStackTrace;
|
|
2500
|
-
return result;
|
|
2501
|
-
}
|
|
2502
|
-
function createPrompt(view) {
|
|
2503
|
-
const callSites = getCallSites();
|
|
2504
|
-
const prompt = (config, context = {}) => {
|
|
2505
|
-
const { input = process.stdin, signal } = context;
|
|
2506
|
-
const cleanups = new Set;
|
|
2507
|
-
const output = new import_mute_stream.default;
|
|
2508
|
-
output.pipe(context.output ?? process.stdout);
|
|
2509
|
-
const rl = readline2.createInterface({
|
|
2510
|
-
terminal: true,
|
|
2511
|
-
input,
|
|
2512
|
-
output
|
|
2513
|
-
});
|
|
2514
|
-
const screen = new ScreenManager(rl);
|
|
2515
|
-
const { promise, resolve, reject } = PromisePolyfill.withResolver();
|
|
2516
|
-
const cancel = () => reject(new CancelPromptError);
|
|
2517
|
-
if (signal) {
|
|
2518
|
-
const abort = () => reject(new AbortPromptError({ cause: signal.reason }));
|
|
2519
|
-
if (signal.aborted) {
|
|
2520
|
-
abort();
|
|
2521
|
-
return Object.assign(promise, { cancel });
|
|
2522
|
-
}
|
|
2523
|
-
signal.addEventListener("abort", abort);
|
|
2524
|
-
cleanups.add(() => signal.removeEventListener("abort", abort));
|
|
2525
|
-
}
|
|
2526
|
-
cleanups.add(onExit((code, signal2) => {
|
|
2527
|
-
reject(new ExitPromptError(`User force closed the prompt with ${code} ${signal2}`));
|
|
2528
|
-
}));
|
|
2529
|
-
const sigint = () => reject(new ExitPromptError(`User force closed the prompt with SIGINT`));
|
|
2530
|
-
rl.on("SIGINT", sigint);
|
|
2531
|
-
cleanups.add(() => rl.removeListener("SIGINT", sigint));
|
|
2532
|
-
const checkCursorPos = () => screen.checkCursorPos();
|
|
2533
|
-
rl.input.on("keypress", checkCursorPos);
|
|
2534
|
-
cleanups.add(() => rl.input.removeListener("keypress", checkCursorPos));
|
|
2535
|
-
return withHooks(rl, (cycle) => {
|
|
2536
|
-
const hooksCleanup = AsyncResource3.bind(() => effectScheduler.clearAll());
|
|
2537
|
-
rl.on("close", hooksCleanup);
|
|
2538
|
-
cleanups.add(() => rl.removeListener("close", hooksCleanup));
|
|
2539
|
-
cycle(() => {
|
|
2540
|
-
try {
|
|
2541
|
-
const nextView = view(config, (value) => {
|
|
2542
|
-
setImmediate(() => resolve(value));
|
|
2543
|
-
});
|
|
2544
|
-
if (nextView === undefined) {
|
|
2545
|
-
const callerFilename = callSites[1]?.getFileName();
|
|
2546
|
-
throw new Error(`Prompt functions must return a string.
|
|
2547
|
-
at ${callerFilename}`);
|
|
2548
|
-
}
|
|
2549
|
-
const [content, bottomContent] = typeof nextView === "string" ? [nextView] : nextView;
|
|
2550
|
-
screen.render(content, bottomContent);
|
|
2551
|
-
effectScheduler.run();
|
|
2552
|
-
} catch (error) {
|
|
2553
|
-
reject(error);
|
|
2554
|
-
}
|
|
2555
|
-
});
|
|
2556
|
-
return Object.assign(promise.then((answer) => {
|
|
2557
|
-
effectScheduler.clearAll();
|
|
2558
|
-
return answer;
|
|
2559
|
-
}, (error) => {
|
|
2560
|
-
effectScheduler.clearAll();
|
|
2561
|
-
throw error;
|
|
2562
|
-
}).finally(() => {
|
|
2563
|
-
cleanups.forEach((cleanup) => cleanup());
|
|
2564
|
-
screen.done({ clearContent: Boolean(context.clearPromptOnDone) });
|
|
2565
|
-
output.end();
|
|
2566
|
-
}).then(() => promise), { cancel });
|
|
2567
|
-
});
|
|
2568
|
-
};
|
|
2569
|
-
return prompt;
|
|
2570
|
-
}
|
|
2571
|
-
// ../../node_modules/.bun/@inquirer+core@11.1.1+b219b5910764fa5c/node_modules/@inquirer/core/dist/lib/Separator.js
|
|
2572
|
-
import { styleText as styleText2 } from "util";
|
|
2573
|
-
class Separator {
|
|
2574
|
-
separator = styleText2("dim", Array.from({ length: 15 }).join(dist_default2.line));
|
|
2575
|
-
type = "separator";
|
|
2576
|
-
constructor(separator) {
|
|
2577
|
-
if (separator) {
|
|
2578
|
-
this.separator = separator;
|
|
2579
|
-
}
|
|
2580
|
-
}
|
|
2581
|
-
static isSeparator(choice) {
|
|
2582
|
-
return Boolean(choice && typeof choice === "object" && "type" in choice && choice.type === "separator");
|
|
2583
|
-
}
|
|
2584
|
-
}
|
|
2585
|
-
// ../../node_modules/.bun/@inquirer+select@5.0.4+b219b5910764fa5c/node_modules/@inquirer/select/dist/index.js
|
|
2586
|
-
import { styleText as styleText3 } from "util";
|
|
2587
|
-
var selectTheme = {
|
|
2588
|
-
icon: { cursor: dist_default2.pointer },
|
|
2589
|
-
style: {
|
|
2590
|
-
disabled: (text) => styleText3("dim", `- ${text}`),
|
|
2591
|
-
description: (text) => styleText3("cyan", text),
|
|
2592
|
-
keysHelpTip: (keys) => keys.map(([key, action]) => `${styleText3("bold", key)} ${styleText3("dim", action)}`).join(styleText3("dim", " \u2022 "))
|
|
2593
|
-
},
|
|
2594
|
-
indexMode: "hidden",
|
|
2595
|
-
keybindings: []
|
|
2596
|
-
};
|
|
2597
|
-
function isSelectable(item) {
|
|
2598
|
-
return !Separator.isSeparator(item) && !item.disabled;
|
|
2599
|
-
}
|
|
2600
|
-
function normalizeChoices(choices) {
|
|
2601
|
-
return choices.map((choice) => {
|
|
2602
|
-
if (Separator.isSeparator(choice))
|
|
2603
|
-
return choice;
|
|
2604
|
-
if (typeof choice !== "object" || choice === null || !("value" in choice)) {
|
|
2605
|
-
const name2 = String(choice);
|
|
2606
|
-
return {
|
|
2607
|
-
value: choice,
|
|
2608
|
-
name: name2,
|
|
2609
|
-
short: name2,
|
|
2610
|
-
disabled: false
|
|
2611
|
-
};
|
|
2612
|
-
}
|
|
2613
|
-
const name = choice.name ?? String(choice.value);
|
|
2614
|
-
const normalizedChoice = {
|
|
2615
|
-
value: choice.value,
|
|
2616
|
-
name,
|
|
2617
|
-
short: choice.short ?? name,
|
|
2618
|
-
disabled: choice.disabled ?? false
|
|
2619
|
-
};
|
|
2620
|
-
if (choice.description) {
|
|
2621
|
-
normalizedChoice.description = choice.description;
|
|
2622
|
-
}
|
|
2623
|
-
return normalizedChoice;
|
|
2624
|
-
});
|
|
2625
|
-
}
|
|
2626
|
-
var dist_default3 = createPrompt((config, done) => {
|
|
2627
|
-
const { loop = true, pageSize = 7 } = config;
|
|
2628
|
-
const theme = makeTheme(selectTheme, config.theme);
|
|
2629
|
-
const { keybindings } = theme;
|
|
2630
|
-
const [status, setStatus] = useState("idle");
|
|
2631
|
-
const prefix = usePrefix({ status, theme });
|
|
2632
|
-
const searchTimeoutRef = useRef();
|
|
2633
|
-
const searchEnabled = !keybindings.includes("vim");
|
|
2634
|
-
const items = useMemo(() => normalizeChoices(config.choices), [config.choices]);
|
|
2635
|
-
const bounds = useMemo(() => {
|
|
2636
|
-
const first = items.findIndex(isSelectable);
|
|
2637
|
-
const last = items.findLastIndex(isSelectable);
|
|
2638
|
-
if (first === -1) {
|
|
2639
|
-
throw new ValidationError("[select prompt] No selectable choices. All choices are disabled.");
|
|
2640
|
-
}
|
|
2641
|
-
return { first, last };
|
|
2642
|
-
}, [items]);
|
|
2643
|
-
const defaultItemIndex = useMemo(() => {
|
|
2644
|
-
if (!("default" in config))
|
|
2645
|
-
return -1;
|
|
2646
|
-
return items.findIndex((item) => isSelectable(item) && item.value === config.default);
|
|
2647
|
-
}, [config.default, items]);
|
|
2648
|
-
const [active, setActive] = useState(defaultItemIndex === -1 ? bounds.first : defaultItemIndex);
|
|
2649
|
-
const selectedChoice = items[active];
|
|
2650
|
-
useKeypress((key, rl) => {
|
|
2651
|
-
clearTimeout(searchTimeoutRef.current);
|
|
2652
|
-
if (isEnterKey(key)) {
|
|
2653
|
-
setStatus("done");
|
|
2654
|
-
done(selectedChoice.value);
|
|
2655
|
-
} else if (isUpKey(key, keybindings) || isDownKey(key, keybindings)) {
|
|
2656
|
-
rl.clearLine(0);
|
|
2657
|
-
if (loop || isUpKey(key, keybindings) && active !== bounds.first || isDownKey(key, keybindings) && active !== bounds.last) {
|
|
2658
|
-
const offset = isUpKey(key, keybindings) ? -1 : 1;
|
|
2659
|
-
let next = active;
|
|
2660
|
-
do {
|
|
2661
|
-
next = (next + offset + items.length) % items.length;
|
|
2662
|
-
} while (!isSelectable(items[next]));
|
|
2663
|
-
setActive(next);
|
|
2664
|
-
}
|
|
2665
|
-
} else if (isNumberKey(key) && !Number.isNaN(Number(rl.line))) {
|
|
2666
|
-
const selectedIndex = Number(rl.line) - 1;
|
|
2667
|
-
let selectableIndex = -1;
|
|
2668
|
-
const position = items.findIndex((item2) => {
|
|
2669
|
-
if (Separator.isSeparator(item2))
|
|
2670
|
-
return false;
|
|
2671
|
-
selectableIndex++;
|
|
2672
|
-
return selectableIndex === selectedIndex;
|
|
2673
|
-
});
|
|
2674
|
-
const item = items[position];
|
|
2675
|
-
if (item != null && isSelectable(item)) {
|
|
2676
|
-
setActive(position);
|
|
2677
|
-
}
|
|
2678
|
-
searchTimeoutRef.current = setTimeout(() => {
|
|
2679
|
-
rl.clearLine(0);
|
|
2680
|
-
}, 700);
|
|
2681
|
-
} else if (isBackspaceKey(key)) {
|
|
2682
|
-
rl.clearLine(0);
|
|
2683
|
-
} else if (searchEnabled) {
|
|
2684
|
-
const searchTerm = rl.line.toLowerCase();
|
|
2685
|
-
const matchIndex = items.findIndex((item) => {
|
|
2686
|
-
if (Separator.isSeparator(item) || !isSelectable(item))
|
|
2687
|
-
return false;
|
|
2688
|
-
return item.name.toLowerCase().startsWith(searchTerm);
|
|
2689
|
-
});
|
|
2690
|
-
if (matchIndex !== -1) {
|
|
2691
|
-
setActive(matchIndex);
|
|
2692
|
-
}
|
|
2693
|
-
searchTimeoutRef.current = setTimeout(() => {
|
|
2694
|
-
rl.clearLine(0);
|
|
2695
|
-
}, 700);
|
|
2696
|
-
}
|
|
2697
|
-
});
|
|
2698
|
-
useEffect(() => () => {
|
|
2699
|
-
clearTimeout(searchTimeoutRef.current);
|
|
2700
|
-
}, []);
|
|
2701
|
-
const message = theme.style.message(config.message, status);
|
|
2702
|
-
const helpLine = theme.style.keysHelpTip([
|
|
2703
|
-
["\u2191\u2193", "navigate"],
|
|
2704
|
-
["\u23CE", "select"]
|
|
2705
|
-
]);
|
|
2706
|
-
let separatorCount = 0;
|
|
2707
|
-
const page = usePagination({
|
|
2708
|
-
items,
|
|
2709
|
-
active,
|
|
2710
|
-
renderItem({ item, isActive, index }) {
|
|
2711
|
-
if (Separator.isSeparator(item)) {
|
|
2712
|
-
separatorCount++;
|
|
2713
|
-
return ` ${item.separator}`;
|
|
2714
|
-
}
|
|
2715
|
-
const indexLabel = theme.indexMode === "number" ? `${index + 1 - separatorCount}. ` : "";
|
|
2716
|
-
if (item.disabled) {
|
|
2717
|
-
const disabledLabel = typeof item.disabled === "string" ? item.disabled : "(disabled)";
|
|
2718
|
-
return theme.style.disabled(`${indexLabel}${item.name} ${disabledLabel}`);
|
|
2719
|
-
}
|
|
2720
|
-
const color = isActive ? theme.style.highlight : (x) => x;
|
|
2721
|
-
const cursor = isActive ? theme.icon.cursor : ` `;
|
|
2722
|
-
return color(`${cursor} ${indexLabel}${item.name}`);
|
|
2723
|
-
},
|
|
2724
|
-
pageSize,
|
|
2725
|
-
loop
|
|
2726
|
-
});
|
|
2727
|
-
if (status === "done") {
|
|
2728
|
-
return [prefix, message, theme.style.answer(selectedChoice.short)].filter(Boolean).join(" ");
|
|
2729
|
-
}
|
|
2730
|
-
const { description } = selectedChoice;
|
|
2731
|
-
const lines = [
|
|
2732
|
-
[prefix, message].filter(Boolean).join(" "),
|
|
2733
|
-
page,
|
|
2734
|
-
" ",
|
|
2735
|
-
description ? theme.style.description(description) : "",
|
|
2736
|
-
helpLine
|
|
2737
|
-
].filter(Boolean).join(`
|
|
2738
|
-
`).trimEnd();
|
|
2739
|
-
return `${lines}${cursorHide}`;
|
|
2740
|
-
});
|
|
2741
|
-
// lib/utils.ts
|
|
2742
|
-
var import_bytes = __toESM(require_bytes(), 1);
|
|
2743
|
-
|
|
2744
|
-
// lib/output.ts
|
|
2745
|
-
var import_picocolors = __toESM(require_picocolors(), 1);
|
|
2746
|
-
var brand = (text) => import_picocolors.default.cyan(import_picocolors.default.bold(text));
|
|
2747
|
-
var success = (text) => `${import_picocolors.default.green("\u2713")} ${text}`;
|
|
2748
|
-
var warn = (text) => `${import_picocolors.default.yellow("\u26A0")} ${text}`;
|
|
2749
|
-
var error = (text) => `${import_picocolors.default.red("\u2717")} ${text}`;
|
|
2750
|
-
var info = (text) => `${import_picocolors.default.cyan("\u2139")} ${text}`;
|
|
2751
|
-
var dim = (text) => import_picocolors.default.dim(text);
|
|
2752
|
-
var green = (text) => import_picocolors.default.green(text);
|
|
2753
|
-
var yellow = (text) => import_picocolors.default.yellow(text);
|
|
2754
|
-
var red = (text) => import_picocolors.default.red(text);
|
|
2755
|
-
var cyan = (text) => import_picocolors.default.cyan(text);
|
|
2756
|
-
var magenta = (text) => import_picocolors.default.magenta(text);
|
|
2757
|
-
function header(text) {
|
|
2758
|
-
console.log("");
|
|
2759
|
-
console.log(brand(` ${text}`));
|
|
2760
|
-
console.log(import_picocolors.default.dim(" " + "\u2500".repeat(text.length + 2)));
|
|
2761
|
-
}
|
|
2762
|
-
function labelValue(label, value) {
|
|
2763
|
-
console.log(` ${import_picocolors.default.dim(label + ":")} ${value}`);
|
|
2764
|
-
}
|
|
2765
|
-
function statusLine(status, name, message, extra) {
|
|
2766
|
-
const icons = { ok: "\u2713", warning: "\u26A0", error: "\u2717" };
|
|
2767
|
-
const colors = { ok: import_picocolors.default.green, warning: import_picocolors.default.yellow, error: import_picocolors.default.red };
|
|
2768
|
-
let line = `${colors[status](icons[status])} ${name}: ${message}`;
|
|
2769
|
-
if (extra) {
|
|
2770
|
-
line += ` ${import_picocolors.default.dim(`(${extra})`)}`;
|
|
2771
|
-
}
|
|
2772
|
-
return line;
|
|
2773
|
-
}
|
|
2774
|
-
function tableRow(columns, widths) {
|
|
2775
|
-
return columns.map((col, i) => {
|
|
2776
|
-
const width = widths[i] || col.length;
|
|
2777
|
-
return col.padEnd(width);
|
|
2778
|
-
}).join(" ");
|
|
2779
|
-
}
|
|
2780
|
-
function tableHeader(columns, widths) {
|
|
2781
|
-
const headerRow = tableRow(columns.map((c) => import_picocolors.default.bold(c)), widths);
|
|
2782
|
-
const underlineRow = widths.map((w) => "\u2500".repeat(w)).join(" ");
|
|
2783
|
-
console.log(headerRow);
|
|
2784
|
-
console.log(import_picocolors.default.dim(underlineRow));
|
|
2785
|
-
}
|
|
2786
|
-
function url(urlStr) {
|
|
2787
|
-
return import_picocolors.default.underline(import_picocolors.default.cyan(urlStr));
|
|
2788
|
-
}
|
|
2789
|
-
function cmd(command) {
|
|
2790
|
-
return import_picocolors.default.cyan(command);
|
|
2791
|
-
}
|
|
2792
|
-
function file(filePath) {
|
|
2793
|
-
return import_picocolors.default.magenta(filePath);
|
|
2794
|
-
}
|
|
2795
|
-
|
|
2796
|
-
// lib/spawn.ts
|
|
2797
|
-
async function spawn(cmd2, opts = {}) {
|
|
2798
|
-
const command = cmd2[0];
|
|
2799
|
-
const args = cmd2.slice(1);
|
|
2800
|
-
if (command === undefined) {
|
|
2801
|
-
throw new Error("No command provided");
|
|
2802
|
-
}
|
|
2803
|
-
if (typeof Bun !== "undefined") {
|
|
2804
|
-
const proc = Bun.spawn(cmd2, {
|
|
2805
|
-
env: opts.env ?? process.env,
|
|
2806
|
-
cwd: opts.cwd ?? process.cwd(),
|
|
2807
|
-
stdin: opts.stdin ?? "inherit",
|
|
2808
|
-
stdout: opts.stdout ?? "inherit",
|
|
2809
|
-
stderr: opts.stderr ?? "inherit"
|
|
2810
|
-
});
|
|
2811
|
-
return proc.exited;
|
|
2812
|
-
} else {
|
|
2813
|
-
const { spawn: nodeSpawn } = await import("child_process");
|
|
2814
|
-
return new Promise((resolve) => {
|
|
2815
|
-
const proc = nodeSpawn(command, args, {
|
|
2816
|
-
env: opts.env,
|
|
2817
|
-
cwd: opts.cwd,
|
|
2818
|
-
stdio: [opts.stdin ?? "inherit", opts.stdout ?? "inherit", opts.stderr ?? "inherit"]
|
|
2819
|
-
});
|
|
2820
|
-
proc.on("close", (code) => resolve(code ?? 1));
|
|
2821
|
-
});
|
|
2822
|
-
}
|
|
2823
|
-
}
|
|
2824
|
-
async function spawnCapture(cmd2, opts = {}) {
|
|
2825
|
-
const command = cmd2[0];
|
|
2826
|
-
const args = cmd2.slice(1);
|
|
2827
|
-
if (command === undefined) {
|
|
2828
|
-
throw new Error("No command provided");
|
|
2829
|
-
}
|
|
2830
|
-
if (typeof Bun !== "undefined") {
|
|
2831
|
-
const proc = Bun.spawn(cmd2, {
|
|
2832
|
-
env: opts.env ?? process.env,
|
|
2833
|
-
cwd: opts.cwd,
|
|
2834
|
-
stdin: opts.stdin ?? "ignore",
|
|
2835
|
-
stdout: "pipe",
|
|
2836
|
-
stderr: "pipe"
|
|
2837
|
-
});
|
|
2838
|
-
const [stdout, stderr, exitCode] = await Promise.all([
|
|
2839
|
-
new Response(proc.stdout).text(),
|
|
2840
|
-
new Response(proc.stderr).text(),
|
|
2841
|
-
proc.exited
|
|
2842
|
-
]);
|
|
2843
|
-
return { exitCode, stdout, stderr };
|
|
2844
|
-
} else {
|
|
2845
|
-
const { spawn: nodeSpawn } = await import("child_process");
|
|
2846
|
-
return new Promise((resolve) => {
|
|
2847
|
-
const proc = nodeSpawn(command, args, {
|
|
2848
|
-
env: opts.env,
|
|
2849
|
-
cwd: opts.cwd,
|
|
2850
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
2851
|
-
});
|
|
2852
|
-
let stdout = "";
|
|
2853
|
-
let stderr = "";
|
|
2854
|
-
proc.stdout?.on("data", (data) => {
|
|
2855
|
-
stdout += data.toString();
|
|
2856
|
-
});
|
|
2857
|
-
proc.stderr?.on("data", (data) => {
|
|
2858
|
-
stderr += data.toString();
|
|
2859
|
-
});
|
|
2860
|
-
proc.on("close", (code) => {
|
|
2861
|
-
resolve({ exitCode: code ?? 1, stdout, stderr });
|
|
2862
|
-
});
|
|
2863
|
-
});
|
|
2864
|
-
}
|
|
2865
|
-
}
|
|
2866
|
-
async function commandExists(cmd2) {
|
|
2867
|
-
try {
|
|
2868
|
-
const result = await spawnCapture(process.platform === "win32" ? ["where", cmd2] : ["which", cmd2]);
|
|
2869
|
-
return result.exitCode === 0;
|
|
2870
|
-
} catch {
|
|
2871
|
-
return false;
|
|
2872
|
-
}
|
|
2873
|
-
}
|
|
2874
|
-
async function getCommandVersion(cmd2) {
|
|
2875
|
-
try {
|
|
2876
|
-
const result = await spawnCapture([cmd2, "--version"]);
|
|
2877
|
-
if (result.exitCode === 0 && result.stdout) {
|
|
2878
|
-
return result.stdout.trim().split(`
|
|
2879
|
-
`)[0] ?? null;
|
|
2880
|
-
}
|
|
2881
|
-
return null;
|
|
2882
|
-
} catch {
|
|
2883
|
-
return null;
|
|
2884
|
-
}
|
|
2885
|
-
}
|
|
2886
|
-
|
|
2887
|
-
// lib/utils.ts
|
|
2888
|
-
async function fetchOllamaModels() {
|
|
2889
|
-
const ollamaUrl = getOllamaUrl();
|
|
2890
|
-
const response = await fetch(`${ollamaUrl}/api/tags`);
|
|
2891
|
-
if (!response.ok) {
|
|
2892
|
-
throw new Error(`Failed to fetch models: ${response.statusText}`);
|
|
2893
|
-
}
|
|
2894
|
-
const data = await response.json();
|
|
2895
|
-
return data.models ?? [];
|
|
2896
|
-
}
|
|
2897
|
-
async function fetchRunningModels() {
|
|
2898
|
-
const ollamaUrl = getOllamaUrl();
|
|
2899
|
-
try {
|
|
2900
|
-
const response = await fetch(`${ollamaUrl}/api/ps`, {
|
|
2901
|
-
signal: AbortSignal.timeout(5000)
|
|
2902
|
-
});
|
|
2903
|
-
if (!response.ok) {
|
|
2904
|
-
return [];
|
|
2905
|
-
}
|
|
2906
|
-
const data = await response.json();
|
|
2907
|
-
return data.models ?? [];
|
|
2908
|
-
} catch (error2) {
|
|
2909
|
-
return [];
|
|
2910
|
-
}
|
|
2911
|
-
}
|
|
2912
|
-
async function isModelLoaded(modelName) {
|
|
2913
|
-
const runningModels = await fetchRunningModels();
|
|
2914
|
-
return runningModels.some((m) => m.model === modelName || m.name === modelName || m.model.startsWith(modelName + ":") || modelName.startsWith(m.model));
|
|
2915
|
-
}
|
|
2916
|
-
async function loadModel(modelName, keepAlive = "10m") {
|
|
2917
|
-
const ollamaUrl = getOllamaUrl();
|
|
2918
|
-
const response = await fetch(`${ollamaUrl}/api/generate`, {
|
|
2919
|
-
method: "POST",
|
|
2920
|
-
headers: {
|
|
2921
|
-
"Content-Type": "application/json"
|
|
2922
|
-
},
|
|
2923
|
-
body: JSON.stringify({
|
|
2924
|
-
model: modelName,
|
|
2925
|
-
prompt: "",
|
|
2926
|
-
stream: false,
|
|
2927
|
-
keep_alive: keepAlive
|
|
2928
|
-
})
|
|
2929
|
-
});
|
|
2930
|
-
if (!response.ok) {
|
|
2931
|
-
throw new Error(`Failed to load model: ${response.statusText}`);
|
|
2932
|
-
}
|
|
2933
|
-
await response.json();
|
|
2934
|
-
}
|
|
2935
|
-
async function ensureModelLoaded(modelName) {
|
|
2936
|
-
const isLoaded = await isModelLoaded(modelName);
|
|
2937
|
-
if (isLoaded) {
|
|
2938
|
-
console.log(dim(` Model ${magenta(modelName)} is already loaded`));
|
|
2939
|
-
return;
|
|
2940
|
-
}
|
|
2941
|
-
console.log(info(`Loading model ${magenta(modelName)}...`));
|
|
2942
|
-
console.log(dim(" This may take a moment on first run"));
|
|
2943
|
-
try {
|
|
2944
|
-
await loadModel(modelName, "10m");
|
|
2945
|
-
console.log(success(`Model ${magenta(modelName)} loaded (keep_alive: 10m)`));
|
|
2946
|
-
} catch (error2) {
|
|
2947
|
-
console.log(warn(`Could not pre-load model (will load on first request)`));
|
|
2948
|
-
console.log(dim(` ${error2 instanceof Error ? error2.message : "Unknown error"}`));
|
|
2949
|
-
}
|
|
2950
|
-
}
|
|
2951
|
-
async function selectModelInteractively() {
|
|
2952
|
-
const ollamaUrl = getOllamaUrl();
|
|
2953
|
-
let models;
|
|
2954
|
-
try {
|
|
2955
|
-
models = await fetchOllamaModels();
|
|
2956
|
-
} catch (error2) {
|
|
2957
|
-
console.log(warn(`Could not connect to Ollama at ${ollamaUrl}`));
|
|
2958
|
-
console.log(dim(" Make sure Ollama is running: loclaude docker-up"));
|
|
2959
|
-
process.exit(1);
|
|
2960
|
-
}
|
|
2961
|
-
if (models.length === 0) {
|
|
2962
|
-
console.log(warn("No models found in Ollama."));
|
|
2963
|
-
console.log(dim(" Pull a model first: loclaude models-pull <model-name>"));
|
|
2964
|
-
process.exit(1);
|
|
2965
|
-
}
|
|
2966
|
-
const runningModels = await fetchRunningModels();
|
|
2967
|
-
const loadedModelNames = new Set(runningModels.map((m) => m.model));
|
|
2968
|
-
const selected = await dist_default3({
|
|
2969
|
-
message: "Select a model",
|
|
2970
|
-
choices: models.map((model) => {
|
|
2971
|
-
const isLoaded = loadedModelNames.has(model.name);
|
|
2972
|
-
const loadedIndicator = isLoaded ? " [loaded]" : "";
|
|
2973
|
-
return {
|
|
2974
|
-
name: `${model.name} (${import_bytes.default(model.size)})${loadedIndicator}`,
|
|
2975
|
-
value: model.name
|
|
2976
|
-
};
|
|
2977
|
-
})
|
|
2978
|
-
});
|
|
2979
|
-
return selected;
|
|
2980
|
-
}
|
|
2981
|
-
async function launchClaude(model, passthroughArgs) {
|
|
2982
|
-
const ollamaUrl = getOllamaUrl();
|
|
2983
|
-
const extraArgs = getClaudeExtraArgs();
|
|
2984
|
-
console.log("");
|
|
2985
|
-
console.log(cyan("Launching Claude Code with Ollama"));
|
|
2986
|
-
console.log(dim(` Model: ${magenta(model)}`));
|
|
2987
|
-
console.log(dim(` API: ${ollamaUrl}`));
|
|
2988
|
-
console.log("");
|
|
2989
|
-
await ensureModelLoaded(model);
|
|
2990
|
-
console.log("");
|
|
2991
|
-
const env = {
|
|
2992
|
-
...process.env,
|
|
2993
|
-
ANTHROPIC_AUTH_TOKEN: "ollama",
|
|
2994
|
-
ANTHROPIC_BASE_URL: ollamaUrl
|
|
2995
|
-
};
|
|
2996
|
-
const claudeArgs = ["claude", "--model", model, ...extraArgs, ...passthroughArgs];
|
|
2997
|
-
const exitCode = await spawn(claudeArgs, { env });
|
|
2998
|
-
process.exit(exitCode);
|
|
2999
|
-
}
|
|
3000
|
-
|
|
3001
|
-
// lib/commands/init.ts
|
|
3002
|
-
import { existsSync as existsSync2, mkdirSync, writeFileSync, readFileSync as readFileSync2 } from "fs";
|
|
3003
|
-
import { join as join2 } from "path";
|
|
3004
|
-
|
|
3005
|
-
// lib/commands/doctor.ts
|
|
3006
|
-
async function checkDocker() {
|
|
3007
|
-
const exists = await commandExists("docker");
|
|
3008
|
-
if (!exists) {
|
|
3009
|
-
return {
|
|
3010
|
-
name: "Docker",
|
|
3011
|
-
status: "error",
|
|
3012
|
-
message: "Not installed",
|
|
3013
|
-
hint: "Install Docker: https://docs.docker.com/get-docker/"
|
|
3014
|
-
};
|
|
3015
|
-
}
|
|
3016
|
-
const version = await getCommandVersion("docker");
|
|
3017
|
-
return {
|
|
3018
|
-
name: "Docker",
|
|
3019
|
-
status: "ok",
|
|
3020
|
-
message: "Installed",
|
|
3021
|
-
version: version ?? undefined
|
|
3022
|
-
};
|
|
3023
|
-
}
|
|
3024
|
-
async function checkDockerCompose() {
|
|
3025
|
-
const result = await spawnCapture(["docker", "compose", "version"]);
|
|
3026
|
-
if (result.exitCode === 0) {
|
|
3027
|
-
const version = result.stdout?.trim().split(`
|
|
3028
|
-
`)[0];
|
|
3029
|
-
return {
|
|
3030
|
-
name: "Docker Compose",
|
|
3031
|
-
status: "ok",
|
|
3032
|
-
message: "Installed (v2)",
|
|
3033
|
-
version: version ?? undefined
|
|
3034
|
-
};
|
|
3035
|
-
}
|
|
3036
|
-
const v1Exists = await commandExists("docker-compose");
|
|
3037
|
-
if (v1Exists) {
|
|
3038
|
-
const version = await getCommandVersion("docker-compose");
|
|
3039
|
-
return {
|
|
3040
|
-
name: "Docker Compose",
|
|
3041
|
-
status: "warning",
|
|
3042
|
-
message: "Using legacy v1",
|
|
3043
|
-
version: version ?? undefined,
|
|
3044
|
-
hint: "Consider upgrading to Docker Compose v2"
|
|
3045
|
-
};
|
|
3046
|
-
}
|
|
3047
|
-
return {
|
|
3048
|
-
name: "Docker Compose",
|
|
3049
|
-
status: "error",
|
|
3050
|
-
message: "Not installed",
|
|
3051
|
-
hint: "Docker Compose is included with Docker Desktop, or install separately"
|
|
3052
|
-
};
|
|
3053
|
-
}
|
|
3054
|
-
async function checkNvidiaSmi() {
|
|
3055
|
-
const exists = await commandExists("nvidia-smi");
|
|
3056
|
-
if (!exists) {
|
|
3057
|
-
return {
|
|
3058
|
-
name: "NVIDIA GPU",
|
|
3059
|
-
status: "warning",
|
|
3060
|
-
message: "nvidia-smi not found",
|
|
3061
|
-
hint: "GPU support requires NVIDIA drivers. CPU-only mode will be used."
|
|
3062
|
-
};
|
|
3063
|
-
}
|
|
3064
|
-
const result = await spawnCapture(["nvidia-smi", "--query-gpu=name", "--format=csv,noheader"]);
|
|
3065
|
-
if (result.exitCode === 0 && result.stdout) {
|
|
3066
|
-
const gpus = result.stdout.trim().split(`
|
|
3067
|
-
`).filter(Boolean);
|
|
3068
|
-
return {
|
|
3069
|
-
name: "NVIDIA GPU",
|
|
3070
|
-
status: "ok",
|
|
3071
|
-
message: `${gpus.length} GPU(s) detected`,
|
|
3072
|
-
version: gpus[0]
|
|
3073
|
-
};
|
|
3074
|
-
}
|
|
3075
|
-
return {
|
|
3076
|
-
name: "NVIDIA GPU",
|
|
3077
|
-
status: "warning",
|
|
3078
|
-
message: "nvidia-smi failed",
|
|
3079
|
-
hint: "GPU may not be available. Check NVIDIA drivers."
|
|
3080
|
-
};
|
|
3081
|
-
}
|
|
3082
|
-
async function checkNvidiaContainerToolkit() {
|
|
3083
|
-
const result = await spawnCapture(["docker", "info", "--format", "{{.Runtimes}}"]);
|
|
3084
|
-
if (result.exitCode === 0 && result.stdout?.includes("nvidia")) {
|
|
3085
|
-
return {
|
|
3086
|
-
name: "NVIDIA Container Toolkit",
|
|
3087
|
-
status: "ok",
|
|
3088
|
-
message: "nvidia runtime available"
|
|
3089
|
-
};
|
|
3090
|
-
}
|
|
3091
|
-
return {
|
|
3092
|
-
name: "NVIDIA Container Toolkit",
|
|
3093
|
-
status: "warning",
|
|
3094
|
-
message: "nvidia runtime not found",
|
|
3095
|
-
hint: "Install: https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html"
|
|
3096
|
-
};
|
|
3097
|
-
}
|
|
3098
|
-
async function checkClaude() {
|
|
3099
|
-
const exists = await commandExists("claude");
|
|
3100
|
-
if (!exists) {
|
|
3101
|
-
return {
|
|
3102
|
-
name: "Claude Code",
|
|
3103
|
-
status: "error",
|
|
3104
|
-
message: "Not installed",
|
|
3105
|
-
hint: "Install: npm install -g @anthropic-ai/claude-code"
|
|
3106
|
-
};
|
|
3107
|
-
}
|
|
3108
|
-
const version = await getCommandVersion("claude");
|
|
3109
|
-
return {
|
|
3110
|
-
name: "Claude Code",
|
|
3111
|
-
status: "ok",
|
|
3112
|
-
message: "Installed",
|
|
3113
|
-
version: version ?? undefined
|
|
3114
|
-
};
|
|
3115
|
-
}
|
|
3116
|
-
async function checkOllamaConnection() {
|
|
3117
|
-
const ollamaUrl = getOllamaUrl();
|
|
3118
|
-
try {
|
|
3119
|
-
const response = await fetch(`${ollamaUrl}/api/tags`, {
|
|
3120
|
-
signal: AbortSignal.timeout(5000)
|
|
3121
|
-
});
|
|
3122
|
-
if (response.ok) {
|
|
3123
|
-
const data = await response.json();
|
|
3124
|
-
const modelCount = data.models?.length ?? 0;
|
|
3125
|
-
return {
|
|
3126
|
-
name: "Ollama API",
|
|
3127
|
-
status: "ok",
|
|
3128
|
-
message: `Connected (${modelCount} model${modelCount === 1 ? "" : "s"})`,
|
|
3129
|
-
version: ollamaUrl
|
|
3130
|
-
};
|
|
3131
|
-
}
|
|
3132
|
-
return {
|
|
3133
|
-
name: "Ollama API",
|
|
3134
|
-
status: "warning",
|
|
3135
|
-
message: `HTTP ${response.status}`,
|
|
3136
|
-
hint: "Ollama may not be running. Try: loclaude docker-up"
|
|
3137
|
-
};
|
|
3138
|
-
} catch (error3) {
|
|
3139
|
-
return {
|
|
3140
|
-
name: "Ollama API",
|
|
3141
|
-
status: "warning",
|
|
3142
|
-
message: "Not reachable",
|
|
3143
|
-
hint: `Cannot connect to ${ollamaUrl}. Start Ollama: loclaude docker-up`
|
|
3144
|
-
};
|
|
3145
|
-
}
|
|
3146
|
-
}
|
|
3147
|
-
var MIN_OLLAMA_VERSION = "0.14.2";
|
|
3148
|
-
function parseVersion(version) {
|
|
3149
|
-
const match = version.match(/(\d+)\.(\d+)\.(\d+)/);
|
|
3150
|
-
if (!match || !match[1] || !match[2] || !match[3])
|
|
3151
|
-
return null;
|
|
3152
|
-
return {
|
|
3153
|
-
major: parseInt(match[1], 10),
|
|
3154
|
-
minor: parseInt(match[2], 10),
|
|
3155
|
-
patch: parseInt(match[3], 10)
|
|
3156
|
-
};
|
|
3157
|
-
}
|
|
3158
|
-
function compareVersions(a, b) {
|
|
3159
|
-
const parsedA = parseVersion(a);
|
|
3160
|
-
const parsedB = parseVersion(b);
|
|
3161
|
-
if (!parsedA || !parsedB)
|
|
3162
|
-
return 0;
|
|
3163
|
-
if (parsedA.major !== parsedB.major)
|
|
3164
|
-
return parsedA.major - parsedB.major;
|
|
3165
|
-
if (parsedA.minor !== parsedB.minor)
|
|
3166
|
-
return parsedA.minor - parsedB.minor;
|
|
3167
|
-
return parsedA.patch - parsedB.patch;
|
|
3168
|
-
}
|
|
3169
|
-
async function checkOllamaVersion() {
|
|
3170
|
-
const ollamaUrl = getOllamaUrl();
|
|
3171
|
-
try {
|
|
3172
|
-
const response = await fetch(`${ollamaUrl}/api/version`, {
|
|
3173
|
-
signal: AbortSignal.timeout(5000)
|
|
3174
|
-
});
|
|
3175
|
-
if (!response.ok) {
|
|
3176
|
-
return {
|
|
3177
|
-
name: "Ollama Version",
|
|
3178
|
-
status: "warning",
|
|
3179
|
-
message: "Could not determine version",
|
|
3180
|
-
hint: "Ollama may not be running. Try: loclaude docker-up"
|
|
3181
|
-
};
|
|
3182
|
-
}
|
|
3183
|
-
const data = await response.json();
|
|
3184
|
-
const version = data.version;
|
|
3185
|
-
if (!version) {
|
|
3186
|
-
return {
|
|
3187
|
-
name: "Ollama Version",
|
|
3188
|
-
status: "warning",
|
|
3189
|
-
message: "Unknown version",
|
|
3190
|
-
hint: "Could not parse version from Ollama API"
|
|
3191
|
-
};
|
|
3192
|
-
}
|
|
3193
|
-
const comparison = compareVersions(version, MIN_OLLAMA_VERSION);
|
|
3194
|
-
if (comparison > 0) {
|
|
3195
|
-
return {
|
|
3196
|
-
name: "Ollama Version",
|
|
3197
|
-
status: "ok",
|
|
3198
|
-
message: "Compatible",
|
|
3199
|
-
version
|
|
3200
|
-
};
|
|
3201
|
-
} else if (comparison === 0) {
|
|
3202
|
-
return {
|
|
3203
|
-
name: "Ollama Version",
|
|
3204
|
-
status: "ok",
|
|
3205
|
-
message: "Compatible",
|
|
3206
|
-
version,
|
|
3207
|
-
hint: `Version ${version} is the minimum. Consider upgrading for best compatibility.`
|
|
3208
|
-
};
|
|
3209
|
-
} else {
|
|
3210
|
-
return {
|
|
3211
|
-
name: "Ollama Version",
|
|
3212
|
-
status: "error",
|
|
3213
|
-
message: `Version too old (requires > ${MIN_OLLAMA_VERSION})`,
|
|
3214
|
-
version,
|
|
3215
|
-
hint: `Upgrade Ollama to a version greater than ${MIN_OLLAMA_VERSION}`
|
|
3216
|
-
};
|
|
3217
|
-
}
|
|
3218
|
-
} catch (error3) {
|
|
3219
|
-
return {
|
|
3220
|
-
name: "Ollama Version",
|
|
3221
|
-
status: "warning",
|
|
3222
|
-
message: "Could not check version",
|
|
3223
|
-
hint: `Cannot connect to ${ollamaUrl}. Start Ollama: loclaude docker-up`
|
|
3224
|
-
};
|
|
3225
|
-
}
|
|
3226
|
-
}
|
|
3227
|
-
function formatCheck(check) {
|
|
3228
|
-
let line = statusLine(check.status, check.name, check.message, check.version);
|
|
3229
|
-
if (check.hint) {
|
|
3230
|
-
line += `
|
|
3231
|
-
${dim("\u2192")} ${dim(check.hint)}`;
|
|
3232
|
-
}
|
|
3233
|
-
return line;
|
|
3234
|
-
}
|
|
3235
|
-
async function doctor() {
|
|
3236
|
-
header("System Health Check");
|
|
3237
|
-
console.log("");
|
|
3238
|
-
const checks = await Promise.all([
|
|
3239
|
-
checkDocker(),
|
|
3240
|
-
checkDockerCompose(),
|
|
3241
|
-
checkNvidiaSmi(),
|
|
3242
|
-
checkNvidiaContainerToolkit(),
|
|
3243
|
-
checkClaude(),
|
|
3244
|
-
checkOllamaConnection(),
|
|
3245
|
-
checkOllamaVersion()
|
|
3246
|
-
]);
|
|
3247
|
-
for (const check of checks) {
|
|
3248
|
-
console.log(formatCheck(check));
|
|
3249
|
-
}
|
|
3250
|
-
const errors2 = checks.filter((c) => c.status === "error");
|
|
3251
|
-
const warnings = checks.filter((c) => c.status === "warning");
|
|
3252
|
-
console.log("");
|
|
3253
|
-
if (errors2.length > 0) {
|
|
3254
|
-
console.log(red(`${errors2.length} error(s) found.`) + " Fix these before proceeding.");
|
|
3255
|
-
process.exit(1);
|
|
3256
|
-
} else if (warnings.length > 0) {
|
|
3257
|
-
console.log(yellow(`${warnings.length} warning(s).`) + " loclaude may work with limited functionality.");
|
|
3258
|
-
} else {
|
|
3259
|
-
console.log(green("All checks passed!") + " Ready to use loclaude.");
|
|
3260
|
-
}
|
|
3261
|
-
}
|
|
3262
|
-
async function hasNvidiaGpu() {
|
|
3263
|
-
const exists = await commandExists("nvidia-smi");
|
|
3264
|
-
if (!exists)
|
|
3265
|
-
return false;
|
|
3266
|
-
const result = await spawnCapture(["nvidia-smi", "--query-gpu=name", "--format=csv,noheader"]);
|
|
3267
|
-
return result.exitCode === 0 && Boolean(result.stdout?.trim());
|
|
3268
|
-
}
|
|
3269
|
-
|
|
3270
|
-
// lib/commands/init.ts
|
|
3271
|
-
var DOCKER_COMPOSE_TEMPLATE_GPU = `# =============================================================================
|
|
3272
|
-
# LOCLAUDE DOCKER COMPOSE - GPU MODE
|
|
3273
|
-
# =============================================================================
|
|
3274
|
-
# This configuration runs Ollama with NVIDIA GPU acceleration for fast inference.
|
|
3275
|
-
# Generated by: loclaude init
|
|
3276
|
-
#
|
|
3277
|
-
# Prerequisites:
|
|
3278
|
-
# - NVIDIA GPU with CUDA support
|
|
3279
|
-
# - NVIDIA drivers installed on host
|
|
3280
|
-
# - NVIDIA Container Toolkit: https://docs.nvidia.com/datacenter/cloud-native/container-toolkit
|
|
3281
|
-
#
|
|
3282
|
-
# Quick test for GPU support:
|
|
3283
|
-
# docker run --rm --gpus all nvidia/cuda:12.0-base nvidia-smi
|
|
3284
|
-
#
|
|
3285
|
-
# =============================================================================
|
|
3286
|
-
|
|
3287
|
-
services:
|
|
3288
|
-
# ===========================================================================
|
|
3289
|
-
# OLLAMA - Local LLM Inference Server
|
|
3290
|
-
# ===========================================================================
|
|
3291
|
-
# Ollama provides the AI backend that Claude Code connects to.
|
|
3292
|
-
# It runs large language models locally on your hardware.
|
|
3293
|
-
#
|
|
3294
|
-
# API Documentation: https://github.com/ollama/ollama/blob/main/docs/api.md
|
|
3295
|
-
# Model Library: https://ollama.com/library
|
|
3296
|
-
# ===========================================================================
|
|
3297
|
-
ollama:
|
|
3298
|
-
# Official Ollama image - 'latest' ensures newest features and model support
|
|
3299
|
-
image: ollama/ollama:latest
|
|
3300
|
-
|
|
3301
|
-
# Fixed container name for easy CLI access:
|
|
3302
|
-
# docker exec ollama ollama list
|
|
3303
|
-
# docker logs ollama
|
|
3304
|
-
container_name: ollama
|
|
3305
|
-
|
|
3306
|
-
# NVIDIA Container Runtime - Required for GPU access
|
|
3307
|
-
# This makes CUDA libraries available inside the container
|
|
3308
|
-
runtime: nvidia
|
|
3309
|
-
|
|
3310
|
-
environment:
|
|
3311
|
-
# ---------------------------------------------------------------------------
|
|
3312
|
-
# GPU Configuration
|
|
3313
|
-
# ---------------------------------------------------------------------------
|
|
3314
|
-
# NVIDIA_VISIBLE_DEVICES: Which GPUs to expose to the container
|
|
3315
|
-
# - 'all': Use all available GPUs (recommended for most setups)
|
|
3316
|
-
# - '0': Use only GPU 0
|
|
3317
|
-
# - '0,1': Use GPUs 0 and 1
|
|
3318
|
-
- NVIDIA_VISIBLE_DEVICES=all
|
|
3319
|
-
|
|
3320
|
-
# NVIDIA_DRIVER_CAPABILITIES: What GPU features to enable
|
|
3321
|
-
# - 'compute': CUDA compute (required for inference)
|
|
3322
|
-
# - 'utility': nvidia-smi and other tools
|
|
3323
|
-
- NVIDIA_DRIVER_CAPABILITIES=compute,utility
|
|
3324
|
-
|
|
3325
|
-
# ---------------------------------------------------------------------------
|
|
3326
|
-
# Ollama Configuration (Optional)
|
|
3327
|
-
# ---------------------------------------------------------------------------
|
|
3328
|
-
# Uncomment these to customize Ollama behavior:
|
|
3329
|
-
|
|
3330
|
-
# Maximum number of models loaded in memory simultaneously
|
|
3331
|
-
# Lower this if you're running out of VRAM
|
|
3332
|
-
# - OLLAMA_MAX_LOADED_MODELS=1
|
|
3333
|
-
|
|
3334
|
-
# Maximum parallel inference requests per model
|
|
3335
|
-
# Higher values use more VRAM but handle more concurrent requests
|
|
3336
|
-
# - OLLAMA_NUM_PARALLEL=1
|
|
3337
|
-
|
|
3338
|
-
# Enable debug logging for troubleshooting
|
|
3339
|
-
# - OLLAMA_DEBUG=1
|
|
3340
|
-
|
|
3341
|
-
# Custom model storage location (inside container)
|
|
3342
|
-
# - OLLAMA_MODELS=/root/.ollama
|
|
3343
|
-
|
|
3344
|
-
volumes:
|
|
3345
|
-
# ---------------------------------------------------------------------------
|
|
3346
|
-
# Model Storage
|
|
3347
|
-
# ---------------------------------------------------------------------------
|
|
3348
|
-
# Maps ./models on your host to /root/.ollama in the container
|
|
3349
|
-
# This persists downloaded models across container restarts
|
|
3350
|
-
#
|
|
3351
|
-
# Disk space requirements (approximate):
|
|
3352
|
-
# - 7B model: ~4GB
|
|
3353
|
-
# - 13B model: ~8GB
|
|
3354
|
-
# - 30B model: ~16GB
|
|
3355
|
-
# - 70B model: ~40GB
|
|
3356
|
-
- ./models:/root/.ollama
|
|
3357
|
-
|
|
3358
|
-
ports:
|
|
3359
|
-
# Ollama API port - access at http://localhost:11434
|
|
3360
|
-
# Used by Claude Code and other Ollama clients
|
|
3361
|
-
- "11434:11434"
|
|
3362
|
-
|
|
3363
|
-
# Restart policy - keeps Ollama running unless manually stopped
|
|
3364
|
-
restart: unless-stopped
|
|
3365
|
-
|
|
3366
|
-
healthcheck:
|
|
3367
|
-
# Verify Ollama is responsive by listing models
|
|
3368
|
-
test: ["CMD", "ollama", "list"]
|
|
3369
|
-
interval: 300s # Check every 5 minutes
|
|
3370
|
-
timeout: 2s # Fail if no response in 2 seconds
|
|
3371
|
-
retries: 3 # Mark unhealthy after 3 consecutive failures
|
|
3372
|
-
start_period: 40s # Grace period for initial model loading
|
|
3373
|
-
|
|
3374
|
-
deploy:
|
|
3375
|
-
resources:
|
|
3376
|
-
reservations:
|
|
3377
|
-
devices:
|
|
3378
|
-
# Request GPU access from Docker
|
|
3379
|
-
- driver: nvidia
|
|
3380
|
-
count: all # Use all available GPUs
|
|
3381
|
-
capabilities: [gpu] # Request GPU compute capability
|
|
3382
|
-
|
|
3383
|
-
# ===========================================================================
|
|
3384
|
-
# OPEN WEBUI - Chat Interface (Optional)
|
|
3385
|
-
# ===========================================================================
|
|
3386
|
-
# Open WebUI provides a ChatGPT-like interface for your local models.
|
|
3387
|
-
# Access at http://localhost:3000 after starting containers.
|
|
3388
|
-
#
|
|
3389
|
-
# Features:
|
|
3390
|
-
# - Multi-model chat interface
|
|
3391
|
-
# - Conversation history
|
|
3392
|
-
# - Model management UI
|
|
3393
|
-
# - RAG/document upload support
|
|
3394
|
-
#
|
|
3395
|
-
# Documentation: https://docs.openwebui.com/
|
|
3396
|
-
# ===========================================================================
|
|
3397
|
-
open-webui:
|
|
3398
|
-
# CUDA-enabled image for GPU-accelerated features (embeddings, etc.)
|
|
3399
|
-
# Change to :main if you don't need GPU features in the UI
|
|
3400
|
-
image: ghcr.io/open-webui/open-webui:cuda
|
|
3401
|
-
|
|
3402
|
-
container_name: open-webui
|
|
3403
|
-
|
|
3404
|
-
ports:
|
|
3405
|
-
# Web UI port - access at http://localhost:3000
|
|
3406
|
-
- "3000:8080"
|
|
3407
|
-
|
|
3408
|
-
environment:
|
|
3409
|
-
# Tell Open WebUI where to find Ollama
|
|
3410
|
-
# Uses Docker internal networking (service name as hostname)
|
|
3411
|
-
- OLLAMA_BASE_URL=http://ollama:11434
|
|
3412
|
-
|
|
3413
|
-
# Wait for Ollama to be ready before starting
|
|
3414
|
-
depends_on:
|
|
3415
|
-
- ollama
|
|
3416
|
-
|
|
3417
|
-
restart: unless-stopped
|
|
3418
|
-
|
|
3419
|
-
healthcheck:
|
|
3420
|
-
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
|
|
3421
|
-
interval: 30s
|
|
3422
|
-
timeout: 10s
|
|
3423
|
-
retries: 3
|
|
3424
|
-
start_period: 60s
|
|
3425
|
-
|
|
3426
|
-
volumes:
|
|
3427
|
-
# Persistent storage for conversations, settings, and user data
|
|
3428
|
-
- open-webui:/app/backend/data
|
|
3429
|
-
|
|
3430
|
-
deploy:
|
|
3431
|
-
resources:
|
|
3432
|
-
reservations:
|
|
3433
|
-
devices:
|
|
3434
|
-
- driver: nvidia
|
|
3435
|
-
count: all
|
|
3436
|
-
capabilities: [gpu]
|
|
3437
|
-
|
|
3438
|
-
# =============================================================================
|
|
3439
|
-
# VOLUMES
|
|
3440
|
-
# =============================================================================
|
|
3441
|
-
# Named volumes for persistent data that survives container recreation
|
|
3442
|
-
volumes:
|
|
3443
|
-
open-webui:
|
|
3444
|
-
# Open WebUI data: conversations, user settings, uploads
|
|
3445
|
-
# Located at /var/lib/docker/volumes/open-webui/_data on host
|
|
3446
|
-
`;
|
|
3447
|
-
var DOCKER_COMPOSE_TEMPLATE_CPU = `# =============================================================================
|
|
3448
|
-
# LOCLAUDE DOCKER COMPOSE - CPU MODE
|
|
3449
|
-
# =============================================================================
|
|
3450
|
-
# This configuration runs Ollama in CPU-only mode.
|
|
3451
|
-
# Inference will be slower than GPU mode but works on any system.
|
|
3452
|
-
# Generated by: loclaude init --no-gpu
|
|
3453
|
-
#
|
|
3454
|
-
# Performance notes:
|
|
3455
|
-
# - 7B models: ~10-20 tokens/sec on modern CPUs
|
|
3456
|
-
# - Larger models will be significantly slower
|
|
3457
|
-
# - Consider using quantized models (Q4_K_M, Q5_K_M) for better performance
|
|
3458
|
-
#
|
|
3459
|
-
# Recommended CPU-optimized models:
|
|
3460
|
-
# - llama3.2:3b (fast, good for simple tasks)
|
|
3461
|
-
# - qwen2.5-coder:7b (coding tasks)
|
|
3462
|
-
# - gemma2:9b (general purpose)
|
|
3463
|
-
#
|
|
3464
|
-
# =============================================================================
|
|
3465
|
-
|
|
3466
|
-
services:
|
|
3467
|
-
# ===========================================================================
|
|
3468
|
-
# OLLAMA - Local LLM Inference Server (CPU Mode)
|
|
3469
|
-
# ===========================================================================
|
|
3470
|
-
# Ollama provides the AI backend that Claude Code connects to.
|
|
3471
|
-
# Running in CPU mode - no GPU acceleration.
|
|
3472
|
-
#
|
|
3473
|
-
# API Documentation: https://github.com/ollama/ollama/blob/main/docs/api.md
|
|
3474
|
-
# Model Library: https://ollama.com/library
|
|
3475
|
-
# ===========================================================================
|
|
3476
|
-
ollama:
|
|
3477
|
-
# Official Ollama image - works for both CPU and GPU
|
|
3478
|
-
image: ollama/ollama:latest
|
|
3479
|
-
|
|
3480
|
-
# Fixed container name for easy CLI access
|
|
3481
|
-
container_name: ollama
|
|
3482
|
-
|
|
3483
|
-
# NOTE: No 'runtime: nvidia' - running in CPU mode
|
|
3484
|
-
|
|
3485
|
-
environment:
|
|
3486
|
-
# ---------------------------------------------------------------------------
|
|
3487
|
-
# Ollama Configuration (Optional)
|
|
3488
|
-
# ---------------------------------------------------------------------------
|
|
3489
|
-
# Uncomment these to customize Ollama behavior:
|
|
3490
|
-
|
|
3491
|
-
# Maximum number of models loaded in memory simultaneously
|
|
3492
|
-
# CPU mode uses system RAM instead of VRAM
|
|
3493
|
-
# - OLLAMA_MAX_LOADED_MODELS=1
|
|
3494
|
-
|
|
3495
|
-
# Number of CPU threads to use (default: auto-detect)
|
|
3496
|
-
# - OLLAMA_NUM_THREADS=8
|
|
3497
|
-
|
|
3498
|
-
# Enable debug logging for troubleshooting
|
|
3499
|
-
# - OLLAMA_DEBUG=1
|
|
3500
|
-
|
|
3501
|
-
volumes:
|
|
3502
|
-
# ---------------------------------------------------------------------------
|
|
3503
|
-
# Model Storage
|
|
3504
|
-
# ---------------------------------------------------------------------------
|
|
3505
|
-
# Maps ./models on your host to /root/.ollama in the container
|
|
3506
|
-
# This persists downloaded models across container restarts
|
|
3507
|
-
- ./models:/root/.ollama
|
|
3508
|
-
|
|
3509
|
-
ports:
|
|
3510
|
-
# Ollama API port - access at http://localhost:11434
|
|
3511
|
-
- "11434:11434"
|
|
3512
|
-
|
|
3513
|
-
restart: unless-stopped
|
|
3514
|
-
|
|
3515
|
-
healthcheck:
|
|
3516
|
-
test: ["CMD", "ollama", "list"]
|
|
3517
|
-
interval: 300s
|
|
3518
|
-
timeout: 2s
|
|
3519
|
-
retries: 3
|
|
3520
|
-
start_period: 40s
|
|
3521
|
-
|
|
3522
|
-
# CPU resource limits (optional - uncomment to constrain)
|
|
3523
|
-
# deploy:
|
|
3524
|
-
# resources:
|
|
3525
|
-
# limits:
|
|
3526
|
-
# cpus: '4' # Limit to 4 CPU cores
|
|
3527
|
-
# memory: 16G # Limit to 16GB RAM
|
|
3528
|
-
# reservations:
|
|
3529
|
-
# cpus: '2' # Reserve at least 2 cores
|
|
3530
|
-
# memory: 8G # Reserve at least 8GB RAM
|
|
3531
|
-
|
|
3532
|
-
# ===========================================================================
|
|
3533
|
-
# OPEN WEBUI - Chat Interface (Optional)
|
|
3534
|
-
# ===========================================================================
|
|
3535
|
-
# Open WebUI provides a ChatGPT-like interface for your local models.
|
|
3536
|
-
# Access at http://localhost:3000 after starting containers.
|
|
3537
|
-
#
|
|
3538
|
-
# Documentation: https://docs.openwebui.com/
|
|
3539
|
-
# ===========================================================================
|
|
3540
|
-
open-webui:
|
|
3541
|
-
# Standard image (no CUDA) - smaller download, CPU-only features
|
|
3542
|
-
image: ghcr.io/open-webui/open-webui:main
|
|
3543
|
-
|
|
3544
|
-
container_name: open-webui
|
|
3545
|
-
|
|
3546
|
-
ports:
|
|
3547
|
-
- "3000:8080"
|
|
3548
|
-
|
|
3549
|
-
environment:
|
|
3550
|
-
- OLLAMA_BASE_URL=http://ollama:11434
|
|
3551
|
-
|
|
3552
|
-
depends_on:
|
|
3553
|
-
- ollama
|
|
3554
|
-
|
|
3555
|
-
restart: unless-stopped
|
|
3556
|
-
|
|
3557
|
-
healthcheck:
|
|
3558
|
-
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
|
|
3559
|
-
interval: 30s
|
|
3560
|
-
timeout: 10s
|
|
3561
|
-
retries: 3
|
|
3562
|
-
start_period: 60s
|
|
3563
|
-
|
|
3564
|
-
volumes:
|
|
3565
|
-
- open-webui:/app/backend/data
|
|
3566
|
-
|
|
3567
|
-
# =============================================================================
|
|
3568
|
-
# VOLUMES
|
|
3569
|
-
# =============================================================================
|
|
3570
|
-
volumes:
|
|
3571
|
-
open-webui:
|
|
3572
|
-
`;
|
|
3573
|
-
function getConfigTemplate(gpu) {
|
|
3574
|
-
return `{
|
|
3575
|
-
"ollama": {
|
|
3576
|
-
"url": "http://localhost:11434",
|
|
3577
|
-
"defaultModel": "${gpu ? "qwen3-coder:30b" : "qwen2.5-coder:7b"}"
|
|
3578
|
-
},
|
|
3579
|
-
"docker": {
|
|
3580
|
-
"composeFile": "./docker-compose.yml",
|
|
3581
|
-
"gpu": ${gpu}
|
|
3582
|
-
}
|
|
3583
|
-
}
|
|
3584
|
-
`;
|
|
3585
|
-
}
|
|
3586
|
-
var GITIGNORE_TEMPLATE = `# Ollama models (large binary files)
|
|
3587
|
-
# These are downloaded by Ollama and can be re-pulled anytime
|
|
3588
|
-
models/
|
|
3589
|
-
`;
|
|
3590
|
-
var MISE_TOML_TEMPLATE = `# =============================================================================
|
|
3591
|
-
# MISE TASK RUNNER CONFIGURATION
|
|
3592
|
-
# =============================================================================
|
|
3593
|
-
# Mise is a task runner that provides convenient shortcuts for common operations.
|
|
3594
|
-
# Run 'mise tasks' to see all available tasks.
|
|
3595
|
-
#
|
|
3596
|
-
# Documentation: https://mise.jdx.dev/
|
|
3597
|
-
# Install: curl https://mise.jdx.dev/install.sh | sh
|
|
3598
|
-
# =============================================================================
|
|
3599
|
-
|
|
3600
|
-
[tasks]
|
|
3601
|
-
|
|
3602
|
-
# =============================================================================
|
|
3603
|
-
# Docker Management
|
|
3604
|
-
# =============================================================================
|
|
3605
|
-
# Commands for managing the Ollama and Open WebUI containers
|
|
3606
|
-
|
|
3607
|
-
[tasks.up]
|
|
3608
|
-
description = "Start Ollama and Open WebUI containers"
|
|
3609
|
-
run = "loclaude docker-up"
|
|
3610
|
-
|
|
3611
|
-
[tasks.down]
|
|
3612
|
-
description = "Stop all containers"
|
|
3613
|
-
run = "loclaude docker-down"
|
|
3614
|
-
|
|
3615
|
-
[tasks.restart]
|
|
3616
|
-
description = "Restart all containers"
|
|
3617
|
-
run = "loclaude docker-restart"
|
|
3618
|
-
|
|
3619
|
-
[tasks.status]
|
|
3620
|
-
description = "Show container status"
|
|
3621
|
-
run = "loclaude docker-status"
|
|
3622
|
-
|
|
3623
|
-
[tasks.logs]
|
|
3624
|
-
description = "Follow container logs"
|
|
3625
|
-
run = "loclaude docker-logs --follow"
|
|
3626
|
-
|
|
3627
|
-
# =============================================================================
|
|
3628
|
-
# Model Management
|
|
3629
|
-
# =============================================================================
|
|
3630
|
-
# Commands for managing Ollama models (download, remove, list)
|
|
3631
|
-
|
|
3632
|
-
[tasks.models]
|
|
3633
|
-
description = "List installed models"
|
|
3634
|
-
run = "loclaude models"
|
|
3635
|
-
|
|
3636
|
-
[tasks.pull]
|
|
3637
|
-
description = "Pull a model (usage: mise run pull <model-name>)"
|
|
3638
|
-
run = "loclaude models-pull {{arg(name='model')}}"
|
|
3639
|
-
|
|
3640
|
-
[tasks."pull:recommended"]
|
|
3641
|
-
description = "Pull the recommended coding model"
|
|
3642
|
-
run = "loclaude models-pull qwen3-coder:30b"
|
|
3643
|
-
|
|
3644
|
-
# =============================================================================
|
|
3645
|
-
# Claude Code
|
|
3646
|
-
# =============================================================================
|
|
3647
|
-
# Commands for running Claude Code with local Ollama
|
|
3648
|
-
|
|
3649
|
-
[tasks.claude]
|
|
3650
|
-
description = "Run Claude Code with local Ollama"
|
|
3651
|
-
run = "loclaude run"
|
|
3652
|
-
|
|
3653
|
-
[tasks."claude:model"]
|
|
3654
|
-
description = "Run Claude with specific model (usage: mise run claude:model <model>)"
|
|
3655
|
-
run = "loclaude run -m {{arg(name='model')}}"
|
|
3656
|
-
|
|
3657
|
-
# =============================================================================
|
|
3658
|
-
# Diagnostics
|
|
3659
|
-
# =============================================================================
|
|
3660
|
-
# Commands for checking system health and troubleshooting
|
|
3661
|
-
|
|
3662
|
-
[tasks.doctor]
|
|
3663
|
-
description = "Check system requirements"
|
|
3664
|
-
run = "loclaude doctor"
|
|
3665
|
-
|
|
3666
|
-
[tasks.gpu]
|
|
3667
|
-
description = "Check GPU status (requires NVIDIA GPU)"
|
|
3668
|
-
run = "docker exec ollama nvidia-smi"
|
|
3669
|
-
|
|
3670
|
-
[tasks.config]
|
|
3671
|
-
description = "Show current configuration"
|
|
3672
|
-
run = "loclaude config"
|
|
3673
|
-
`;
|
|
3674
|
-
var README_TEMPLATE = `# Project Name
|
|
3675
|
-
|
|
3676
|
-
> Powered by [loclaude](https://github.com/nicholasgalante1997/loclaude) - Run Claude Code with local Ollama LLMs
|
|
3677
|
-
|
|
3678
|
-
## Prerequisites
|
|
3679
|
-
|
|
3680
|
-
- [Docker](https://docs.docker.com/get-docker/) with Docker Compose v2
|
|
3681
|
-
- [mise](https://mise.jdx.dev/) task runner (recommended)
|
|
3682
|
-
- [loclaude](https://www.npmjs.com/package/loclaude) CLI (\`npm install -g loclaude\`)
|
|
3683
|
-
|
|
3684
|
-
### For GPU Mode (Recommended)
|
|
3685
|
-
|
|
3686
|
-
- [NVIDIA GPU](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html) with CUDA support
|
|
3687
|
-
- NVIDIA drivers installed on host
|
|
3688
|
-
- [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html)
|
|
3689
|
-
|
|
3690
|
-
## Quick Start
|
|
3691
|
-
|
|
3692
|
-
\`\`\`bash
|
|
3693
|
-
# Start the LLM backend (Ollama + Open WebUI)
|
|
3694
|
-
mise run up
|
|
3695
|
-
|
|
3696
|
-
# Pull a model (adjust based on your hardware)
|
|
3697
|
-
mise run pull qwen3-coder:30b # GPU: 30B model (~16GB VRAM)
|
|
3698
|
-
mise run pull qwen2.5-coder:7b # CPU: 7B model (faster)
|
|
3699
|
-
|
|
3700
|
-
# Run Claude Code with local LLM
|
|
3701
|
-
mise run claude
|
|
3702
|
-
\`\`\`
|
|
3703
|
-
|
|
3704
|
-
## Available Commands
|
|
3705
|
-
|
|
3706
|
-
Run \`mise tasks\` to see all available commands.
|
|
3707
|
-
|
|
3708
|
-
| Command | Description |
|
|
3709
|
-
|---------|-------------|
|
|
3710
|
-
| \`mise run up\` | Start Ollama and Open WebUI containers |
|
|
3711
|
-
| \`mise run down\` | Stop all containers |
|
|
3712
|
-
| \`mise run status\` | Show container status |
|
|
3713
|
-
| \`mise run logs\` | Follow container logs |
|
|
3714
|
-
| \`mise run models\` | List installed models |
|
|
3715
|
-
| \`mise run pull <model>\` | Pull a model from Ollama registry |
|
|
3716
|
-
| \`mise run claude\` | Run Claude Code with model selection |
|
|
3717
|
-
| \`mise run claude:model <model>\` | Run Claude with specific model |
|
|
3718
|
-
| \`mise run doctor\` | Check system requirements |
|
|
3719
|
-
| \`mise run gpu\` | Check GPU status |
|
|
3720
|
-
|
|
3721
|
-
## Service URLs
|
|
3722
|
-
|
|
3723
|
-
| Service | URL | Description |
|
|
3724
|
-
|---------|-----|-------------|
|
|
3725
|
-
| Ollama API | http://localhost:11434 | LLM inference API |
|
|
3726
|
-
| Open WebUI | http://localhost:3000 | Chat interface |
|
|
3727
|
-
|
|
3728
|
-
## Project Structure
|
|
3729
|
-
|
|
3730
|
-
\`\`\`
|
|
3731
|
-
.
|
|
3732
|
-
\u251C\u2500\u2500 .claude/
|
|
3733
|
-
\u2502 \u2514\u2500\u2500 CLAUDE.md # Claude Code project instructions
|
|
3734
|
-
\u251C\u2500\u2500 .loclaude/
|
|
3735
|
-
\u2502 \u2514\u2500\u2500 config.json # Loclaude configuration
|
|
3736
|
-
\u251C\u2500\u2500 models/ # Ollama model storage (gitignored)
|
|
3737
|
-
\u251C\u2500\u2500 docker-compose.yml # Container definitions
|
|
3738
|
-
\u251C\u2500\u2500 mise.toml # Task runner configuration
|
|
3739
|
-
\u2514\u2500\u2500 README.md
|
|
3740
|
-
\`\`\`
|
|
3741
|
-
|
|
3742
|
-
## Configuration
|
|
3743
|
-
|
|
3744
|
-
### Loclaude Config (\`.loclaude/config.json\`)
|
|
3745
|
-
|
|
3746
|
-
\`\`\`json
|
|
3747
|
-
{
|
|
3748
|
-
"ollama": {
|
|
3749
|
-
"url": "http://localhost:11434",
|
|
3750
|
-
"defaultModel": "qwen3-coder:30b"
|
|
3751
|
-
},
|
|
3752
|
-
"docker": {
|
|
3753
|
-
"composeFile": "./docker-compose.yml",
|
|
3754
|
-
"gpu": true
|
|
3755
|
-
}
|
|
3756
|
-
}
|
|
3757
|
-
\`\`\`
|
|
3758
|
-
|
|
3759
|
-
### Environment Variables
|
|
3760
|
-
|
|
3761
|
-
| Variable | Description | Default |
|
|
3762
|
-
|----------|-------------|---------|
|
|
3763
|
-
| \`OLLAMA_URL\` | Ollama API endpoint | \`http://localhost:11434\` |
|
|
3764
|
-
| \`OLLAMA_MODEL\` | Default model name | \`qwen3-coder:30b\` |
|
|
3765
|
-
| \`LOCLAUDE_GPU\` | Enable GPU mode | \`true\` |
|
|
3766
|
-
|
|
3767
|
-
## Recommended Models
|
|
3768
|
-
|
|
3769
|
-
### For GPU (NVIDIA with 16GB+ VRAM)
|
|
3770
|
-
|
|
3771
|
-
| Model | Size | Use Case |
|
|
3772
|
-
|-------|------|----------|
|
|
3773
|
-
| \`qwen3-coder:30b\` | ~16GB | Best coding performance |
|
|
3774
|
-
| \`gpt-oss:20b\` | ~12GB | General purpose |
|
|
3775
|
-
| \`glm-4.7:cloud\` | Cloud | No local storage needed |
|
|
3776
|
-
|
|
3777
|
-
### For CPU or Limited VRAM
|
|
3778
|
-
|
|
3779
|
-
| Model | Size | Use Case |
|
|
3780
|
-
|-------|------|----------|
|
|
3781
|
-
| \`qwen2.5-coder:7b\` | ~4GB | Coding on CPU |
|
|
3782
|
-
| \`llama3.2:3b\` | ~2GB | Fast, simple tasks |
|
|
3783
|
-
| \`gemma2:9b\` | ~5GB | General purpose |
|
|
3784
|
-
|
|
3785
|
-
## Troubleshooting
|
|
3786
|
-
|
|
3787
|
-
### Check System Requirements
|
|
3788
|
-
|
|
3789
|
-
\`\`\`bash
|
|
3790
|
-
mise run doctor
|
|
3791
|
-
\`\`\`
|
|
3792
|
-
|
|
3793
|
-
### View Container Logs
|
|
3794
|
-
|
|
3795
|
-
\`\`\`bash
|
|
3796
|
-
mise run logs
|
|
3797
|
-
\`\`\`
|
|
3798
|
-
|
|
3799
|
-
### Restart Containers
|
|
3800
|
-
|
|
3801
|
-
\`\`\`bash
|
|
3802
|
-
mise run down && mise run up
|
|
3803
|
-
\`\`\`
|
|
3804
|
-
|
|
3805
|
-
### GPU Not Detected
|
|
3806
|
-
|
|
3807
|
-
1. Verify NVIDIA drivers: \`nvidia-smi\`
|
|
3808
|
-
2. Check Docker GPU access: \`docker run --rm --gpus all nvidia/cuda:12.0-base nvidia-smi\`
|
|
3809
|
-
3. Install NVIDIA Container Toolkit if missing
|
|
3810
|
-
|
|
3811
|
-
## License
|
|
3812
|
-
|
|
3813
|
-
MIT
|
|
3814
|
-
`;
|
|
3815
|
-
var CLAUDE_MD_TEMPLATE = `# Claude Code Instructions
|
|
3816
|
-
|
|
3817
|
-
Project-specific instructions for Claude Code.
|
|
3818
|
-
|
|
3819
|
-
## Project Overview
|
|
3820
|
-
|
|
3821
|
-
This project uses [loclaude](https://github.com/nicholasgalante1997/loclaude) to run Claude Code with local Ollama LLMs.
|
|
3822
|
-
|
|
3823
|
-
## Quick Reference
|
|
3824
|
-
|
|
3825
|
-
\`\`\`bash
|
|
3826
|
-
# Start the LLM backend
|
|
3827
|
-
mise run up
|
|
3828
|
-
|
|
3829
|
-
# Run Claude Code
|
|
3830
|
-
mise run claude
|
|
3831
|
-
|
|
3832
|
-
# Check system status
|
|
3833
|
-
mise run doctor
|
|
3834
|
-
\`\`\`
|
|
3835
|
-
|
|
3836
|
-
## Available Commands
|
|
3837
|
-
|
|
3838
|
-
| Command | Description |
|
|
3839
|
-
|---------|-------------|
|
|
3840
|
-
| \`mise run up\` | Start Ollama + Open WebUI containers |
|
|
3841
|
-
| \`mise run down\` | Stop containers |
|
|
3842
|
-
| \`mise run claude\` | Run Claude Code with model selection |
|
|
3843
|
-
| \`mise run models\` | List installed models |
|
|
3844
|
-
| \`mise run pull <model>\` | Pull a new model |
|
|
3845
|
-
| \`mise run doctor\` | Check prerequisites |
|
|
3846
|
-
|
|
3847
|
-
## Service URLs
|
|
3848
|
-
|
|
3849
|
-
- **Ollama API:** http://localhost:11434
|
|
3850
|
-
- **Open WebUI:** http://localhost:3000
|
|
3851
|
-
|
|
3852
|
-
## Configuration
|
|
3853
|
-
|
|
3854
|
-
- **Docker:** \`docker-compose.yml\`
|
|
3855
|
-
- **Loclaude:** \`.loclaude/config.json\`
|
|
3856
|
-
- **Tasks:** \`mise.toml\`
|
|
3857
|
-
|
|
3858
|
-
## Conventions
|
|
3859
|
-
|
|
3860
|
-
<!-- Add project-specific conventions here -->
|
|
3861
|
-
|
|
3862
|
-
## Do Not
|
|
3863
|
-
|
|
3864
|
-
- Commit the \`models/\` directory (contains large model files)
|
|
3865
|
-
`;
|
|
3866
|
-
async function init(options = {}) {
|
|
3867
|
-
const cwd = process.cwd();
|
|
3868
|
-
const composePath = join2(cwd, "docker-compose.yml");
|
|
3869
|
-
const configDir = join2(cwd, ".loclaude");
|
|
3870
|
-
const configPath = join2(configDir, "config.json");
|
|
3871
|
-
const modelsDir = join2(cwd, "models");
|
|
3872
|
-
const gitignorePath = join2(cwd, ".gitignore");
|
|
3873
|
-
const miseTomlPath = join2(cwd, "mise.toml");
|
|
3874
|
-
const claudeDir = join2(cwd, ".claude");
|
|
3875
|
-
const claudeMdPath = join2(claudeDir, "CLAUDE.md");
|
|
3876
|
-
const readmePath = join2(cwd, "README.md");
|
|
3877
|
-
header("Initializing loclaude project");
|
|
3878
|
-
console.log("");
|
|
3879
|
-
let gpuMode;
|
|
3880
|
-
if (options.gpu === false) {
|
|
3881
|
-
gpuMode = false;
|
|
3882
|
-
console.log(info("CPU-only mode (--no-gpu)"));
|
|
3883
|
-
} else if (options.gpu === true) {
|
|
3884
|
-
gpuMode = true;
|
|
3885
|
-
console.log(info("GPU mode enabled (--gpu)"));
|
|
3886
|
-
} else {
|
|
3887
|
-
console.log(dim(" Detecting GPU..."));
|
|
3888
|
-
gpuMode = await hasNvidiaGpu();
|
|
3889
|
-
if (gpuMode) {
|
|
3890
|
-
console.log(success("NVIDIA GPU detected - using GPU mode"));
|
|
3891
|
-
} else {
|
|
3892
|
-
console.log(warn("No NVIDIA GPU detected - using CPU mode"));
|
|
3893
|
-
console.log(dim(" Use --gpu to force GPU mode if you have an NVIDIA GPU"));
|
|
3894
|
-
}
|
|
3895
|
-
}
|
|
3896
|
-
console.log("");
|
|
3897
|
-
if (existsSync2(readmePath) && !options.force) {
|
|
3898
|
-
console.log(warn(`${file("README.md")} already exists`));
|
|
3899
|
-
} else {
|
|
3900
|
-
writeFileSync(readmePath, README_TEMPLATE);
|
|
3901
|
-
console.log(success(`Created ${file("README.md")}`));
|
|
3902
|
-
}
|
|
3903
|
-
if (existsSync2(composePath) && !options.force) {
|
|
3904
|
-
console.log(warn(`${file("docker-compose.yml")} already exists`));
|
|
3905
|
-
console.log(dim(" Use --force to overwrite"));
|
|
3906
|
-
} else {
|
|
3907
|
-
let composeContent = gpuMode ? DOCKER_COMPOSE_TEMPLATE_GPU : DOCKER_COMPOSE_TEMPLATE_CPU;
|
|
3908
|
-
if (options.noWebui) {
|
|
3909
|
-
composeContent = composeContent.replace(/\n # =+\n # OPEN WEBUI[\s\S]*?capabilities: \[gpu\]\n/m, `
|
|
3910
|
-
`).replace(/\n # =+\n # OPEN WEBUI[\s\S]*?open-webui:\/app\/backend\/data\n/m, `
|
|
3911
|
-
`).replace(/\nvolumes:\n open-webui:\n.*$/m, `
|
|
3912
|
-
`);
|
|
3913
|
-
}
|
|
3914
|
-
writeFileSync(composePath, composeContent);
|
|
3915
|
-
const modeLabel = gpuMode ? cyan("GPU") : cyan("CPU");
|
|
3916
|
-
console.log(success(`Created ${file("docker-compose.yml")} (${modeLabel} mode)`));
|
|
3917
|
-
}
|
|
3918
|
-
if (existsSync2(miseTomlPath) && !options.force) {
|
|
3919
|
-
console.log(warn(`${file("mise.toml")} already exists`));
|
|
3920
|
-
} else {
|
|
3921
|
-
writeFileSync(miseTomlPath, MISE_TOML_TEMPLATE);
|
|
3922
|
-
console.log(success(`Created ${file("mise.toml")}`));
|
|
3923
|
-
}
|
|
3924
|
-
if (!existsSync2(claudeDir)) {
|
|
3925
|
-
mkdirSync(claudeDir, { recursive: true });
|
|
3926
|
-
}
|
|
3927
|
-
if (existsSync2(claudeMdPath) && !options.force) {
|
|
3928
|
-
console.log(warn(`${file(".claude/CLAUDE.md")} already exists`));
|
|
3929
|
-
} else {
|
|
3930
|
-
writeFileSync(claudeMdPath, CLAUDE_MD_TEMPLATE);
|
|
3931
|
-
console.log(success(`Created ${file(".claude/CLAUDE.md")}`));
|
|
3932
|
-
}
|
|
3933
|
-
if (!existsSync2(configDir)) {
|
|
3934
|
-
mkdirSync(configDir, { recursive: true });
|
|
3935
|
-
console.log(success(`Created ${file(".loclaude/")} directory`));
|
|
3936
|
-
}
|
|
3937
|
-
if (existsSync2(configPath) && !options.force) {
|
|
3938
|
-
console.log(warn(`${file(".loclaude/config.json")} already exists`));
|
|
3939
|
-
} else {
|
|
3940
|
-
writeFileSync(configPath, getConfigTemplate(gpuMode));
|
|
3941
|
-
console.log(success(`Created ${file(".loclaude/config.json")}`));
|
|
3942
|
-
}
|
|
3943
|
-
if (!existsSync2(modelsDir)) {
|
|
3944
|
-
mkdirSync(modelsDir, { recursive: true });
|
|
3945
|
-
console.log(success(`Created ${file("models/")} directory`));
|
|
3946
|
-
}
|
|
3947
|
-
if (existsSync2(gitignorePath)) {
|
|
3948
|
-
const existing = readFileSync2(gitignorePath, "utf-8");
|
|
3949
|
-
if (!existing.includes("models/")) {
|
|
3950
|
-
writeFileSync(gitignorePath, existing + `
|
|
3951
|
-
` + GITIGNORE_TEMPLATE);
|
|
3952
|
-
console.log(success(`Updated ${file(".gitignore")}`));
|
|
3953
|
-
}
|
|
3954
|
-
} else {
|
|
3955
|
-
writeFileSync(gitignorePath, GITIGNORE_TEMPLATE);
|
|
3956
|
-
console.log(success(`Created ${file(".gitignore")}`));
|
|
3957
|
-
}
|
|
3958
|
-
const recommendedModel = gpuMode ? "qwen3-coder:30b" : "qwen2.5-coder:7b";
|
|
3959
|
-
console.log("");
|
|
3960
|
-
console.log(green("Project initialized!"));
|
|
3961
|
-
console.log("");
|
|
3962
|
-
console.log(cyan("Next steps:"));
|
|
3963
|
-
console.log(` 1. Start containers: ${cmd("mise run up")}`);
|
|
3964
|
-
console.log(` 2. Pull a model: ${cmd(`mise run pull ${recommendedModel}`)}`);
|
|
3965
|
-
console.log(` 3. Run Claude: ${cmd("mise run claude")}`);
|
|
3966
|
-
console.log("");
|
|
3967
|
-
console.log(cyan("Service URLs:"));
|
|
3968
|
-
console.log(` Ollama API: ${url("http://localhost:11434")}`);
|
|
3969
|
-
if (!options.noWebui) {
|
|
3970
|
-
console.log(` Open WebUI: ${url("http://localhost:3000")}`);
|
|
3971
|
-
}
|
|
3972
|
-
}
|
|
3973
|
-
// lib/commands/config.ts
|
|
3974
|
-
async function configShow() {
|
|
3975
|
-
const config = loadConfig();
|
|
3976
|
-
const activePath = getActiveConfigPath();
|
|
3977
|
-
header("Current Configuration");
|
|
3978
|
-
console.log("");
|
|
3979
|
-
console.log(cyan("Ollama:"));
|
|
3980
|
-
labelValue(" URL", config.ollama.url);
|
|
3981
|
-
labelValue(" Default Model", magenta(config.ollama.defaultModel));
|
|
3982
|
-
console.log("");
|
|
3983
|
-
console.log(cyan("Docker:"));
|
|
3984
|
-
labelValue(" Compose File", config.docker.composeFile);
|
|
3985
|
-
labelValue(" GPU Mode", config.docker.gpu ? green("enabled") : dim("disabled"));
|
|
3986
|
-
console.log("");
|
|
3987
|
-
console.log(cyan("Claude:"));
|
|
3988
|
-
if (config.claude.extraArgs.length > 0) {
|
|
3989
|
-
labelValue(" Extra Args", config.claude.extraArgs.join(" "));
|
|
3990
|
-
} else {
|
|
3991
|
-
labelValue(" Extra Args", dim("none"));
|
|
3992
|
-
}
|
|
3993
|
-
console.log("");
|
|
3994
|
-
console.log(dim("\u2500".repeat(40)));
|
|
3995
|
-
if (activePath) {
|
|
3996
|
-
console.log(dim(`Loaded from: ${file(activePath)}`));
|
|
3997
|
-
} else {
|
|
3998
|
-
console.log(dim("Using default configuration (no config file found)"));
|
|
3999
|
-
}
|
|
4000
|
-
}
|
|
4001
|
-
async function configPaths() {
|
|
4002
|
-
const paths = getConfigSearchPaths();
|
|
4003
|
-
const activePath = getActiveConfigPath();
|
|
4004
|
-
header("Config Search Paths");
|
|
4005
|
-
console.log("");
|
|
4006
|
-
console.log(dim("Files are checked in priority order (first found wins):"));
|
|
4007
|
-
console.log("");
|
|
4008
|
-
for (let i = 0;i < paths.length; i++) {
|
|
4009
|
-
const configPath = paths[i];
|
|
4010
|
-
if (!configPath)
|
|
4011
|
-
continue;
|
|
4012
|
-
const isActive = configPath === activePath;
|
|
4013
|
-
const num = `${i + 1}.`;
|
|
4014
|
-
if (isActive) {
|
|
4015
|
-
console.log(` ${num} ${file(configPath)} ${green("\u2190 active")}`);
|
|
4016
|
-
} else {
|
|
4017
|
-
console.log(` ${num} ${dim(configPath)}`);
|
|
4018
|
-
}
|
|
4019
|
-
}
|
|
4020
|
-
console.log("");
|
|
4021
|
-
if (!activePath) {
|
|
4022
|
-
console.log(info("No config file found. Using defaults."));
|
|
4023
|
-
console.log(dim(` Run ${cmd("loclaude init")} to create a project config.`));
|
|
4024
|
-
}
|
|
4025
|
-
}
|
|
4026
|
-
// lib/commands/docker.ts
|
|
4027
|
-
import { existsSync as existsSync3 } from "fs";
|
|
4028
|
-
import path, { join as join3, isAbsolute } from "path";
|
|
4029
|
-
import { fileURLToPath } from "url";
|
|
4030
|
-
function findComposeFile() {
|
|
4031
|
-
const configPath = getComposeFile();
|
|
4032
|
-
if (configPath) {
|
|
4033
|
-
const absolutePath = isAbsolute(configPath) ? configPath : join3(process.cwd(), configPath);
|
|
4034
|
-
if (existsSync3(absolutePath)) {
|
|
4035
|
-
return absolutePath;
|
|
4036
|
-
}
|
|
4037
|
-
}
|
|
4038
|
-
let dir = process.cwd();
|
|
4039
|
-
while (dir !== "/" && dir.startsWith(process.cwd())) {
|
|
4040
|
-
const composePath = join3(dir, "docker-compose.yml");
|
|
4041
|
-
if (existsSync3(composePath)) {
|
|
4042
|
-
return composePath;
|
|
4043
|
-
}
|
|
4044
|
-
const dockerComposePath = join3(dir, "docker", "docker-compose.yml");
|
|
4045
|
-
if (existsSync3(dockerComposePath)) {
|
|
4046
|
-
return dockerComposePath;
|
|
4047
|
-
}
|
|
4048
|
-
dir = join3(dir, "..");
|
|
4049
|
-
}
|
|
4050
|
-
const backup = path.resolve(fileURLToPath(import.meta.url), "..", "docker", "docker-compose.yml");
|
|
4051
|
-
if (existsSync3(backup)) {
|
|
4052
|
-
return backup;
|
|
4053
|
-
}
|
|
4054
|
-
return null;
|
|
4055
|
-
}
|
|
4056
|
-
function getComposeCommand() {
|
|
4057
|
-
return ["docker", "compose"];
|
|
4058
|
-
}
|
|
4059
|
-
async function runCompose(args, options = {}) {
|
|
4060
|
-
const composeFile = options.file ?? findComposeFile();
|
|
4061
|
-
if (!composeFile) {
|
|
4062
|
-
console.log(error("No docker-compose.yml found"));
|
|
4063
|
-
console.log(dim(` Run ${cmd("loclaude init")} to create one, or specify --file`));
|
|
4064
|
-
return 1;
|
|
4065
|
-
}
|
|
4066
|
-
const cmd_args = [...getComposeCommand(), "-f", composeFile, ...args];
|
|
4067
|
-
return spawn(cmd_args);
|
|
4068
|
-
}
|
|
4069
|
-
async function dockerUp(options = {}) {
|
|
4070
|
-
const args = ["up"];
|
|
4071
|
-
if (options.detach !== false) {
|
|
4072
|
-
args.push("-d");
|
|
4073
|
-
}
|
|
4074
|
-
console.log(info("Starting containers..."));
|
|
4075
|
-
console.log("");
|
|
4076
|
-
const exitCode = await runCompose(args, options);
|
|
4077
|
-
if (exitCode === 0) {
|
|
4078
|
-
console.log("");
|
|
4079
|
-
console.log(success("Containers started"));
|
|
4080
|
-
console.log("");
|
|
4081
|
-
console.log(cyan("Service URLs:"));
|
|
4082
|
-
console.log(` Ollama API: ${url("http://localhost:11434")}`);
|
|
4083
|
-
console.log(` Open WebUI: ${url("http://localhost:3000")}`);
|
|
4084
|
-
}
|
|
4085
|
-
process.exit(exitCode);
|
|
4086
|
-
}
|
|
4087
|
-
async function dockerDown(options = {}) {
|
|
4088
|
-
console.log(info("Stopping containers..."));
|
|
4089
|
-
console.log("");
|
|
4090
|
-
const exitCode = await runCompose(["down"], options);
|
|
4091
|
-
if (exitCode === 0) {
|
|
4092
|
-
console.log("");
|
|
4093
|
-
console.log(success("Containers stopped"));
|
|
4094
|
-
}
|
|
4095
|
-
process.exit(exitCode);
|
|
4096
|
-
}
|
|
4097
|
-
async function dockerStatus(options = {}) {
|
|
4098
|
-
console.log(info("Container status:"));
|
|
4099
|
-
console.log("");
|
|
4100
|
-
const exitCode = await runCompose(["ps"], options);
|
|
4101
|
-
process.exit(exitCode);
|
|
4102
|
-
}
|
|
4103
|
-
async function dockerLogs(options = {}) {
|
|
4104
|
-
const args = ["logs"];
|
|
4105
|
-
if (options.follow) {
|
|
4106
|
-
args.push("-f");
|
|
4107
|
-
}
|
|
4108
|
-
if (options.service) {
|
|
4109
|
-
args.push(options.service);
|
|
4110
|
-
console.log(info(`Logs for ${cyan(options.service)}:`));
|
|
4111
|
-
} else {
|
|
4112
|
-
console.log(info("Container logs:"));
|
|
4113
|
-
}
|
|
4114
|
-
console.log("");
|
|
4115
|
-
const exitCode = await runCompose(args, options);
|
|
4116
|
-
process.exit(exitCode);
|
|
4117
|
-
}
|
|
4118
|
-
async function dockerRestart(options = {}) {
|
|
4119
|
-
console.log(info("Restarting containers..."));
|
|
4120
|
-
console.log("");
|
|
4121
|
-
const exitCode = await runCompose(["restart"], options);
|
|
4122
|
-
if (exitCode === 0) {
|
|
4123
|
-
console.log("");
|
|
4124
|
-
console.log(success("Containers restarted"));
|
|
4125
|
-
}
|
|
4126
|
-
process.exit(exitCode);
|
|
4127
|
-
}
|
|
4128
|
-
// lib/commands/models.ts
|
|
4129
|
-
var import_bytes2 = __toESM(require_bytes(), 1);
|
|
4130
|
-
async function fetchModels() {
|
|
4131
|
-
const ollamaUrl = getOllamaUrl();
|
|
4132
|
-
try {
|
|
4133
|
-
const response = await fetch(`${ollamaUrl}/api/tags`, {
|
|
4134
|
-
signal: AbortSignal.timeout(1e4)
|
|
4135
|
-
});
|
|
4136
|
-
if (!response.ok) {
|
|
4137
|
-
throw new Error(`HTTP ${response.status}`);
|
|
4138
|
-
}
|
|
4139
|
-
const data = await response.json();
|
|
4140
|
-
return data.models ?? [];
|
|
4141
|
-
} catch (error3) {
|
|
4142
|
-
if (error3 instanceof Error && error3.name === "TimeoutError") {
|
|
4143
|
-
throw new Error(`Connection to Ollama timed out (${ollamaUrl})`);
|
|
4144
|
-
}
|
|
4145
|
-
throw error3;
|
|
4146
|
-
}
|
|
4147
|
-
}
|
|
4148
|
-
async function isOllamaInDocker() {
|
|
4149
|
-
const result = await spawnCapture(["docker", "ps", "--filter", "name=ollama", "--format", "{{.Names}}"]);
|
|
4150
|
-
return result.exitCode === 0 && (result.stdout?.includes("ollama") ?? false);
|
|
4151
|
-
}
|
|
4152
|
-
async function runOllamaCommand(args) {
|
|
4153
|
-
const inDocker = await isOllamaInDocker();
|
|
4154
|
-
if (inDocker) {
|
|
4155
|
-
return spawn(["docker", "exec", "-it", "ollama", "ollama", ...args]);
|
|
4156
|
-
} else {
|
|
4157
|
-
return spawn(["ollama", ...args]);
|
|
4158
|
-
}
|
|
4159
|
-
}
|
|
4160
|
-
function formatSize(sizeBytes) {
|
|
4161
|
-
const sizeStr = import_bytes2.default(sizeBytes) ?? "?";
|
|
4162
|
-
const sizeNum = sizeBytes / (1024 * 1024 * 1024);
|
|
4163
|
-
if (sizeNum > 20) {
|
|
4164
|
-
return yellow(sizeStr);
|
|
4165
|
-
} else if (sizeNum > 10) {
|
|
4166
|
-
return cyan(sizeStr);
|
|
4167
|
-
}
|
|
4168
|
-
return dim(sizeStr);
|
|
4169
|
-
}
|
|
4170
|
-
async function modelsList() {
|
|
4171
|
-
try {
|
|
4172
|
-
const models = await fetchModels();
|
|
4173
|
-
if (models.length === 0) {
|
|
4174
|
-
header("Installed Models");
|
|
4175
|
-
console.log("");
|
|
4176
|
-
console.log(info("No models installed."));
|
|
4177
|
-
console.log("");
|
|
4178
|
-
console.log(`Pull a model with: ${cmd("loclaude models-pull <model-name>")}`);
|
|
4179
|
-
console.log(`Example: ${cmd("loclaude models-pull llama3.2")}`);
|
|
4180
|
-
return;
|
|
4181
|
-
}
|
|
4182
|
-
header("Installed Models");
|
|
4183
|
-
console.log("");
|
|
4184
|
-
const nameWidth = Math.max(...models.map((m) => m.name.length), "NAME".length);
|
|
4185
|
-
const sizeWidth = 10;
|
|
4186
|
-
const modifiedWidth = 20;
|
|
4187
|
-
tableHeader(["NAME", "SIZE", "MODIFIED"], [nameWidth, sizeWidth, modifiedWidth]);
|
|
4188
|
-
for (const model of models) {
|
|
4189
|
-
const name = magenta(model.name.padEnd(nameWidth));
|
|
4190
|
-
const size = formatSize(model.size).padStart(sizeWidth);
|
|
4191
|
-
const modified = dim(formatRelativeTime(model.modified_at));
|
|
4192
|
-
console.log(`${name} ${size} ${modified}`);
|
|
4193
|
-
}
|
|
4194
|
-
console.log("");
|
|
4195
|
-
console.log(dim(`${models.length} model(s) installed`));
|
|
4196
|
-
} catch (err) {
|
|
4197
|
-
const ollamaUrl = getOllamaUrl();
|
|
4198
|
-
console.log(error(`Could not connect to Ollama at ${ollamaUrl}`));
|
|
4199
|
-
console.log(dim(` Make sure Ollama is running: ${cmd("loclaude docker-up")}`));
|
|
4200
|
-
process.exit(1);
|
|
4201
|
-
}
|
|
4202
|
-
}
|
|
4203
|
-
async function modelsPull(modelName) {
|
|
4204
|
-
if (!modelName) {
|
|
4205
|
-
console.log(error("Model name required"));
|
|
4206
|
-
console.log(dim(`Usage: ${cmd("loclaude models-pull <model-name>")}`));
|
|
4207
|
-
console.log(dim(`Example: ${cmd("loclaude models-pull llama3.2")}`));
|
|
4208
|
-
process.exit(1);
|
|
4209
|
-
}
|
|
4210
|
-
console.log(info(`Pulling model: ${magenta(modelName)}`));
|
|
4211
|
-
console.log("");
|
|
4212
|
-
const exitCode = await runOllamaCommand(["pull", modelName]);
|
|
4213
|
-
if (exitCode === 0) {
|
|
4214
|
-
console.log("");
|
|
4215
|
-
console.log(success(`Model '${magenta(modelName)}' pulled successfully`));
|
|
4216
|
-
}
|
|
4217
|
-
process.exit(exitCode);
|
|
4218
|
-
}
|
|
4219
|
-
async function modelsRm(modelName) {
|
|
4220
|
-
if (!modelName) {
|
|
4221
|
-
console.log(error("Model name required"));
|
|
4222
|
-
console.log(dim(`Usage: ${cmd("loclaude models-rm <model-name>")}`));
|
|
4223
|
-
process.exit(1);
|
|
4224
|
-
}
|
|
4225
|
-
console.log(info(`Removing model: ${magenta(modelName)}`));
|
|
4226
|
-
console.log("");
|
|
4227
|
-
const exitCode = await runOllamaCommand(["rm", modelName]);
|
|
4228
|
-
if (exitCode === 0) {
|
|
4229
|
-
console.log("");
|
|
4230
|
-
console.log(success(`Model '${magenta(modelName)}' removed`));
|
|
4231
|
-
}
|
|
4232
|
-
process.exit(exitCode);
|
|
4233
|
-
}
|
|
4234
|
-
async function modelsShow(modelName) {
|
|
4235
|
-
if (!modelName) {
|
|
4236
|
-
console.log(error("Model name required"));
|
|
4237
|
-
console.log(dim(`Usage: ${cmd("loclaude models-show <model-name>")}`));
|
|
4238
|
-
process.exit(1);
|
|
4239
|
-
}
|
|
4240
|
-
console.log(info(`Model details: ${magenta(modelName)}`));
|
|
4241
|
-
console.log("");
|
|
4242
|
-
const exitCode = await runOllamaCommand(["show", modelName]);
|
|
4243
|
-
process.exit(exitCode);
|
|
4244
|
-
}
|
|
4245
|
-
async function modelsRun(modelName) {
|
|
4246
|
-
if (!modelName) {
|
|
4247
|
-
console.log(error("Model name required"));
|
|
4248
|
-
console.log(dim(`Usage: ${cmd("loclaude models-run <model-name>")}`));
|
|
4249
|
-
process.exit(1);
|
|
4250
|
-
}
|
|
4251
|
-
console.log(info(`Running model: ${magenta(modelName)}`));
|
|
4252
|
-
console.log("");
|
|
4253
|
-
const exitCode = await runOllamaCommand(["run", modelName]);
|
|
4254
|
-
process.exit(exitCode);
|
|
4255
|
-
}
|
|
4256
|
-
function formatRelativeTime(dateStr) {
|
|
4257
|
-
const date = new Date(dateStr);
|
|
4258
|
-
const now = new Date;
|
|
4259
|
-
const diffMs = now.getTime() - date.getTime();
|
|
4260
|
-
const diffSecs = Math.floor(diffMs / 1000);
|
|
4261
|
-
const diffMins = Math.floor(diffSecs / 60);
|
|
4262
|
-
const diffHours = Math.floor(diffMins / 60);
|
|
4263
|
-
const diffDays = Math.floor(diffHours / 24);
|
|
4264
|
-
const diffWeeks = Math.floor(diffDays / 7);
|
|
4265
|
-
if (diffSecs < 60)
|
|
4266
|
-
return "just now";
|
|
4267
|
-
if (diffMins < 60)
|
|
4268
|
-
return `${diffMins} minute${diffMins === 1 ? "" : "s"} ago`;
|
|
4269
|
-
if (diffHours < 24)
|
|
4270
|
-
return `${diffHours} hour${diffHours === 1 ? "" : "s"} ago`;
|
|
4271
|
-
if (diffDays < 7)
|
|
4272
|
-
return `${diffDays} day${diffDays === 1 ? "" : "s"} ago`;
|
|
4273
|
-
if (diffWeeks < 4)
|
|
4274
|
-
return `${diffWeeks} week${diffWeeks === 1 ? "" : "s"} ago`;
|
|
4275
|
-
return date.toLocaleDateString();
|
|
4276
|
-
}
|
|
4277
|
-
// lib/cac.ts
|
|
4278
|
-
var cli = dist_default("loclaude");
|
|
4279
|
-
cli.command("run [...args]", "Run Claude Code with local Ollama", {
|
|
4280
|
-
allowUnknownOptions: true
|
|
4281
|
-
}).alias("x").option("-m, --model <name>", "Specify model to use").action(async (args, options) => {
|
|
4282
|
-
let model;
|
|
4283
|
-
if (options.model) {
|
|
4284
|
-
model = options.model;
|
|
4285
|
-
} else if (args.includes("--help") || args.includes("-h")) {
|
|
4286
|
-
model = DEFAULT_MODEL;
|
|
4287
|
-
} else {
|
|
4288
|
-
model = await selectModelInteractively();
|
|
4289
|
-
}
|
|
4290
|
-
await launchClaude(model, args);
|
|
4291
|
-
});
|
|
4292
|
-
cli.command("init", "Initialize a new loclaude project").option("--force", "Overwrite existing files").option("--no-webui", "Skip Open WebUI in docker-compose").option("--gpu", "Force GPU mode (NVIDIA)").option("--no-gpu", "Force CPU-only mode").action(async (options) => {
|
|
4293
|
-
await init(options);
|
|
4294
|
-
});
|
|
4295
|
-
cli.command("doctor", "Check system requirements and health").action(async () => {
|
|
4296
|
-
await doctor();
|
|
4297
|
-
});
|
|
4298
|
-
cli.command("config", "Show current configuration").action(async () => {
|
|
4299
|
-
await configShow();
|
|
4300
|
-
});
|
|
4301
|
-
cli.command("config-paths", "Show config file search paths").action(async () => {
|
|
4302
|
-
await configPaths();
|
|
4303
|
-
});
|
|
4304
|
-
cli.command("docker-up", "Start Ollama and Open WebUI containers").option("-f, --file <path>", "Path to docker-compose.yml").option("--no-detach", "Run in foreground (don't detach)").action(async (options) => {
|
|
4305
|
-
await dockerUp(options);
|
|
4306
|
-
});
|
|
4307
|
-
cli.command("docker-down", "Stop containers").option("-f, --file <path>", "Path to docker-compose.yml").action(async (options) => {
|
|
4308
|
-
await dockerDown(options);
|
|
4309
|
-
});
|
|
4310
|
-
cli.command("docker-status", "Show container status").option("-f, --file <path>", "Path to docker-compose.yml").action(async (options) => {
|
|
4311
|
-
await dockerStatus(options);
|
|
4312
|
-
});
|
|
4313
|
-
cli.command("docker-logs", "Show container logs").option("-f, --file <path>", "Path to docker-compose.yml").option("--follow", "Follow log output").option("-s, --service <name>", "Show logs for specific service").action(async (options) => {
|
|
4314
|
-
await dockerLogs(options);
|
|
4315
|
-
});
|
|
4316
|
-
cli.command("docker-restart", "Restart containers").option("-f, --file <path>", "Path to docker-compose.yml").action(async (options) => {
|
|
4317
|
-
await dockerRestart(options);
|
|
4318
|
-
});
|
|
4319
|
-
cli.command("models", "List installed Ollama models").action(async () => {
|
|
4320
|
-
await modelsList();
|
|
4321
|
-
});
|
|
4322
|
-
cli.command("models-pull <name>", "Pull a model from Ollama registry").action(async (name) => {
|
|
4323
|
-
await modelsPull(name);
|
|
4324
|
-
});
|
|
4325
|
-
cli.command("models-rm <name>", "Remove an installed model").action(async (name) => {
|
|
4326
|
-
await modelsRm(name);
|
|
4327
|
-
});
|
|
4328
|
-
cli.command("models-show <name>", "Show model information").action(async (name) => {
|
|
4329
|
-
await modelsShow(name);
|
|
4330
|
-
});
|
|
4331
|
-
cli.command("models-run <name>", "Run a model interactively").action(async (name) => {
|
|
4332
|
-
await modelsRun(name);
|
|
4333
|
-
});
|
|
4334
|
-
cli.help();
|
|
4335
|
-
cli.version("0.0.1-rc.1");
|
|
4336
|
-
var help = () => cli.outputHelp();
|
|
4337
|
-
var version = () => cli.outputVersion();
|
|
4338
|
-
var run_cli = () => {
|
|
4339
|
-
cli.parse();
|
|
4340
|
-
};
|
|
4341
|
-
export {
|
|
4342
|
-
version,
|
|
4343
|
-
run_cli,
|
|
4344
|
-
help,
|
|
4345
|
-
cli
|
|
4346
|
-
};
|
|
4347
|
-
|
|
4348
|
-
//# debugId=8AC1271036F3EB4864756E2164756E21
|
|
4349
|
-
//# sourceMappingURL=index.bun.js.map
|