@iannuttall/dotagents 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -8
- package/dist/cli.js +2119 -1517
- package/package.json +5 -9
package/dist/cli.js
CHANGED
|
@@ -19,6 +19,134 @@ var __toESM = (mod, isNodeMode, target) => {
|
|
|
19
19
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
20
20
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
21
21
|
|
|
22
|
+
// node_modules/sisteransi/src/index.js
|
|
23
|
+
var require_src = __commonJS((exports, module) => {
|
|
24
|
+
var ESC = "\x1B";
|
|
25
|
+
var CSI = `${ESC}[`;
|
|
26
|
+
var beep = "\x07";
|
|
27
|
+
var cursor = {
|
|
28
|
+
to(x, y) {
|
|
29
|
+
if (!y)
|
|
30
|
+
return `${CSI}${x + 1}G`;
|
|
31
|
+
return `${CSI}${y + 1};${x + 1}H`;
|
|
32
|
+
},
|
|
33
|
+
move(x, y) {
|
|
34
|
+
let ret = "";
|
|
35
|
+
if (x < 0)
|
|
36
|
+
ret += `${CSI}${-x}D`;
|
|
37
|
+
else if (x > 0)
|
|
38
|
+
ret += `${CSI}${x}C`;
|
|
39
|
+
if (y < 0)
|
|
40
|
+
ret += `${CSI}${-y}A`;
|
|
41
|
+
else if (y > 0)
|
|
42
|
+
ret += `${CSI}${y}B`;
|
|
43
|
+
return ret;
|
|
44
|
+
},
|
|
45
|
+
up: (count = 1) => `${CSI}${count}A`,
|
|
46
|
+
down: (count = 1) => `${CSI}${count}B`,
|
|
47
|
+
forward: (count = 1) => `${CSI}${count}C`,
|
|
48
|
+
backward: (count = 1) => `${CSI}${count}D`,
|
|
49
|
+
nextLine: (count = 1) => `${CSI}E`.repeat(count),
|
|
50
|
+
prevLine: (count = 1) => `${CSI}F`.repeat(count),
|
|
51
|
+
left: `${CSI}G`,
|
|
52
|
+
hide: `${CSI}?25l`,
|
|
53
|
+
show: `${CSI}?25h`,
|
|
54
|
+
save: `${ESC}7`,
|
|
55
|
+
restore: `${ESC}8`
|
|
56
|
+
};
|
|
57
|
+
var scroll = {
|
|
58
|
+
up: (count = 1) => `${CSI}S`.repeat(count),
|
|
59
|
+
down: (count = 1) => `${CSI}T`.repeat(count)
|
|
60
|
+
};
|
|
61
|
+
var erase = {
|
|
62
|
+
screen: `${CSI}2J`,
|
|
63
|
+
up: (count = 1) => `${CSI}1J`.repeat(count),
|
|
64
|
+
down: (count = 1) => `${CSI}J`.repeat(count),
|
|
65
|
+
line: `${CSI}2K`,
|
|
66
|
+
lineEnd: `${CSI}K`,
|
|
67
|
+
lineStart: `${CSI}1K`,
|
|
68
|
+
lines(count) {
|
|
69
|
+
let clear = "";
|
|
70
|
+
for (let i = 0;i < count; i++)
|
|
71
|
+
clear += this.line + (i < count - 1 ? cursor.up() : "");
|
|
72
|
+
if (count)
|
|
73
|
+
clear += cursor.left;
|
|
74
|
+
return clear;
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
module.exports = { cursor, scroll, erase, beep };
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
// node_modules/picocolors/picocolors.js
|
|
81
|
+
var require_picocolors = __commonJS((exports, module) => {
|
|
82
|
+
var p = process || {};
|
|
83
|
+
var argv = p.argv || [];
|
|
84
|
+
var env2 = p.env || {};
|
|
85
|
+
var isColorSupported = !(!!env2.NO_COLOR || argv.includes("--no-color")) && (!!env2.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env2.TERM !== "dumb" || !!env2.CI);
|
|
86
|
+
var formatter = (open, close, replace = open) => (input) => {
|
|
87
|
+
let string = "" + input, index = string.indexOf(close, open.length);
|
|
88
|
+
return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
|
|
89
|
+
};
|
|
90
|
+
var replaceClose = (string, close, replace, index) => {
|
|
91
|
+
let result = "", cursor = 0;
|
|
92
|
+
do {
|
|
93
|
+
result += string.substring(cursor, index) + replace;
|
|
94
|
+
cursor = index + close.length;
|
|
95
|
+
index = string.indexOf(close, cursor);
|
|
96
|
+
} while (~index);
|
|
97
|
+
return result + string.substring(cursor);
|
|
98
|
+
};
|
|
99
|
+
var createColors = (enabled = isColorSupported) => {
|
|
100
|
+
let f = enabled ? formatter : () => String;
|
|
101
|
+
return {
|
|
102
|
+
isColorSupported: enabled,
|
|
103
|
+
reset: f("\x1B[0m", "\x1B[0m"),
|
|
104
|
+
bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
|
|
105
|
+
dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
|
|
106
|
+
italic: f("\x1B[3m", "\x1B[23m"),
|
|
107
|
+
underline: f("\x1B[4m", "\x1B[24m"),
|
|
108
|
+
inverse: f("\x1B[7m", "\x1B[27m"),
|
|
109
|
+
hidden: f("\x1B[8m", "\x1B[28m"),
|
|
110
|
+
strikethrough: f("\x1B[9m", "\x1B[29m"),
|
|
111
|
+
black: f("\x1B[30m", "\x1B[39m"),
|
|
112
|
+
red: f("\x1B[31m", "\x1B[39m"),
|
|
113
|
+
green: f("\x1B[32m", "\x1B[39m"),
|
|
114
|
+
yellow: f("\x1B[33m", "\x1B[39m"),
|
|
115
|
+
blue: f("\x1B[34m", "\x1B[39m"),
|
|
116
|
+
magenta: f("\x1B[35m", "\x1B[39m"),
|
|
117
|
+
cyan: f("\x1B[36m", "\x1B[39m"),
|
|
118
|
+
white: f("\x1B[37m", "\x1B[39m"),
|
|
119
|
+
gray: f("\x1B[90m", "\x1B[39m"),
|
|
120
|
+
bgBlack: f("\x1B[40m", "\x1B[49m"),
|
|
121
|
+
bgRed: f("\x1B[41m", "\x1B[49m"),
|
|
122
|
+
bgGreen: f("\x1B[42m", "\x1B[49m"),
|
|
123
|
+
bgYellow: f("\x1B[43m", "\x1B[49m"),
|
|
124
|
+
bgBlue: f("\x1B[44m", "\x1B[49m"),
|
|
125
|
+
bgMagenta: f("\x1B[45m", "\x1B[49m"),
|
|
126
|
+
bgCyan: f("\x1B[46m", "\x1B[49m"),
|
|
127
|
+
bgWhite: f("\x1B[47m", "\x1B[49m"),
|
|
128
|
+
blackBright: f("\x1B[90m", "\x1B[39m"),
|
|
129
|
+
redBright: f("\x1B[91m", "\x1B[39m"),
|
|
130
|
+
greenBright: f("\x1B[92m", "\x1B[39m"),
|
|
131
|
+
yellowBright: f("\x1B[93m", "\x1B[39m"),
|
|
132
|
+
blueBright: f("\x1B[94m", "\x1B[39m"),
|
|
133
|
+
magentaBright: f("\x1B[95m", "\x1B[39m"),
|
|
134
|
+
cyanBright: f("\x1B[96m", "\x1B[39m"),
|
|
135
|
+
whiteBright: f("\x1B[97m", "\x1B[39m"),
|
|
136
|
+
bgBlackBright: f("\x1B[100m", "\x1B[49m"),
|
|
137
|
+
bgRedBright: f("\x1B[101m", "\x1B[49m"),
|
|
138
|
+
bgGreenBright: f("\x1B[102m", "\x1B[49m"),
|
|
139
|
+
bgYellowBright: f("\x1B[103m", "\x1B[49m"),
|
|
140
|
+
bgBlueBright: f("\x1B[104m", "\x1B[49m"),
|
|
141
|
+
bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
|
|
142
|
+
bgCyanBright: f("\x1B[106m", "\x1B[49m"),
|
|
143
|
+
bgWhiteBright: f("\x1B[107m", "\x1B[49m")
|
|
144
|
+
};
|
|
145
|
+
};
|
|
146
|
+
module.exports = createColors();
|
|
147
|
+
module.exports.createColors = createColors;
|
|
148
|
+
});
|
|
149
|
+
|
|
22
150
|
// node_modules/kind-of/index.js
|
|
23
151
|
var require_kind_of = __commonJS((exports, module) => {
|
|
24
152
|
var toString = Object.prototype.toString;
|
|
@@ -164,23 +292,23 @@ var require_is_extendable = __commonJS((exports, module) => {
|
|
|
164
292
|
// node_modules/extend-shallow/index.js
|
|
165
293
|
var require_extend_shallow = __commonJS((exports, module) => {
|
|
166
294
|
var isObject = require_is_extendable();
|
|
167
|
-
module.exports = function extend(
|
|
168
|
-
if (!isObject(
|
|
169
|
-
|
|
295
|
+
module.exports = function extend(o2) {
|
|
296
|
+
if (!isObject(o2)) {
|
|
297
|
+
o2 = {};
|
|
170
298
|
}
|
|
171
299
|
var len = arguments.length;
|
|
172
300
|
for (var i = 1;i < len; i++) {
|
|
173
301
|
var obj = arguments[i];
|
|
174
302
|
if (isObject(obj)) {
|
|
175
|
-
assign(
|
|
303
|
+
assign(o2, obj);
|
|
176
304
|
}
|
|
177
305
|
}
|
|
178
|
-
return
|
|
306
|
+
return o2;
|
|
179
307
|
};
|
|
180
|
-
function assign(
|
|
181
|
-
for (var key in
|
|
182
|
-
if (hasOwn(
|
|
183
|
-
|
|
308
|
+
function assign(a3, b3) {
|
|
309
|
+
for (var key in b3) {
|
|
310
|
+
if (hasOwn(b3, key)) {
|
|
311
|
+
a3[key] = b3[key];
|
|
184
312
|
}
|
|
185
313
|
}
|
|
186
314
|
}
|
|
@@ -790,13 +918,13 @@ var require_int = __commonJS((exports, module) => {
|
|
|
790
918
|
return sign * parseInt(value, 8);
|
|
791
919
|
}
|
|
792
920
|
if (value.indexOf(":") !== -1) {
|
|
793
|
-
value.split(":").forEach(function(
|
|
794
|
-
digits.unshift(parseInt(
|
|
921
|
+
value.split(":").forEach(function(v2) {
|
|
922
|
+
digits.unshift(parseInt(v2, 10));
|
|
795
923
|
});
|
|
796
924
|
value = 0;
|
|
797
925
|
base = 1;
|
|
798
|
-
digits.forEach(function(
|
|
799
|
-
value +=
|
|
926
|
+
digits.forEach(function(d3) {
|
|
927
|
+
value += d3 * base;
|
|
800
928
|
base *= 60;
|
|
801
929
|
});
|
|
802
930
|
return sign * value;
|
|
@@ -861,13 +989,13 @@ var require_float = __commonJS((exports, module) => {
|
|
|
861
989
|
} else if (value === ".nan") {
|
|
862
990
|
return NaN;
|
|
863
991
|
} else if (value.indexOf(":") >= 0) {
|
|
864
|
-
value.split(":").forEach(function(
|
|
865
|
-
digits.unshift(parseFloat(
|
|
992
|
+
value.split(":").forEach(function(v2) {
|
|
993
|
+
digits.unshift(parseFloat(v2, 10));
|
|
866
994
|
});
|
|
867
995
|
value = 0;
|
|
868
996
|
base = 1;
|
|
869
|
-
digits.forEach(function(
|
|
870
|
-
value +=
|
|
997
|
+
digits.forEach(function(d3) {
|
|
998
|
+
value += d3 * base;
|
|
871
999
|
base *= 60;
|
|
872
1000
|
});
|
|
873
1001
|
return sign * value;
|
|
@@ -1321,7 +1449,7 @@ var require_function = __commonJS((exports, module) => {
|
|
|
1321
1449
|
try {
|
|
1322
1450
|
_require = __require;
|
|
1323
1451
|
esprima = _require("esprima");
|
|
1324
|
-
} catch (
|
|
1452
|
+
} catch (_3) {
|
|
1325
1453
|
if (typeof window !== "undefined")
|
|
1326
1454
|
esprima = window.esprima;
|
|
1327
1455
|
}
|
|
@@ -3378,7 +3506,7 @@ var require_parse = __commonJS((exports, module) => {
|
|
|
3378
3506
|
|
|
3379
3507
|
// node_modules/gray-matter/index.js
|
|
3380
3508
|
var require_gray_matter = __commonJS((exports, module) => {
|
|
3381
|
-
var
|
|
3509
|
+
var fs4 = __require("fs");
|
|
3382
3510
|
var sections = require_section_matter();
|
|
3383
3511
|
var defaults = require_defaults();
|
|
3384
3512
|
var stringify = require_stringify();
|
|
@@ -3465,7 +3593,7 @@ var require_gray_matter = __commonJS((exports, module) => {
|
|
|
3465
3593
|
return stringify(file, data, options2);
|
|
3466
3594
|
};
|
|
3467
3595
|
matter.read = function(filepath, options2) {
|
|
3468
|
-
const str2 =
|
|
3596
|
+
const str2 = fs4.readFileSync(filepath, "utf8");
|
|
3469
3597
|
const file = matter(str2, options2);
|
|
3470
3598
|
file.path = filepath;
|
|
3471
3599
|
return file;
|
|
@@ -3493,292 +3621,1346 @@ var require_gray_matter = __commonJS((exports, module) => {
|
|
|
3493
3621
|
});
|
|
3494
3622
|
|
|
3495
3623
|
// src/cli.tsx
|
|
3496
|
-
import
|
|
3497
|
-
|
|
3498
|
-
// src/tui/App.tsx
|
|
3499
|
-
import { useEffect as useEffect2, useMemo, useState } from "react";
|
|
3500
|
-
import fs10 from "fs";
|
|
3501
|
-
import { Box as Box4, Text as Text2, useApp, useInput as useInput2, useStdout as useStdout3 } from "ink";
|
|
3502
|
-
import SelectInput from "ink-select-input";
|
|
3503
|
-
import TextInput from "ink-text-input";
|
|
3504
|
-
import Spinner from "ink-spinner";
|
|
3505
|
-
|
|
3506
|
-
// src/core/plan.ts
|
|
3507
|
-
import fs2 from "fs";
|
|
3508
|
-
import path4 from "path";
|
|
3509
|
-
|
|
3510
|
-
// src/core/mappings.ts
|
|
3511
|
-
import path2 from "path";
|
|
3624
|
+
import path12 from "path";
|
|
3512
3625
|
|
|
3513
|
-
//
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
|
|
3518
|
-
|
|
3519
|
-
|
|
3520
|
-
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
|
|
3626
|
+
// node_modules/chalk/source/vendor/ansi-styles/index.js
|
|
3627
|
+
var ANSI_BACKGROUND_OFFSET = 10;
|
|
3628
|
+
var wrapAnsi16 = (offset = 0) => (code) => `\x1B[${code + offset}m`;
|
|
3629
|
+
var wrapAnsi256 = (offset = 0) => (code) => `\x1B[${38 + offset};5;${code}m`;
|
|
3630
|
+
var wrapAnsi16m = (offset = 0) => (red, green, blue) => `\x1B[${38 + offset};2;${red};${green};${blue}m`;
|
|
3631
|
+
var styles = {
|
|
3632
|
+
modifier: {
|
|
3633
|
+
reset: [0, 0],
|
|
3634
|
+
bold: [1, 22],
|
|
3635
|
+
dim: [2, 22],
|
|
3636
|
+
italic: [3, 23],
|
|
3637
|
+
underline: [4, 24],
|
|
3638
|
+
overline: [53, 55],
|
|
3639
|
+
inverse: [7, 27],
|
|
3640
|
+
hidden: [8, 28],
|
|
3641
|
+
strikethrough: [9, 29]
|
|
3642
|
+
},
|
|
3643
|
+
color: {
|
|
3644
|
+
black: [30, 39],
|
|
3645
|
+
red: [31, 39],
|
|
3646
|
+
green: [32, 39],
|
|
3647
|
+
yellow: [33, 39],
|
|
3648
|
+
blue: [34, 39],
|
|
3649
|
+
magenta: [35, 39],
|
|
3650
|
+
cyan: [36, 39],
|
|
3651
|
+
white: [37, 39],
|
|
3652
|
+
blackBright: [90, 39],
|
|
3653
|
+
gray: [90, 39],
|
|
3654
|
+
grey: [90, 39],
|
|
3655
|
+
redBright: [91, 39],
|
|
3656
|
+
greenBright: [92, 39],
|
|
3657
|
+
yellowBright: [93, 39],
|
|
3658
|
+
blueBright: [94, 39],
|
|
3659
|
+
magentaBright: [95, 39],
|
|
3660
|
+
cyanBright: [96, 39],
|
|
3661
|
+
whiteBright: [97, 39]
|
|
3662
|
+
},
|
|
3663
|
+
bgColor: {
|
|
3664
|
+
bgBlack: [40, 49],
|
|
3665
|
+
bgRed: [41, 49],
|
|
3666
|
+
bgGreen: [42, 49],
|
|
3667
|
+
bgYellow: [43, 49],
|
|
3668
|
+
bgBlue: [44, 49],
|
|
3669
|
+
bgMagenta: [45, 49],
|
|
3670
|
+
bgCyan: [46, 49],
|
|
3671
|
+
bgWhite: [47, 49],
|
|
3672
|
+
bgBlackBright: [100, 49],
|
|
3673
|
+
bgGray: [100, 49],
|
|
3674
|
+
bgGrey: [100, 49],
|
|
3675
|
+
bgRedBright: [101, 49],
|
|
3676
|
+
bgGreenBright: [102, 49],
|
|
3677
|
+
bgYellowBright: [103, 49],
|
|
3678
|
+
bgBlueBright: [104, 49],
|
|
3679
|
+
bgMagentaBright: [105, 49],
|
|
3680
|
+
bgCyanBright: [106, 49],
|
|
3681
|
+
bgWhiteBright: [107, 49]
|
|
3528
3682
|
}
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3683
|
+
};
|
|
3684
|
+
var modifierNames = Object.keys(styles.modifier);
|
|
3685
|
+
var foregroundColorNames = Object.keys(styles.color);
|
|
3686
|
+
var backgroundColorNames = Object.keys(styles.bgColor);
|
|
3687
|
+
var colorNames = [...foregroundColorNames, ...backgroundColorNames];
|
|
3688
|
+
function assembleStyles() {
|
|
3689
|
+
const codes = new Map;
|
|
3690
|
+
for (const [groupName, group] of Object.entries(styles)) {
|
|
3691
|
+
for (const [styleName, style] of Object.entries(group)) {
|
|
3692
|
+
styles[styleName] = {
|
|
3693
|
+
open: `\x1B[${style[0]}m`,
|
|
3694
|
+
close: `\x1B[${style[1]}m`
|
|
3695
|
+
};
|
|
3696
|
+
group[styleName] = styles[styleName];
|
|
3697
|
+
codes.set(style[0], style[1]);
|
|
3698
|
+
}
|
|
3699
|
+
Object.defineProperty(styles, groupName, {
|
|
3700
|
+
value: group,
|
|
3701
|
+
enumerable: false
|
|
3702
|
+
});
|
|
3703
|
+
}
|
|
3704
|
+
Object.defineProperty(styles, "codes", {
|
|
3705
|
+
value: codes,
|
|
3706
|
+
enumerable: false
|
|
3707
|
+
});
|
|
3708
|
+
styles.color.close = "\x1B[39m";
|
|
3709
|
+
styles.bgColor.close = "\x1B[49m";
|
|
3710
|
+
styles.color.ansi = wrapAnsi16();
|
|
3711
|
+
styles.color.ansi256 = wrapAnsi256();
|
|
3712
|
+
styles.color.ansi16m = wrapAnsi16m();
|
|
3713
|
+
styles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET);
|
|
3714
|
+
styles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET);
|
|
3715
|
+
styles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET);
|
|
3716
|
+
Object.defineProperties(styles, {
|
|
3717
|
+
rgbToAnsi256: {
|
|
3718
|
+
value(red, green, blue) {
|
|
3719
|
+
if (red === green && green === blue) {
|
|
3720
|
+
if (red < 8) {
|
|
3721
|
+
return 16;
|
|
3722
|
+
}
|
|
3723
|
+
if (red > 248) {
|
|
3724
|
+
return 231;
|
|
3725
|
+
}
|
|
3726
|
+
return Math.round((red - 8) / 247 * 24) + 232;
|
|
3727
|
+
}
|
|
3728
|
+
return 16 + 36 * Math.round(red / 255 * 5) + 6 * Math.round(green / 255 * 5) + Math.round(blue / 255 * 5);
|
|
3729
|
+
},
|
|
3730
|
+
enumerable: false
|
|
3731
|
+
},
|
|
3732
|
+
hexToRgb: {
|
|
3733
|
+
value(hex) {
|
|
3734
|
+
const matches = /[a-f\d]{6}|[a-f\d]{3}/i.exec(hex.toString(16));
|
|
3735
|
+
if (!matches) {
|
|
3736
|
+
return [0, 0, 0];
|
|
3737
|
+
}
|
|
3738
|
+
let [colorString] = matches;
|
|
3739
|
+
if (colorString.length === 3) {
|
|
3740
|
+
colorString = [...colorString].map((character) => character + character).join("");
|
|
3741
|
+
}
|
|
3742
|
+
const integer = Number.parseInt(colorString, 16);
|
|
3743
|
+
return [
|
|
3744
|
+
integer >> 16 & 255,
|
|
3745
|
+
integer >> 8 & 255,
|
|
3746
|
+
integer & 255
|
|
3747
|
+
];
|
|
3748
|
+
},
|
|
3749
|
+
enumerable: false
|
|
3750
|
+
},
|
|
3751
|
+
hexToAnsi256: {
|
|
3752
|
+
value: (hex) => styles.rgbToAnsi256(...styles.hexToRgb(hex)),
|
|
3753
|
+
enumerable: false
|
|
3549
3754
|
},
|
|
3550
|
-
{
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
|
|
3755
|
+
ansi256ToAnsi: {
|
|
3756
|
+
value(code) {
|
|
3757
|
+
if (code < 8) {
|
|
3758
|
+
return 30 + code;
|
|
3759
|
+
}
|
|
3760
|
+
if (code < 16) {
|
|
3761
|
+
return 90 + (code - 8);
|
|
3762
|
+
}
|
|
3763
|
+
let red;
|
|
3764
|
+
let green;
|
|
3765
|
+
let blue;
|
|
3766
|
+
if (code >= 232) {
|
|
3767
|
+
red = ((code - 232) * 10 + 8) / 255;
|
|
3768
|
+
green = red;
|
|
3769
|
+
blue = red;
|
|
3770
|
+
} else {
|
|
3771
|
+
code -= 16;
|
|
3772
|
+
const remainder = code % 36;
|
|
3773
|
+
red = Math.floor(code / 36) / 5;
|
|
3774
|
+
green = Math.floor(remainder / 6) / 5;
|
|
3775
|
+
blue = remainder % 6 / 5;
|
|
3776
|
+
}
|
|
3777
|
+
const value = Math.max(red, green, blue) * 2;
|
|
3778
|
+
if (value === 0) {
|
|
3779
|
+
return 30;
|
|
3780
|
+
}
|
|
3781
|
+
let result = 30 + (Math.round(blue) << 2 | Math.round(green) << 1 | Math.round(red));
|
|
3782
|
+
if (value === 2) {
|
|
3783
|
+
result += 60;
|
|
3784
|
+
}
|
|
3785
|
+
return result;
|
|
3786
|
+
},
|
|
3787
|
+
enumerable: false
|
|
3559
3788
|
},
|
|
3560
|
-
{
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
targets: [
|
|
3564
|
-
path2.join(roots.claudeRoot, "hooks"),
|
|
3565
|
-
path2.join(roots.factoryRoot, "hooks")
|
|
3566
|
-
],
|
|
3567
|
-
kind: "dir"
|
|
3789
|
+
rgbToAnsi: {
|
|
3790
|
+
value: (red, green, blue) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)),
|
|
3791
|
+
enumerable: false
|
|
3568
3792
|
},
|
|
3569
|
-
{
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
targets: [
|
|
3573
|
-
path2.join(roots.claudeRoot, "skills"),
|
|
3574
|
-
path2.join(roots.factoryRoot, "skills")
|
|
3575
|
-
],
|
|
3576
|
-
kind: "dir"
|
|
3793
|
+
hexToAnsi: {
|
|
3794
|
+
value: (hex) => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)),
|
|
3795
|
+
enumerable: false
|
|
3577
3796
|
}
|
|
3578
|
-
|
|
3797
|
+
});
|
|
3798
|
+
return styles;
|
|
3579
3799
|
}
|
|
3800
|
+
var ansiStyles = assembleStyles();
|
|
3801
|
+
var ansi_styles_default = ansiStyles;
|
|
3580
3802
|
|
|
3581
|
-
//
|
|
3582
|
-
import
|
|
3583
|
-
import
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
return false;
|
|
3591
|
-
throw err;
|
|
3592
|
-
}
|
|
3593
|
-
}
|
|
3594
|
-
async function ensureDir(dir) {
|
|
3595
|
-
await fs.promises.mkdir(dir, { recursive: true });
|
|
3596
|
-
}
|
|
3597
|
-
async function ensureFile(filePath, content) {
|
|
3598
|
-
await ensureDir(path3.dirname(filePath));
|
|
3599
|
-
await fs.promises.writeFile(filePath, content, "utf8");
|
|
3600
|
-
}
|
|
3601
|
-
async function readText(filePath) {
|
|
3602
|
-
return await fs.promises.readFile(filePath, "utf8");
|
|
3603
|
-
}
|
|
3604
|
-
async function copyFile(src, dest, force = false) {
|
|
3605
|
-
if (!force && await pathExists(dest))
|
|
3606
|
-
return "skipped";
|
|
3607
|
-
await ensureDir(path3.dirname(dest));
|
|
3608
|
-
await fs.promises.copyFile(src, dest);
|
|
3609
|
-
return "written";
|
|
3803
|
+
// node_modules/chalk/source/vendor/supports-color/index.js
|
|
3804
|
+
import process2 from "node:process";
|
|
3805
|
+
import os from "node:os";
|
|
3806
|
+
import tty from "node:tty";
|
|
3807
|
+
function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process2.argv) {
|
|
3808
|
+
const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
|
|
3809
|
+
const position = argv.indexOf(prefix + flag);
|
|
3810
|
+
const terminatorPosition = argv.indexOf("--");
|
|
3811
|
+
return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
|
|
3610
3812
|
}
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
3813
|
+
var { env } = process2;
|
|
3814
|
+
var flagForceColor;
|
|
3815
|
+
if (hasFlag("no-color") || hasFlag("no-colors") || hasFlag("color=false") || hasFlag("color=never")) {
|
|
3816
|
+
flagForceColor = 0;
|
|
3817
|
+
} else if (hasFlag("color") || hasFlag("colors") || hasFlag("color=true") || hasFlag("color=always")) {
|
|
3818
|
+
flagForceColor = 1;
|
|
3617
3819
|
}
|
|
3618
|
-
|
|
3619
|
-
if (
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3820
|
+
function envForceColor() {
|
|
3821
|
+
if ("FORCE_COLOR" in env) {
|
|
3822
|
+
if (env.FORCE_COLOR === "true") {
|
|
3823
|
+
return 1;
|
|
3824
|
+
}
|
|
3825
|
+
if (env.FORCE_COLOR === "false") {
|
|
3826
|
+
return 0;
|
|
3827
|
+
}
|
|
3828
|
+
return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);
|
|
3626
3829
|
}
|
|
3627
3830
|
}
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
|
|
3631
|
-
return entries.filter((e) => e.isFile()).map((e) => path3.join(dir, e.name));
|
|
3632
|
-
} catch (err) {
|
|
3633
|
-
if (err && err.code === "ENOENT")
|
|
3634
|
-
return [];
|
|
3635
|
-
throw err;
|
|
3831
|
+
function translateLevel(level) {
|
|
3832
|
+
if (level === 0) {
|
|
3833
|
+
return false;
|
|
3636
3834
|
}
|
|
3835
|
+
return {
|
|
3836
|
+
level,
|
|
3837
|
+
hasBasic: true,
|
|
3838
|
+
has256: level >= 2,
|
|
3839
|
+
has16m: level >= 3
|
|
3840
|
+
};
|
|
3637
3841
|
}
|
|
3638
|
-
|
|
3639
|
-
const
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
async function listDirs(dir) {
|
|
3643
|
-
try {
|
|
3644
|
-
const entries = await fs.promises.readdir(dir, { withFileTypes: true });
|
|
3645
|
-
return entries.filter((e) => e.isDirectory()).map((e) => path3.join(dir, e.name));
|
|
3646
|
-
} catch (err) {
|
|
3647
|
-
if (err && err.code === "ENOENT")
|
|
3648
|
-
return [];
|
|
3649
|
-
throw err;
|
|
3842
|
+
function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
|
|
3843
|
+
const noFlagForceColor = envForceColor();
|
|
3844
|
+
if (noFlagForceColor !== undefined) {
|
|
3845
|
+
flagForceColor = noFlagForceColor;
|
|
3650
3846
|
}
|
|
3651
|
-
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3847
|
+
const forceColor = sniffFlags ? flagForceColor : noFlagForceColor;
|
|
3848
|
+
if (forceColor === 0) {
|
|
3849
|
+
return 0;
|
|
3850
|
+
}
|
|
3851
|
+
if (sniffFlags) {
|
|
3852
|
+
if (hasFlag("color=16m") || hasFlag("color=full") || hasFlag("color=truecolor")) {
|
|
3853
|
+
return 3;
|
|
3854
|
+
}
|
|
3855
|
+
if (hasFlag("color=256")) {
|
|
3856
|
+
return 2;
|
|
3659
3857
|
}
|
|
3660
|
-
return link;
|
|
3661
|
-
} catch {
|
|
3662
|
-
return null;
|
|
3663
3858
|
}
|
|
3664
|
-
|
|
3665
|
-
|
|
3666
|
-
const exists = await pathExists(source);
|
|
3667
|
-
if (!exists)
|
|
3668
|
-
return [{ type: "ensure-source", path: source, kind }];
|
|
3669
|
-
const stat = await fs2.promises.lstat(source);
|
|
3670
|
-
if (kind === "file" && stat.isDirectory()) {
|
|
3671
|
-
return [{ type: "conflict", source, target: source, reason: "Expected file but found directory", kind }];
|
|
3859
|
+
if ("TF_BUILD" in env && "AGENT_NAME" in env) {
|
|
3860
|
+
return 1;
|
|
3672
3861
|
}
|
|
3673
|
-
if (
|
|
3674
|
-
return
|
|
3862
|
+
if (haveStream && !streamIsTTY && forceColor === undefined) {
|
|
3863
|
+
return 0;
|
|
3675
3864
|
}
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
if (
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
const resolved = await getLinkTargetAbsolute(target);
|
|
3685
|
-
if (resolved && path4.resolve(resolved) === path4.resolve(source)) {
|
|
3686
|
-
return { type: "noop", source, target };
|
|
3865
|
+
const min = forceColor || 0;
|
|
3866
|
+
if (env.TERM === "dumb") {
|
|
3867
|
+
return min;
|
|
3868
|
+
}
|
|
3869
|
+
if (process2.platform === "win32") {
|
|
3870
|
+
const osRelease = os.release().split(".");
|
|
3871
|
+
if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
|
|
3872
|
+
return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
3687
3873
|
}
|
|
3688
|
-
|
|
3689
|
-
return { type: "conflict", source, target, reason: detail, kind };
|
|
3874
|
+
return 1;
|
|
3690
3875
|
}
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
|
|
3694
|
-
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
for (const mapping of mappings) {
|
|
3698
|
-
tasks.push(...await ensureSourceTask(mapping.source, mapping.kind));
|
|
3699
|
-
for (const target of mapping.targets) {
|
|
3700
|
-
tasks.push(await analyzeTarget(mapping.source, target, mapping.kind));
|
|
3876
|
+
if ("CI" in env) {
|
|
3877
|
+
if (["GITHUB_ACTIONS", "GITEA_ACTIONS", "CIRCLECI"].some((key) => (key in env))) {
|
|
3878
|
+
return 3;
|
|
3879
|
+
}
|
|
3880
|
+
if (["TRAVIS", "APPVEYOR", "GITLAB_CI", "BUILDKITE", "DRONE"].some((sign) => (sign in env)) || env.CI_NAME === "codeship") {
|
|
3881
|
+
return 1;
|
|
3701
3882
|
}
|
|
3883
|
+
return min;
|
|
3702
3884
|
}
|
|
3703
|
-
|
|
3704
|
-
|
|
3705
|
-
|
|
3885
|
+
if ("TEAMCITY_VERSION" in env) {
|
|
3886
|
+
return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
|
|
3887
|
+
}
|
|
3888
|
+
if (env.COLORTERM === "truecolor") {
|
|
3889
|
+
return 3;
|
|
3890
|
+
}
|
|
3891
|
+
if (env.TERM === "xterm-kitty") {
|
|
3892
|
+
return 3;
|
|
3893
|
+
}
|
|
3894
|
+
if (env.TERM === "xterm-ghostty") {
|
|
3895
|
+
return 3;
|
|
3896
|
+
}
|
|
3897
|
+
if (env.TERM === "wezterm") {
|
|
3898
|
+
return 3;
|
|
3899
|
+
}
|
|
3900
|
+
if ("TERM_PROGRAM" in env) {
|
|
3901
|
+
const version = Number.parseInt((env.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
|
|
3902
|
+
switch (env.TERM_PROGRAM) {
|
|
3903
|
+
case "iTerm.app": {
|
|
3904
|
+
return version >= 3 ? 3 : 2;
|
|
3905
|
+
}
|
|
3906
|
+
case "Apple_Terminal": {
|
|
3907
|
+
return 2;
|
|
3908
|
+
}
|
|
3909
|
+
}
|
|
3910
|
+
}
|
|
3911
|
+
if (/-256(color)?$/i.test(env.TERM)) {
|
|
3912
|
+
return 2;
|
|
3913
|
+
}
|
|
3914
|
+
if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
|
|
3915
|
+
return 1;
|
|
3916
|
+
}
|
|
3917
|
+
if ("COLORTERM" in env) {
|
|
3918
|
+
return 1;
|
|
3919
|
+
}
|
|
3920
|
+
return min;
|
|
3921
|
+
}
|
|
3922
|
+
function createSupportsColor(stream, options2 = {}) {
|
|
3923
|
+
const level = _supportsColor(stream, {
|
|
3924
|
+
streamIsTTY: stream && stream.isTTY,
|
|
3925
|
+
...options2
|
|
3926
|
+
});
|
|
3927
|
+
return translateLevel(level);
|
|
3706
3928
|
}
|
|
3929
|
+
var supportsColor = {
|
|
3930
|
+
stdout: createSupportsColor({ isTTY: tty.isatty(1) }),
|
|
3931
|
+
stderr: createSupportsColor({ isTTY: tty.isatty(2) })
|
|
3932
|
+
};
|
|
3933
|
+
var supports_color_default = supportsColor;
|
|
3707
3934
|
|
|
3708
|
-
//
|
|
3709
|
-
|
|
3710
|
-
|
|
3711
|
-
|
|
3935
|
+
// node_modules/chalk/source/utilities.js
|
|
3936
|
+
function stringReplaceAll(string, substring, replacer) {
|
|
3937
|
+
let index = string.indexOf(substring);
|
|
3938
|
+
if (index === -1) {
|
|
3939
|
+
return string;
|
|
3940
|
+
}
|
|
3941
|
+
const substringLength = substring.length;
|
|
3942
|
+
let endIndex = 0;
|
|
3943
|
+
let returnValue = "";
|
|
3944
|
+
do {
|
|
3945
|
+
returnValue += string.slice(endIndex, index) + substring + replacer;
|
|
3946
|
+
endIndex = index + substringLength;
|
|
3947
|
+
index = string.indexOf(substring, endIndex);
|
|
3948
|
+
} while (index !== -1);
|
|
3949
|
+
returnValue += string.slice(endIndex);
|
|
3950
|
+
return returnValue;
|
|
3951
|
+
}
|
|
3952
|
+
function stringEncaseCRLFWithFirstIndex(string, prefix, postfix, index) {
|
|
3953
|
+
let endIndex = 0;
|
|
3954
|
+
let returnValue = "";
|
|
3955
|
+
do {
|
|
3956
|
+
const gotCR = string[index - 1] === "\r";
|
|
3957
|
+
returnValue += string.slice(endIndex, gotCR ? index - 1 : index) + prefix + (gotCR ? `\r
|
|
3958
|
+
` : `
|
|
3959
|
+
`) + postfix;
|
|
3960
|
+
endIndex = index + 1;
|
|
3961
|
+
index = string.indexOf(`
|
|
3962
|
+
`, endIndex);
|
|
3963
|
+
} while (index !== -1);
|
|
3964
|
+
returnValue += string.slice(endIndex);
|
|
3965
|
+
return returnValue;
|
|
3966
|
+
}
|
|
3712
3967
|
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
|
|
3716
|
-
|
|
3717
|
-
|
|
3718
|
-
|
|
3719
|
-
|
|
3720
|
-
|
|
3968
|
+
// node_modules/chalk/source/index.js
|
|
3969
|
+
var { stdout: stdoutColor, stderr: stderrColor } = supports_color_default;
|
|
3970
|
+
var GENERATOR = Symbol("GENERATOR");
|
|
3971
|
+
var STYLER = Symbol("STYLER");
|
|
3972
|
+
var IS_EMPTY = Symbol("IS_EMPTY");
|
|
3973
|
+
var levelMapping = [
|
|
3974
|
+
"ansi",
|
|
3975
|
+
"ansi",
|
|
3976
|
+
"ansi256",
|
|
3977
|
+
"ansi16m"
|
|
3978
|
+
];
|
|
3979
|
+
var styles2 = Object.create(null);
|
|
3980
|
+
var applyOptions = (object, options2 = {}) => {
|
|
3981
|
+
if (options2.level && !(Number.isInteger(options2.level) && options2.level >= 0 && options2.level <= 3)) {
|
|
3982
|
+
throw new Error("The `level` option should be an integer from 0 to 3");
|
|
3983
|
+
}
|
|
3984
|
+
const colorLevel = stdoutColor ? stdoutColor.level : 0;
|
|
3985
|
+
object.level = options2.level === undefined ? colorLevel : options2.level;
|
|
3986
|
+
};
|
|
3987
|
+
var chalkFactory = (options2) => {
|
|
3988
|
+
const chalk = (...strings) => strings.join(" ");
|
|
3989
|
+
applyOptions(chalk, options2);
|
|
3990
|
+
Object.setPrototypeOf(chalk, createChalk.prototype);
|
|
3991
|
+
return chalk;
|
|
3992
|
+
};
|
|
3993
|
+
function createChalk(options2) {
|
|
3994
|
+
return chalkFactory(options2);
|
|
3721
3995
|
}
|
|
3722
|
-
|
|
3723
|
-
|
|
3724
|
-
|
|
3725
|
-
|
|
3726
|
-
|
|
3727
|
-
|
|
3728
|
-
|
|
3729
|
-
|
|
3730
|
-
|
|
3996
|
+
Object.setPrototypeOf(createChalk.prototype, Function.prototype);
|
|
3997
|
+
for (const [styleName, style] of Object.entries(ansi_styles_default)) {
|
|
3998
|
+
styles2[styleName] = {
|
|
3999
|
+
get() {
|
|
4000
|
+
const builder = createBuilder(this, createStyler(style.open, style.close, this[STYLER]), this[IS_EMPTY]);
|
|
4001
|
+
Object.defineProperty(this, styleName, { value: builder });
|
|
4002
|
+
return builder;
|
|
4003
|
+
}
|
|
4004
|
+
};
|
|
3731
4005
|
}
|
|
3732
|
-
|
|
3733
|
-
|
|
3734
|
-
|
|
3735
|
-
|
|
3736
|
-
|
|
3737
|
-
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
|
|
3741
|
-
|
|
3742
|
-
|
|
3743
|
-
}
|
|
3744
|
-
continue;
|
|
4006
|
+
styles2.visible = {
|
|
4007
|
+
get() {
|
|
4008
|
+
const builder = createBuilder(this, this[STYLER], true);
|
|
4009
|
+
Object.defineProperty(this, "visible", { value: builder });
|
|
4010
|
+
return builder;
|
|
4011
|
+
}
|
|
4012
|
+
};
|
|
4013
|
+
var getModelAnsi = (model, level, type, ...arguments_) => {
|
|
4014
|
+
if (model === "rgb") {
|
|
4015
|
+
if (level === "ansi16m") {
|
|
4016
|
+
return ansi_styles_default[type].ansi16m(...arguments_);
|
|
3745
4017
|
}
|
|
3746
|
-
if (
|
|
3747
|
-
|
|
3748
|
-
continue;
|
|
4018
|
+
if (level === "ansi256") {
|
|
4019
|
+
return ansi_styles_default[type].ansi256(ansi_styles_default.rgbToAnsi256(...arguments_));
|
|
3749
4020
|
}
|
|
3750
|
-
|
|
3751
|
-
|
|
3752
|
-
|
|
3753
|
-
|
|
4021
|
+
return ansi_styles_default[type].ansi(ansi_styles_default.rgbToAnsi(...arguments_));
|
|
4022
|
+
}
|
|
4023
|
+
if (model === "hex") {
|
|
4024
|
+
return getModelAnsi("rgb", level, type, ...ansi_styles_default.hexToRgb(...arguments_));
|
|
4025
|
+
}
|
|
4026
|
+
return ansi_styles_default[type][model](...arguments_);
|
|
4027
|
+
};
|
|
4028
|
+
var usedModels = ["rgb", "hex", "ansi256"];
|
|
4029
|
+
for (const model of usedModels) {
|
|
4030
|
+
styles2[model] = {
|
|
4031
|
+
get() {
|
|
4032
|
+
const { level } = this;
|
|
4033
|
+
return function(...arguments_) {
|
|
4034
|
+
const styler = createStyler(getModelAnsi(model, levelMapping[level], "color", ...arguments_), ansi_styles_default.color.close, this[STYLER]);
|
|
4035
|
+
return createBuilder(this, styler, this[IS_EMPTY]);
|
|
4036
|
+
};
|
|
3754
4037
|
}
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
|
|
4038
|
+
};
|
|
4039
|
+
const bgModel = "bg" + model[0].toUpperCase() + model.slice(1);
|
|
4040
|
+
styles2[bgModel] = {
|
|
4041
|
+
get() {
|
|
4042
|
+
const { level } = this;
|
|
4043
|
+
return function(...arguments_) {
|
|
4044
|
+
const styler = createStyler(getModelAnsi(model, levelMapping[level], "bgColor", ...arguments_), ansi_styles_default.bgColor.close, this[STYLER]);
|
|
4045
|
+
return createBuilder(this, styler, this[IS_EMPTY]);
|
|
4046
|
+
};
|
|
3762
4047
|
}
|
|
3763
|
-
}
|
|
3764
|
-
return { applied, skipped, conflicts };
|
|
4048
|
+
};
|
|
3765
4049
|
}
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
4050
|
+
var proto = Object.defineProperties(() => {}, {
|
|
4051
|
+
...styles2,
|
|
4052
|
+
level: {
|
|
4053
|
+
enumerable: true,
|
|
4054
|
+
get() {
|
|
4055
|
+
return this[GENERATOR].level;
|
|
4056
|
+
},
|
|
4057
|
+
set(level) {
|
|
4058
|
+
this[GENERATOR].level = level;
|
|
4059
|
+
}
|
|
4060
|
+
}
|
|
4061
|
+
});
|
|
4062
|
+
var createStyler = (open, close, parent) => {
|
|
4063
|
+
let openAll;
|
|
4064
|
+
let closeAll;
|
|
4065
|
+
if (parent === undefined) {
|
|
4066
|
+
openAll = open;
|
|
4067
|
+
closeAll = close;
|
|
4068
|
+
} else {
|
|
4069
|
+
openAll = parent.openAll + open;
|
|
4070
|
+
closeAll = close + parent.closeAll;
|
|
4071
|
+
}
|
|
4072
|
+
return {
|
|
4073
|
+
open,
|
|
4074
|
+
close,
|
|
4075
|
+
openAll,
|
|
4076
|
+
closeAll,
|
|
4077
|
+
parent
|
|
4078
|
+
};
|
|
4079
|
+
};
|
|
4080
|
+
var createBuilder = (self, _styler, _isEmpty) => {
|
|
4081
|
+
const builder = (...arguments_) => applyStyle(builder, arguments_.length === 1 ? "" + arguments_[0] : arguments_.join(" "));
|
|
4082
|
+
Object.setPrototypeOf(builder, proto);
|
|
4083
|
+
builder[GENERATOR] = self;
|
|
4084
|
+
builder[STYLER] = _styler;
|
|
4085
|
+
builder[IS_EMPTY] = _isEmpty;
|
|
4086
|
+
return builder;
|
|
4087
|
+
};
|
|
4088
|
+
var applyStyle = (self, string) => {
|
|
4089
|
+
if (self.level <= 0 || !string) {
|
|
4090
|
+
return self[IS_EMPTY] ? "" : string;
|
|
4091
|
+
}
|
|
4092
|
+
let styler = self[STYLER];
|
|
4093
|
+
if (styler === undefined) {
|
|
4094
|
+
return string;
|
|
4095
|
+
}
|
|
4096
|
+
const { openAll, closeAll } = styler;
|
|
4097
|
+
if (string.includes("\x1B")) {
|
|
4098
|
+
while (styler !== undefined) {
|
|
4099
|
+
string = stringReplaceAll(string, styler.close, styler.open);
|
|
4100
|
+
styler = styler.parent;
|
|
4101
|
+
}
|
|
4102
|
+
}
|
|
4103
|
+
const lfIndex = string.indexOf(`
|
|
4104
|
+
`);
|
|
4105
|
+
if (lfIndex !== -1) {
|
|
4106
|
+
string = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex);
|
|
4107
|
+
}
|
|
4108
|
+
return openAll + string + closeAll;
|
|
4109
|
+
};
|
|
4110
|
+
Object.defineProperties(createChalk.prototype, styles2);
|
|
4111
|
+
var chalk = createChalk();
|
|
4112
|
+
var chalkStderr = createChalk({ level: stderrColor ? stderrColor.level : 0 });
|
|
4113
|
+
var source_default = chalk;
|
|
4114
|
+
|
|
4115
|
+
// node_modules/@clack/core/dist/index.mjs
|
|
4116
|
+
var import_sisteransi = __toESM(require_src(), 1);
|
|
4117
|
+
import { stdin as $, stdout as k } from "node:process";
|
|
4118
|
+
import * as f from "node:readline";
|
|
4119
|
+
import _ from "node:readline";
|
|
4120
|
+
import { WriteStream as U } from "node:tty";
|
|
4121
|
+
function q({ onlyFirst: e = false } = {}) {
|
|
4122
|
+
const F = ["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?(?:\\u0007|\\u001B\\u005C|\\u009C))", "(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))"].join("|");
|
|
4123
|
+
return new RegExp(F, e ? undefined : "g");
|
|
4124
|
+
}
|
|
4125
|
+
var J = q();
|
|
4126
|
+
function S(e) {
|
|
4127
|
+
if (typeof e != "string")
|
|
4128
|
+
throw new TypeError(`Expected a \`string\`, got \`${typeof e}\``);
|
|
4129
|
+
return e.replace(J, "");
|
|
4130
|
+
}
|
|
4131
|
+
function T(e) {
|
|
4132
|
+
return e && e.__esModule && Object.prototype.hasOwnProperty.call(e, "default") ? e.default : e;
|
|
4133
|
+
}
|
|
4134
|
+
var j = { exports: {} };
|
|
4135
|
+
(function(e) {
|
|
4136
|
+
var u = {};
|
|
4137
|
+
e.exports = u, u.eastAsianWidth = function(t) {
|
|
4138
|
+
var s = t.charCodeAt(0), C = t.length == 2 ? t.charCodeAt(1) : 0, D = s;
|
|
4139
|
+
return 55296 <= s && s <= 56319 && 56320 <= C && C <= 57343 && (s &= 1023, C &= 1023, D = s << 10 | C, D += 65536), D == 12288 || 65281 <= D && D <= 65376 || 65504 <= D && D <= 65510 ? "F" : D == 8361 || 65377 <= D && D <= 65470 || 65474 <= D && D <= 65479 || 65482 <= D && D <= 65487 || 65490 <= D && D <= 65495 || 65498 <= D && D <= 65500 || 65512 <= D && D <= 65518 ? "H" : 4352 <= D && D <= 4447 || 4515 <= D && D <= 4519 || 4602 <= D && D <= 4607 || 9001 <= D && D <= 9002 || 11904 <= D && D <= 11929 || 11931 <= D && D <= 12019 || 12032 <= D && D <= 12245 || 12272 <= D && D <= 12283 || 12289 <= D && D <= 12350 || 12353 <= D && D <= 12438 || 12441 <= D && D <= 12543 || 12549 <= D && D <= 12589 || 12593 <= D && D <= 12686 || 12688 <= D && D <= 12730 || 12736 <= D && D <= 12771 || 12784 <= D && D <= 12830 || 12832 <= D && D <= 12871 || 12880 <= D && D <= 13054 || 13056 <= D && D <= 19903 || 19968 <= D && D <= 42124 || 42128 <= D && D <= 42182 || 43360 <= D && D <= 43388 || 44032 <= D && D <= 55203 || 55216 <= D && D <= 55238 || 55243 <= D && D <= 55291 || 63744 <= D && D <= 64255 || 65040 <= D && D <= 65049 || 65072 <= D && D <= 65106 || 65108 <= D && D <= 65126 || 65128 <= D && D <= 65131 || 110592 <= D && D <= 110593 || 127488 <= D && D <= 127490 || 127504 <= D && D <= 127546 || 127552 <= D && D <= 127560 || 127568 <= D && D <= 127569 || 131072 <= D && D <= 194367 || 177984 <= D && D <= 196605 || 196608 <= D && D <= 262141 ? "W" : 32 <= D && D <= 126 || 162 <= D && D <= 163 || 165 <= D && D <= 166 || D == 172 || D == 175 || 10214 <= D && D <= 10221 || 10629 <= D && D <= 10630 ? "Na" : D == 161 || D == 164 || 167 <= D && D <= 168 || D == 170 || 173 <= D && D <= 174 || 176 <= D && D <= 180 || 182 <= D && D <= 186 || 188 <= D && D <= 191 || D == 198 || D == 208 || 215 <= D && D <= 216 || 222 <= D && D <= 225 || D == 230 || 232 <= D && D <= 234 || 236 <= D && D <= 237 || D == 240 || 242 <= D && D <= 243 || 247 <= D && D <= 250 || D == 252 || D == 254 || D == 257 || D == 273 || D == 275 || D == 283 || 294 <= D && D <= 295 || D == 299 || 305 <= D && D <= 307 || D == 312 || 319 <= D && D <= 322 || D == 324 || 328 <= D && D <= 331 || D == 333 || 338 <= D && D <= 339 || 358 <= D && D <= 359 || D == 363 || D == 462 || D == 464 || D == 466 || D == 468 || D == 470 || D == 472 || D == 474 || D == 476 || D == 593 || D == 609 || D == 708 || D == 711 || 713 <= D && D <= 715 || D == 717 || D == 720 || 728 <= D && D <= 731 || D == 733 || D == 735 || 768 <= D && D <= 879 || 913 <= D && D <= 929 || 931 <= D && D <= 937 || 945 <= D && D <= 961 || 963 <= D && D <= 969 || D == 1025 || 1040 <= D && D <= 1103 || D == 1105 || D == 8208 || 8211 <= D && D <= 8214 || 8216 <= D && D <= 8217 || 8220 <= D && D <= 8221 || 8224 <= D && D <= 8226 || 8228 <= D && D <= 8231 || D == 8240 || 8242 <= D && D <= 8243 || D == 8245 || D == 8251 || D == 8254 || D == 8308 || D == 8319 || 8321 <= D && D <= 8324 || D == 8364 || D == 8451 || D == 8453 || D == 8457 || D == 8467 || D == 8470 || 8481 <= D && D <= 8482 || D == 8486 || D == 8491 || 8531 <= D && D <= 8532 || 8539 <= D && D <= 8542 || 8544 <= D && D <= 8555 || 8560 <= D && D <= 8569 || D == 8585 || 8592 <= D && D <= 8601 || 8632 <= D && D <= 8633 || D == 8658 || D == 8660 || D == 8679 || D == 8704 || 8706 <= D && D <= 8707 || 8711 <= D && D <= 8712 || D == 8715 || D == 8719 || D == 8721 || D == 8725 || D == 8730 || 8733 <= D && D <= 8736 || D == 8739 || D == 8741 || 8743 <= D && D <= 8748 || D == 8750 || 8756 <= D && D <= 8759 || 8764 <= D && D <= 8765 || D == 8776 || D == 8780 || D == 8786 || 8800 <= D && D <= 8801 || 8804 <= D && D <= 8807 || 8810 <= D && D <= 8811 || 8814 <= D && D <= 8815 || 8834 <= D && D <= 8835 || 8838 <= D && D <= 8839 || D == 8853 || D == 8857 || D == 8869 || D == 8895 || D == 8978 || 9312 <= D && D <= 9449 || 9451 <= D && D <= 9547 || 9552 <= D && D <= 9587 || 9600 <= D && D <= 9615 || 9618 <= D && D <= 9621 || 9632 <= D && D <= 9633 || 9635 <= D && D <= 9641 || 9650 <= D && D <= 9651 || 9654 <= D && D <= 9655 || 9660 <= D && D <= 9661 || 9664 <= D && D <= 9665 || 9670 <= D && D <= 9672 || D == 9675 || 9678 <= D && D <= 9681 || 9698 <= D && D <= 9701 || D == 9711 || 9733 <= D && D <= 9734 || D == 9737 || 9742 <= D && D <= 9743 || 9748 <= D && D <= 9749 || D == 9756 || D == 9758 || D == 9792 || D == 9794 || 9824 <= D && D <= 9825 || 9827 <= D && D <= 9829 || 9831 <= D && D <= 9834 || 9836 <= D && D <= 9837 || D == 9839 || 9886 <= D && D <= 9887 || 9918 <= D && D <= 9919 || 9924 <= D && D <= 9933 || 9935 <= D && D <= 9953 || D == 9955 || 9960 <= D && D <= 9983 || D == 10045 || D == 10071 || 10102 <= D && D <= 10111 || 11093 <= D && D <= 11097 || 12872 <= D && D <= 12879 || 57344 <= D && D <= 63743 || 65024 <= D && D <= 65039 || D == 65533 || 127232 <= D && D <= 127242 || 127248 <= D && D <= 127277 || 127280 <= D && D <= 127337 || 127344 <= D && D <= 127386 || 917760 <= D && D <= 917999 || 983040 <= D && D <= 1048573 || 1048576 <= D && D <= 1114109 ? "A" : "N";
|
|
4140
|
+
}, u.characterLength = function(t) {
|
|
4141
|
+
var s = this.eastAsianWidth(t);
|
|
4142
|
+
return s == "F" || s == "W" || s == "A" ? 2 : 1;
|
|
4143
|
+
};
|
|
4144
|
+
function F(t) {
|
|
4145
|
+
return t.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]|[^\uD800-\uDFFF]/g) || [];
|
|
4146
|
+
}
|
|
4147
|
+
u.length = function(t) {
|
|
4148
|
+
for (var s = F(t), C = 0, D = 0;D < s.length; D++)
|
|
4149
|
+
C = C + this.characterLength(s[D]);
|
|
4150
|
+
return C;
|
|
4151
|
+
}, u.slice = function(t, s, C) {
|
|
4152
|
+
textLen = u.length(t), s = s || 0, C = C || 1, s < 0 && (s = textLen + s), C < 0 && (C = textLen + C);
|
|
4153
|
+
for (var D = "", i = 0, n = F(t), E = 0;E < n.length; E++) {
|
|
4154
|
+
var h = n[E], o = u.length(h);
|
|
4155
|
+
if (i >= s - (o == 2 ? 1 : 0))
|
|
4156
|
+
if (i + o <= C)
|
|
4157
|
+
D += h;
|
|
4158
|
+
else
|
|
4159
|
+
break;
|
|
4160
|
+
i += o;
|
|
4161
|
+
}
|
|
4162
|
+
return D;
|
|
4163
|
+
};
|
|
4164
|
+
})(j);
|
|
4165
|
+
var Q = j.exports;
|
|
4166
|
+
var X = T(Q);
|
|
4167
|
+
var DD = function() {
|
|
4168
|
+
return /\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67)\uDB40\uDC7F|(?:\uD83E\uDDD1\uD83C\uDFFF\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFC-\uDFFF])|\uD83D\uDC68(?:\uD83C\uDFFB(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|[\u2695\u2696\u2708]\uFE0F|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))?|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])\uFE0F|\u200D(?:(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D[\uDC66\uDC67])|\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC)?|(?:\uD83D\uDC69(?:\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69]))|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC69(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83E\uDDD1(?:\u200D(?:\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDE36\u200D\uD83C\uDF2B|\uD83C\uDFF3\uFE0F\u200D\u26A7|\uD83D\uDC3B\u200D\u2744|(?:(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\uD83C\uDFF4\u200D\u2620|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])\u200D[\u2640\u2642]|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u2600-\u2604\u260E\u2611\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26B0\u26B1\u26C8\u26CF\u26D1\u26D3\u26E9\u26F0\u26F1\u26F4\u26F7\u26F8\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u3030\u303D\u3297\u3299]|\uD83C[\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]|\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|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDE35\u200D\uD83D\uDCAB|\uD83D\uDE2E\u200D\uD83D\uDCA8|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83E\uDDD1(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83D\uDC69(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF6\uD83C\uDDE6|\uD83C\uDDF4\uD83C\uDDF2|\uD83D\uDC08\u200D\u2B1B|\u2764\uFE0F\u200D(?:\uD83D\uDD25|\uD83E\uDE79)|\uD83D\uDC41\uFE0F|\uD83C\uDFF3\uFE0F|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|[#\*0-9]\uFE0F\u20E3|\u2764\uFE0F|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|\uD83C\uDFF4|(?:[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\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]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270C\u270D]|\uD83D[\uDD74\uDD90])(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC08\uDC15\uDC3B\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE2E\uDE35\uDE36\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5]|\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD]|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF]|[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\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-\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0D\uDD0E\uDD10-\uDD17\uDD1D\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78\uDD7A-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCB\uDDD0\uDDE0-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6]|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26A7\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5-\uDED7\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDD77\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g;
|
|
4169
|
+
};
|
|
4170
|
+
var uD = T(DD);
|
|
4171
|
+
function A(e, u = {}) {
|
|
4172
|
+
if (typeof e != "string" || e.length === 0 || (u = { ambiguousIsNarrow: true, ...u }, e = S(e), e.length === 0))
|
|
4173
|
+
return 0;
|
|
4174
|
+
e = e.replace(uD(), " ");
|
|
4175
|
+
const F = u.ambiguousIsNarrow ? 1 : 2;
|
|
4176
|
+
let t = 0;
|
|
4177
|
+
for (const s of e) {
|
|
4178
|
+
const C = s.codePointAt(0);
|
|
4179
|
+
if (C <= 31 || C >= 127 && C <= 159 || C >= 768 && C <= 879)
|
|
4180
|
+
continue;
|
|
4181
|
+
switch (X.eastAsianWidth(s)) {
|
|
4182
|
+
case "F":
|
|
4183
|
+
case "W":
|
|
4184
|
+
t += 2;
|
|
4185
|
+
break;
|
|
4186
|
+
case "A":
|
|
4187
|
+
t += F;
|
|
4188
|
+
break;
|
|
4189
|
+
default:
|
|
4190
|
+
t += 1;
|
|
4191
|
+
}
|
|
4192
|
+
}
|
|
4193
|
+
return t;
|
|
4194
|
+
}
|
|
4195
|
+
var d = 10;
|
|
4196
|
+
var M = (e = 0) => (u) => `\x1B[${u + e}m`;
|
|
4197
|
+
var P = (e = 0) => (u) => `\x1B[${38 + e};5;${u}m`;
|
|
4198
|
+
var W = (e = 0) => (u, F, t) => `\x1B[${38 + e};2;${u};${F};${t}m`;
|
|
4199
|
+
var r = { modifier: { reset: [0, 0], bold: [1, 22], dim: [2, 22], italic: [3, 23], underline: [4, 24], overline: [53, 55], inverse: [7, 27], hidden: [8, 28], strikethrough: [9, 29] }, color: { black: [30, 39], red: [31, 39], green: [32, 39], yellow: [33, 39], blue: [34, 39], magenta: [35, 39], cyan: [36, 39], white: [37, 39], blackBright: [90, 39], gray: [90, 39], grey: [90, 39], redBright: [91, 39], greenBright: [92, 39], yellowBright: [93, 39], blueBright: [94, 39], magentaBright: [95, 39], cyanBright: [96, 39], whiteBright: [97, 39] }, bgColor: { bgBlack: [40, 49], bgRed: [41, 49], bgGreen: [42, 49], bgYellow: [43, 49], bgBlue: [44, 49], bgMagenta: [45, 49], bgCyan: [46, 49], bgWhite: [47, 49], bgBlackBright: [100, 49], bgGray: [100, 49], bgGrey: [100, 49], bgRedBright: [101, 49], bgGreenBright: [102, 49], bgYellowBright: [103, 49], bgBlueBright: [104, 49], bgMagentaBright: [105, 49], bgCyanBright: [106, 49], bgWhiteBright: [107, 49] } };
|
|
4200
|
+
Object.keys(r.modifier);
|
|
4201
|
+
var FD = Object.keys(r.color);
|
|
4202
|
+
var eD = Object.keys(r.bgColor);
|
|
4203
|
+
[...FD, ...eD];
|
|
4204
|
+
function tD() {
|
|
4205
|
+
const e = new Map;
|
|
4206
|
+
for (const [u, F] of Object.entries(r)) {
|
|
4207
|
+
for (const [t, s] of Object.entries(F))
|
|
4208
|
+
r[t] = { open: `\x1B[${s[0]}m`, close: `\x1B[${s[1]}m` }, F[t] = r[t], e.set(s[0], s[1]);
|
|
4209
|
+
Object.defineProperty(r, u, { value: F, enumerable: false });
|
|
4210
|
+
}
|
|
4211
|
+
return Object.defineProperty(r, "codes", { value: e, enumerable: false }), r.color.close = "\x1B[39m", r.bgColor.close = "\x1B[49m", r.color.ansi = M(), r.color.ansi256 = P(), r.color.ansi16m = W(), r.bgColor.ansi = M(d), r.bgColor.ansi256 = P(d), r.bgColor.ansi16m = W(d), Object.defineProperties(r, { rgbToAnsi256: { value: (u, F, t) => u === F && F === t ? u < 8 ? 16 : u > 248 ? 231 : Math.round((u - 8) / 247 * 24) + 232 : 16 + 36 * Math.round(u / 255 * 5) + 6 * Math.round(F / 255 * 5) + Math.round(t / 255 * 5), enumerable: false }, hexToRgb: { value: (u) => {
|
|
4212
|
+
const F = /[a-f\d]{6}|[a-f\d]{3}/i.exec(u.toString(16));
|
|
4213
|
+
if (!F)
|
|
4214
|
+
return [0, 0, 0];
|
|
4215
|
+
let [t] = F;
|
|
4216
|
+
t.length === 3 && (t = [...t].map((C) => C + C).join(""));
|
|
4217
|
+
const s = Number.parseInt(t, 16);
|
|
4218
|
+
return [s >> 16 & 255, s >> 8 & 255, s & 255];
|
|
4219
|
+
}, enumerable: false }, hexToAnsi256: { value: (u) => r.rgbToAnsi256(...r.hexToRgb(u)), enumerable: false }, ansi256ToAnsi: { value: (u) => {
|
|
4220
|
+
if (u < 8)
|
|
4221
|
+
return 30 + u;
|
|
4222
|
+
if (u < 16)
|
|
4223
|
+
return 90 + (u - 8);
|
|
4224
|
+
let F, t, s;
|
|
4225
|
+
if (u >= 232)
|
|
4226
|
+
F = ((u - 232) * 10 + 8) / 255, t = F, s = F;
|
|
4227
|
+
else {
|
|
4228
|
+
u -= 16;
|
|
4229
|
+
const i = u % 36;
|
|
4230
|
+
F = Math.floor(u / 36) / 5, t = Math.floor(i / 6) / 5, s = i % 6 / 5;
|
|
4231
|
+
}
|
|
4232
|
+
const C = Math.max(F, t, s) * 2;
|
|
4233
|
+
if (C === 0)
|
|
4234
|
+
return 30;
|
|
4235
|
+
let D = 30 + (Math.round(s) << 2 | Math.round(t) << 1 | Math.round(F));
|
|
4236
|
+
return C === 2 && (D += 60), D;
|
|
4237
|
+
}, enumerable: false }, rgbToAnsi: { value: (u, F, t) => r.ansi256ToAnsi(r.rgbToAnsi256(u, F, t)), enumerable: false }, hexToAnsi: { value: (u) => r.ansi256ToAnsi(r.hexToAnsi256(u)), enumerable: false } }), r;
|
|
4238
|
+
}
|
|
4239
|
+
var sD = tD();
|
|
4240
|
+
var g = new Set(["\x1B", ""]);
|
|
4241
|
+
var CD = 39;
|
|
4242
|
+
var b = "\x07";
|
|
4243
|
+
var O = "[";
|
|
4244
|
+
var iD = "]";
|
|
4245
|
+
var I = "m";
|
|
4246
|
+
var w = `${iD}8;;`;
|
|
4247
|
+
var N = (e) => `${g.values().next().value}${O}${e}${I}`;
|
|
4248
|
+
var L = (e) => `${g.values().next().value}${w}${e}${b}`;
|
|
4249
|
+
var rD = (e) => e.split(" ").map((u) => A(u));
|
|
4250
|
+
var y = (e, u, F) => {
|
|
4251
|
+
const t = [...u];
|
|
4252
|
+
let s = false, C = false, D = A(S(e[e.length - 1]));
|
|
4253
|
+
for (const [i, n] of t.entries()) {
|
|
4254
|
+
const E = A(n);
|
|
4255
|
+
if (D + E <= F ? e[e.length - 1] += n : (e.push(n), D = 0), g.has(n) && (s = true, C = t.slice(i + 1).join("").startsWith(w)), s) {
|
|
4256
|
+
C ? n === b && (s = false, C = false) : n === I && (s = false);
|
|
4257
|
+
continue;
|
|
4258
|
+
}
|
|
4259
|
+
D += E, D === F && i < t.length - 1 && (e.push(""), D = 0);
|
|
4260
|
+
}
|
|
4261
|
+
!D && e[e.length - 1].length > 0 && e.length > 1 && (e[e.length - 2] += e.pop());
|
|
4262
|
+
};
|
|
4263
|
+
var ED = (e) => {
|
|
4264
|
+
const u = e.split(" ");
|
|
4265
|
+
let F = u.length;
|
|
4266
|
+
for (;F > 0 && !(A(u[F - 1]) > 0); )
|
|
4267
|
+
F--;
|
|
4268
|
+
return F === u.length ? e : u.slice(0, F).join(" ") + u.slice(F).join("");
|
|
4269
|
+
};
|
|
4270
|
+
var oD = (e, u, F = {}) => {
|
|
4271
|
+
if (F.trim !== false && e.trim() === "")
|
|
4272
|
+
return "";
|
|
4273
|
+
let t = "", s, C;
|
|
4274
|
+
const D = rD(e);
|
|
4275
|
+
let i = [""];
|
|
4276
|
+
for (const [E, h] of e.split(" ").entries()) {
|
|
4277
|
+
F.trim !== false && (i[i.length - 1] = i[i.length - 1].trimStart());
|
|
4278
|
+
let o = A(i[i.length - 1]);
|
|
4279
|
+
if (E !== 0 && (o >= u && (F.wordWrap === false || F.trim === false) && (i.push(""), o = 0), (o > 0 || F.trim === false) && (i[i.length - 1] += " ", o++)), F.hard && D[E] > u) {
|
|
4280
|
+
const B = u - o, p = 1 + Math.floor((D[E] - B - 1) / u);
|
|
4281
|
+
Math.floor((D[E] - 1) / u) < p && i.push(""), y(i, h, u);
|
|
4282
|
+
continue;
|
|
4283
|
+
}
|
|
4284
|
+
if (o + D[E] > u && o > 0 && D[E] > 0) {
|
|
4285
|
+
if (F.wordWrap === false && o < u) {
|
|
4286
|
+
y(i, h, u);
|
|
4287
|
+
continue;
|
|
4288
|
+
}
|
|
4289
|
+
i.push("");
|
|
4290
|
+
}
|
|
4291
|
+
if (o + D[E] > u && F.wordWrap === false) {
|
|
4292
|
+
y(i, h, u);
|
|
4293
|
+
continue;
|
|
4294
|
+
}
|
|
4295
|
+
i[i.length - 1] += h;
|
|
4296
|
+
}
|
|
4297
|
+
F.trim !== false && (i = i.map((E) => ED(E)));
|
|
4298
|
+
const n = [...i.join(`
|
|
4299
|
+
`)];
|
|
4300
|
+
for (const [E, h] of n.entries()) {
|
|
4301
|
+
if (t += h, g.has(h)) {
|
|
4302
|
+
const { groups: B } = new RegExp(`(?:\\${O}(?<code>\\d+)m|\\${w}(?<uri>.*)${b})`).exec(n.slice(E).join("")) || { groups: {} };
|
|
4303
|
+
if (B.code !== undefined) {
|
|
4304
|
+
const p = Number.parseFloat(B.code);
|
|
4305
|
+
s = p === CD ? undefined : p;
|
|
4306
|
+
} else
|
|
4307
|
+
B.uri !== undefined && (C = B.uri.length === 0 ? undefined : B.uri);
|
|
4308
|
+
}
|
|
4309
|
+
const o = sD.codes.get(Number(s));
|
|
4310
|
+
n[E + 1] === `
|
|
4311
|
+
` ? (C && (t += L("")), s && o && (t += N(o))) : h === `
|
|
4312
|
+
` && (s && o && (t += N(s)), C && (t += L(C)));
|
|
4313
|
+
}
|
|
4314
|
+
return t;
|
|
4315
|
+
};
|
|
4316
|
+
function R(e, u, F) {
|
|
4317
|
+
return String(e).normalize().replace(/\r\n/g, `
|
|
4318
|
+
`).split(`
|
|
4319
|
+
`).map((t) => oD(t, u, F)).join(`
|
|
4320
|
+
`);
|
|
4321
|
+
}
|
|
4322
|
+
var nD = Object.defineProperty;
|
|
4323
|
+
var aD = (e, u, F) => (u in e) ? nD(e, u, { enumerable: true, configurable: true, writable: true, value: F }) : e[u] = F;
|
|
4324
|
+
var a = (e, u, F) => (aD(e, typeof u != "symbol" ? u + "" : u, F), F);
|
|
4325
|
+
function hD(e, u) {
|
|
4326
|
+
if (e === u)
|
|
4327
|
+
return;
|
|
4328
|
+
const F = e.split(`
|
|
4329
|
+
`), t = u.split(`
|
|
4330
|
+
`), s = [];
|
|
4331
|
+
for (let C = 0;C < Math.max(F.length, t.length); C++)
|
|
4332
|
+
F[C] !== t[C] && s.push(C);
|
|
4333
|
+
return s;
|
|
4334
|
+
}
|
|
4335
|
+
var V = Symbol("clack:cancel");
|
|
4336
|
+
function lD(e) {
|
|
4337
|
+
return e === V;
|
|
4338
|
+
}
|
|
4339
|
+
function v(e, u) {
|
|
4340
|
+
e.isTTY && e.setRawMode(u);
|
|
4341
|
+
}
|
|
4342
|
+
var z = new Map([["k", "up"], ["j", "down"], ["h", "left"], ["l", "right"]]);
|
|
4343
|
+
var xD = new Set(["up", "down", "left", "right", "space", "enter"]);
|
|
4344
|
+
|
|
4345
|
+
class x {
|
|
4346
|
+
constructor({ render: u, input: F = $, output: t = k, ...s }, C = true) {
|
|
4347
|
+
a(this, "input"), a(this, "output"), a(this, "rl"), a(this, "opts"), a(this, "_track", false), a(this, "_render"), a(this, "_cursor", 0), a(this, "state", "initial"), a(this, "value"), a(this, "error", ""), a(this, "subscribers", new Map), a(this, "_prevFrame", ""), this.opts = s, this.onKeypress = this.onKeypress.bind(this), this.close = this.close.bind(this), this.render = this.render.bind(this), this._render = u.bind(this), this._track = C, this.input = F, this.output = t;
|
|
4348
|
+
}
|
|
4349
|
+
prompt() {
|
|
4350
|
+
const u = new U(0);
|
|
4351
|
+
return u._write = (F, t, s) => {
|
|
4352
|
+
this._track && (this.value = this.rl.line.replace(/\t/g, ""), this._cursor = this.rl.cursor, this.emit("value", this.value)), s();
|
|
4353
|
+
}, this.input.pipe(u), this.rl = _.createInterface({ input: this.input, output: u, tabSize: 2, prompt: "", escapeCodeTimeout: 50 }), _.emitKeypressEvents(this.input, this.rl), this.rl.prompt(), this.opts.initialValue !== undefined && this._track && this.rl.write(this.opts.initialValue), this.input.on("keypress", this.onKeypress), v(this.input, true), this.output.on("resize", this.render), this.render(), new Promise((F, t) => {
|
|
4354
|
+
this.once("submit", () => {
|
|
4355
|
+
this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), v(this.input, false), F(this.value);
|
|
4356
|
+
}), this.once("cancel", () => {
|
|
4357
|
+
this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), v(this.input, false), F(V);
|
|
4358
|
+
});
|
|
4359
|
+
});
|
|
4360
|
+
}
|
|
4361
|
+
on(u, F) {
|
|
4362
|
+
const t = this.subscribers.get(u) ?? [];
|
|
4363
|
+
t.push({ cb: F }), this.subscribers.set(u, t);
|
|
4364
|
+
}
|
|
4365
|
+
once(u, F) {
|
|
4366
|
+
const t = this.subscribers.get(u) ?? [];
|
|
4367
|
+
t.push({ cb: F, once: true }), this.subscribers.set(u, t);
|
|
4368
|
+
}
|
|
4369
|
+
emit(u, ...F) {
|
|
4370
|
+
const t = this.subscribers.get(u) ?? [], s = [];
|
|
4371
|
+
for (const C of t)
|
|
4372
|
+
C.cb(...F), C.once && s.push(() => t.splice(t.indexOf(C), 1));
|
|
4373
|
+
for (const C of s)
|
|
4374
|
+
C();
|
|
4375
|
+
}
|
|
4376
|
+
unsubscribe() {
|
|
4377
|
+
this.subscribers.clear();
|
|
4378
|
+
}
|
|
4379
|
+
onKeypress(u, F) {
|
|
4380
|
+
if (this.state === "error" && (this.state = "active"), F?.name && !this._track && z.has(F.name) && this.emit("cursor", z.get(F.name)), F?.name && xD.has(F.name) && this.emit("cursor", F.name), u && (u.toLowerCase() === "y" || u.toLowerCase() === "n") && this.emit("confirm", u.toLowerCase() === "y"), u === "\t" && this.opts.placeholder && (this.value || (this.rl.write(this.opts.placeholder), this.emit("value", this.opts.placeholder))), u && this.emit("key", u.toLowerCase()), F?.name === "return") {
|
|
4381
|
+
if (this.opts.validate) {
|
|
4382
|
+
const t = this.opts.validate(this.value);
|
|
4383
|
+
t && (this.error = t, this.state = "error", this.rl.write(this.value));
|
|
4384
|
+
}
|
|
4385
|
+
this.state !== "error" && (this.state = "submit");
|
|
4386
|
+
}
|
|
4387
|
+
u === "\x03" && (this.state = "cancel"), (this.state === "submit" || this.state === "cancel") && this.emit("finalize"), this.render(), (this.state === "submit" || this.state === "cancel") && this.close();
|
|
4388
|
+
}
|
|
4389
|
+
close() {
|
|
4390
|
+
this.input.unpipe(), this.input.removeListener("keypress", this.onKeypress), this.output.write(`
|
|
4391
|
+
`), v(this.input, false), this.rl.close(), this.emit(`${this.state}`, this.value), this.unsubscribe();
|
|
4392
|
+
}
|
|
4393
|
+
restoreCursor() {
|
|
4394
|
+
const u = R(this._prevFrame, process.stdout.columns, { hard: true }).split(`
|
|
4395
|
+
`).length - 1;
|
|
4396
|
+
this.output.write(import_sisteransi.cursor.move(-999, u * -1));
|
|
4397
|
+
}
|
|
4398
|
+
render() {
|
|
4399
|
+
const u = R(this._render(this) ?? "", process.stdout.columns, { hard: true });
|
|
4400
|
+
if (u !== this._prevFrame) {
|
|
4401
|
+
if (this.state === "initial")
|
|
4402
|
+
this.output.write(import_sisteransi.cursor.hide);
|
|
4403
|
+
else {
|
|
4404
|
+
const F = hD(this._prevFrame, u);
|
|
4405
|
+
if (this.restoreCursor(), F && F?.length === 1) {
|
|
4406
|
+
const t = F[0];
|
|
4407
|
+
this.output.write(import_sisteransi.cursor.move(0, t)), this.output.write(import_sisteransi.erase.lines(1));
|
|
4408
|
+
const s = u.split(`
|
|
4409
|
+
`);
|
|
4410
|
+
this.output.write(s[t]), this._prevFrame = u, this.output.write(import_sisteransi.cursor.move(0, s.length - t - 1));
|
|
4411
|
+
return;
|
|
4412
|
+
} else if (F && F?.length > 1) {
|
|
4413
|
+
const t = F[0];
|
|
4414
|
+
this.output.write(import_sisteransi.cursor.move(0, t)), this.output.write(import_sisteransi.erase.down());
|
|
4415
|
+
const s = u.split(`
|
|
4416
|
+
`).slice(t);
|
|
4417
|
+
this.output.write(s.join(`
|
|
4418
|
+
`)), this._prevFrame = u;
|
|
4419
|
+
return;
|
|
4420
|
+
}
|
|
4421
|
+
this.output.write(import_sisteransi.erase.down());
|
|
4422
|
+
}
|
|
4423
|
+
this.output.write(u), this.state === "initial" && (this.state = "active"), this._prevFrame = u;
|
|
4424
|
+
}
|
|
4425
|
+
}
|
|
4426
|
+
}
|
|
4427
|
+
|
|
4428
|
+
class BD extends x {
|
|
4429
|
+
get cursor() {
|
|
4430
|
+
return this.value ? 0 : 1;
|
|
4431
|
+
}
|
|
4432
|
+
get _value() {
|
|
4433
|
+
return this.cursor === 0;
|
|
4434
|
+
}
|
|
4435
|
+
constructor(u) {
|
|
4436
|
+
super(u, false), this.value = !!u.initialValue, this.on("value", () => {
|
|
4437
|
+
this.value = this._value;
|
|
4438
|
+
}), this.on("confirm", (F) => {
|
|
4439
|
+
this.output.write(import_sisteransi.cursor.move(0, -1)), this.value = F, this.state = "submit", this.close();
|
|
4440
|
+
}), this.on("cursor", () => {
|
|
4441
|
+
this.value = !this.value;
|
|
4442
|
+
});
|
|
4443
|
+
}
|
|
4444
|
+
}
|
|
4445
|
+
var fD = Object.defineProperty;
|
|
4446
|
+
var gD = (e, u, F) => (u in e) ? fD(e, u, { enumerable: true, configurable: true, writable: true, value: F }) : e[u] = F;
|
|
4447
|
+
var K = (e, u, F) => (gD(e, typeof u != "symbol" ? u + "" : u, F), F);
|
|
4448
|
+
var vD = class extends x {
|
|
4449
|
+
constructor(u) {
|
|
4450
|
+
super(u, false), K(this, "options"), K(this, "cursor", 0), this.options = u.options, this.value = [...u.initialValues ?? []], this.cursor = Math.max(this.options.findIndex(({ value: F }) => F === u.cursorAt), 0), this.on("key", (F) => {
|
|
4451
|
+
F === "a" && this.toggleAll();
|
|
4452
|
+
}), this.on("cursor", (F) => {
|
|
4453
|
+
switch (F) {
|
|
4454
|
+
case "left":
|
|
4455
|
+
case "up":
|
|
4456
|
+
this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
|
|
4457
|
+
break;
|
|
4458
|
+
case "down":
|
|
4459
|
+
case "right":
|
|
4460
|
+
this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
|
|
4461
|
+
break;
|
|
4462
|
+
case "space":
|
|
4463
|
+
this.toggleValue();
|
|
4464
|
+
break;
|
|
4465
|
+
}
|
|
4466
|
+
});
|
|
4467
|
+
}
|
|
4468
|
+
get _value() {
|
|
4469
|
+
return this.options[this.cursor].value;
|
|
4470
|
+
}
|
|
4471
|
+
toggleAll() {
|
|
4472
|
+
const u = this.value.length === this.options.length;
|
|
4473
|
+
this.value = u ? [] : this.options.map((F) => F.value);
|
|
4474
|
+
}
|
|
4475
|
+
toggleValue() {
|
|
4476
|
+
const u = this.value.includes(this._value);
|
|
4477
|
+
this.value = u ? this.value.filter((F) => F !== this._value) : [...this.value, this._value];
|
|
4478
|
+
}
|
|
4479
|
+
};
|
|
4480
|
+
var wD = Object.defineProperty;
|
|
4481
|
+
var yD = (e, u, F) => (u in e) ? wD(e, u, { enumerable: true, configurable: true, writable: true, value: F }) : e[u] = F;
|
|
4482
|
+
var Z = (e, u, F) => (yD(e, typeof u != "symbol" ? u + "" : u, F), F);
|
|
4483
|
+
var $D = class extends x {
|
|
4484
|
+
constructor(u) {
|
|
4485
|
+
super(u, false), Z(this, "options"), Z(this, "cursor", 0), this.options = u.options, this.cursor = this.options.findIndex(({ value: F }) => F === u.initialValue), this.cursor === -1 && (this.cursor = 0), this.changeValue(), this.on("cursor", (F) => {
|
|
4486
|
+
switch (F) {
|
|
4487
|
+
case "left":
|
|
4488
|
+
case "up":
|
|
4489
|
+
this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
|
|
4490
|
+
break;
|
|
4491
|
+
case "down":
|
|
4492
|
+
case "right":
|
|
4493
|
+
this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
|
|
4494
|
+
break;
|
|
4495
|
+
}
|
|
4496
|
+
this.changeValue();
|
|
4497
|
+
});
|
|
4498
|
+
}
|
|
4499
|
+
get _value() {
|
|
4500
|
+
return this.options[this.cursor];
|
|
4501
|
+
}
|
|
4502
|
+
changeValue() {
|
|
4503
|
+
this.value = this._value.value;
|
|
4504
|
+
}
|
|
4505
|
+
};
|
|
4506
|
+
var WD = globalThis.process.platform.startsWith("win");
|
|
4507
|
+
function OD({ input: e = $, output: u = k, overwrite: F = true, hideCursor: t = true } = {}) {
|
|
4508
|
+
const s = f.createInterface({ input: e, output: u, prompt: "", tabSize: 1 });
|
|
4509
|
+
f.emitKeypressEvents(e, s), e.isTTY && e.setRawMode(true);
|
|
4510
|
+
const C = (D, { name: i }) => {
|
|
4511
|
+
if (String(D) === "\x03") {
|
|
4512
|
+
t && u.write(import_sisteransi.cursor.show), process.exit(0);
|
|
4513
|
+
return;
|
|
4514
|
+
}
|
|
4515
|
+
if (!F)
|
|
4516
|
+
return;
|
|
4517
|
+
let n = i === "return" ? 0 : -1, E = i === "return" ? -1 : 0;
|
|
4518
|
+
f.moveCursor(u, n, E, () => {
|
|
4519
|
+
f.clearLine(u, 1, () => {
|
|
4520
|
+
e.once("keypress", C);
|
|
4521
|
+
});
|
|
4522
|
+
});
|
|
4523
|
+
};
|
|
4524
|
+
return t && u.write(import_sisteransi.cursor.hide), e.once("keypress", C), () => {
|
|
4525
|
+
e.off("keypress", C), t && u.write(import_sisteransi.cursor.show), e.isTTY && !WD && e.setRawMode(false), s.terminal = false, s.close();
|
|
4526
|
+
};
|
|
4527
|
+
}
|
|
4528
|
+
|
|
4529
|
+
// node_modules/@clack/prompts/dist/index.mjs
|
|
4530
|
+
var import_picocolors = __toESM(require_picocolors(), 1);
|
|
4531
|
+
var import_sisteransi2 = __toESM(require_src(), 1);
|
|
4532
|
+
import h from "node:process";
|
|
4533
|
+
function q2() {
|
|
4534
|
+
return h.platform !== "win32" ? h.env.TERM !== "linux" : Boolean(h.env.CI) || Boolean(h.env.WT_SESSION) || Boolean(h.env.TERMINUS_SUBLIME) || h.env.ConEmuTask === "{cmd::Cmder}" || h.env.TERM_PROGRAM === "Terminus-Sublime" || h.env.TERM_PROGRAM === "vscode" || h.env.TERM === "xterm-256color" || h.env.TERM === "alacritty" || h.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
|
|
4535
|
+
}
|
|
4536
|
+
var _2 = q2();
|
|
4537
|
+
var o = (r2, n) => _2 ? r2 : n;
|
|
4538
|
+
var H = o("◆", "*");
|
|
4539
|
+
var I2 = o("■", "x");
|
|
4540
|
+
var x2 = o("▲", "x");
|
|
4541
|
+
var S2 = o("◇", "o");
|
|
4542
|
+
var K2 = o("┌", "T");
|
|
4543
|
+
var a2 = o("│", "|");
|
|
4544
|
+
var d2 = o("└", "—");
|
|
4545
|
+
var b2 = o("●", ">");
|
|
4546
|
+
var E = o("○", " ");
|
|
4547
|
+
var C = o("◻", "[•]");
|
|
4548
|
+
var w2 = o("◼", "[+]");
|
|
4549
|
+
var M2 = o("◻", "[ ]");
|
|
4550
|
+
var U2 = o("▪", "•");
|
|
4551
|
+
var B = o("─", "-");
|
|
4552
|
+
var Z2 = o("╮", "+");
|
|
4553
|
+
var z2 = o("├", "+");
|
|
4554
|
+
var X2 = o("╯", "+");
|
|
4555
|
+
var J2 = o("●", "•");
|
|
4556
|
+
var Y = o("◆", "*");
|
|
4557
|
+
var Q2 = o("▲", "!");
|
|
4558
|
+
var ee = o("■", "x");
|
|
4559
|
+
var y2 = (r2) => {
|
|
4560
|
+
switch (r2) {
|
|
4561
|
+
case "initial":
|
|
4562
|
+
case "active":
|
|
4563
|
+
return import_picocolors.default.cyan(H);
|
|
4564
|
+
case "cancel":
|
|
4565
|
+
return import_picocolors.default.red(I2);
|
|
4566
|
+
case "error":
|
|
4567
|
+
return import_picocolors.default.yellow(x2);
|
|
4568
|
+
case "submit":
|
|
4569
|
+
return import_picocolors.default.green(S2);
|
|
4570
|
+
}
|
|
4571
|
+
};
|
|
4572
|
+
var se = (r2) => {
|
|
4573
|
+
const n = r2.active ?? "Yes", i = r2.inactive ?? "No";
|
|
4574
|
+
return new BD({ active: n, inactive: i, initialValue: r2.initialValue ?? true, render() {
|
|
4575
|
+
const t = `${import_picocolors.default.gray(a2)}
|
|
4576
|
+
${y2(this.state)} ${r2.message}
|
|
4577
|
+
`, s = this.value ? n : i;
|
|
4578
|
+
switch (this.state) {
|
|
4579
|
+
case "submit":
|
|
4580
|
+
return `${t}${import_picocolors.default.gray(a2)} ${import_picocolors.default.dim(s)}`;
|
|
4581
|
+
case "cancel":
|
|
4582
|
+
return `${t}${import_picocolors.default.gray(a2)} ${import_picocolors.default.strikethrough(import_picocolors.default.dim(s))}
|
|
4583
|
+
${import_picocolors.default.gray(a2)}`;
|
|
4584
|
+
default:
|
|
4585
|
+
return `${t}${import_picocolors.default.cyan(a2)} ${this.value ? `${import_picocolors.default.green(b2)} ${n}` : `${import_picocolors.default.dim(E)} ${import_picocolors.default.dim(n)}`} ${import_picocolors.default.dim("/")} ${this.value ? `${import_picocolors.default.dim(E)} ${import_picocolors.default.dim(i)}` : `${import_picocolors.default.green(b2)} ${i}`}
|
|
4586
|
+
${import_picocolors.default.cyan(d2)}
|
|
4587
|
+
`;
|
|
4588
|
+
}
|
|
4589
|
+
} }).prompt();
|
|
4590
|
+
};
|
|
4591
|
+
var ie = (r2) => {
|
|
4592
|
+
const n = (t, s) => {
|
|
4593
|
+
const c = t.label ?? String(t.value);
|
|
4594
|
+
return s === "active" ? `${import_picocolors.default.green(b2)} ${c} ${t.hint ? import_picocolors.default.dim(`(${t.hint})`) : ""}` : s === "selected" ? `${import_picocolors.default.dim(c)}` : s === "cancelled" ? `${import_picocolors.default.strikethrough(import_picocolors.default.dim(c))}` : `${import_picocolors.default.dim(E)} ${import_picocolors.default.dim(c)}`;
|
|
4595
|
+
};
|
|
4596
|
+
let i = 0;
|
|
4597
|
+
return new $D({ options: r2.options, initialValue: r2.initialValue, render() {
|
|
4598
|
+
const t = `${import_picocolors.default.gray(a2)}
|
|
4599
|
+
${y2(this.state)} ${r2.message}
|
|
4600
|
+
`;
|
|
4601
|
+
switch (this.state) {
|
|
4602
|
+
case "submit":
|
|
4603
|
+
return `${t}${import_picocolors.default.gray(a2)} ${n(this.options[this.cursor], "selected")}`;
|
|
4604
|
+
case "cancel":
|
|
4605
|
+
return `${t}${import_picocolors.default.gray(a2)} ${n(this.options[this.cursor], "cancelled")}
|
|
4606
|
+
${import_picocolors.default.gray(a2)}`;
|
|
4607
|
+
default: {
|
|
4608
|
+
const s = r2.maxItems === undefined ? 1 / 0 : Math.max(r2.maxItems, 5);
|
|
4609
|
+
this.cursor >= i + s - 3 ? i = Math.max(Math.min(this.cursor - s + 3, this.options.length - s), 0) : this.cursor < i + 2 && (i = Math.max(this.cursor - 2, 0));
|
|
4610
|
+
const c = s < this.options.length && i > 0, l2 = s < this.options.length && i + s < this.options.length;
|
|
4611
|
+
return `${t}${import_picocolors.default.cyan(a2)} ${this.options.slice(i, i + s).map((u, m2, $2) => m2 === 0 && c ? import_picocolors.default.dim("...") : m2 === $2.length - 1 && l2 ? import_picocolors.default.dim("...") : n(u, m2 + i === this.cursor ? "active" : "inactive")).join(`
|
|
4612
|
+
${import_picocolors.default.cyan(a2)} `)}
|
|
4613
|
+
${import_picocolors.default.cyan(d2)}
|
|
4614
|
+
`;
|
|
4615
|
+
}
|
|
4616
|
+
}
|
|
4617
|
+
} }).prompt();
|
|
4618
|
+
};
|
|
4619
|
+
var ae = (r2) => {
|
|
4620
|
+
const n = (i, t) => {
|
|
4621
|
+
const s = i.label ?? String(i.value);
|
|
4622
|
+
return t === "active" ? `${import_picocolors.default.cyan(C)} ${s} ${i.hint ? import_picocolors.default.dim(`(${i.hint})`) : ""}` : t === "selected" ? `${import_picocolors.default.green(w2)} ${import_picocolors.default.dim(s)}` : t === "cancelled" ? `${import_picocolors.default.strikethrough(import_picocolors.default.dim(s))}` : t === "active-selected" ? `${import_picocolors.default.green(w2)} ${s} ${i.hint ? import_picocolors.default.dim(`(${i.hint})`) : ""}` : t === "submitted" ? `${import_picocolors.default.dim(s)}` : `${import_picocolors.default.dim(M2)} ${import_picocolors.default.dim(s)}`;
|
|
4623
|
+
};
|
|
4624
|
+
return new vD({ options: r2.options, initialValues: r2.initialValues, required: r2.required ?? true, cursorAt: r2.cursorAt, validate(i) {
|
|
4625
|
+
if (this.required && i.length === 0)
|
|
4626
|
+
return `Please select at least one option.
|
|
4627
|
+
${import_picocolors.default.reset(import_picocolors.default.dim(`Press ${import_picocolors.default.gray(import_picocolors.default.bgWhite(import_picocolors.default.inverse(" space ")))} to select, ${import_picocolors.default.gray(import_picocolors.default.bgWhite(import_picocolors.default.inverse(" enter ")))} to submit`))}`;
|
|
4628
|
+
}, render() {
|
|
4629
|
+
let i = `${import_picocolors.default.gray(a2)}
|
|
4630
|
+
${y2(this.state)} ${r2.message}
|
|
4631
|
+
`;
|
|
4632
|
+
switch (this.state) {
|
|
4633
|
+
case "submit":
|
|
4634
|
+
return `${i}${import_picocolors.default.gray(a2)} ${this.options.filter(({ value: t }) => this.value.includes(t)).map((t) => n(t, "submitted")).join(import_picocolors.default.dim(", ")) || import_picocolors.default.dim("none")}`;
|
|
4635
|
+
case "cancel": {
|
|
4636
|
+
const t = this.options.filter(({ value: s }) => this.value.includes(s)).map((s) => n(s, "cancelled")).join(import_picocolors.default.dim(", "));
|
|
4637
|
+
return `${i}${import_picocolors.default.gray(a2)} ${t.trim() ? `${t}
|
|
4638
|
+
${import_picocolors.default.gray(a2)}` : ""}`;
|
|
4639
|
+
}
|
|
4640
|
+
case "error": {
|
|
4641
|
+
const t = this.error.split(`
|
|
4642
|
+
`).map((s, c) => c === 0 ? `${import_picocolors.default.yellow(d2)} ${import_picocolors.default.yellow(s)}` : ` ${s}`).join(`
|
|
4643
|
+
`);
|
|
4644
|
+
return i + import_picocolors.default.yellow(a2) + " " + this.options.map((s, c) => {
|
|
4645
|
+
const l2 = this.value.includes(s.value), u = c === this.cursor;
|
|
4646
|
+
return u && l2 ? n(s, "active-selected") : l2 ? n(s, "selected") : n(s, u ? "active" : "inactive");
|
|
4647
|
+
}).join(`
|
|
4648
|
+
${import_picocolors.default.yellow(a2)} `) + `
|
|
4649
|
+
` + t + `
|
|
4650
|
+
`;
|
|
4651
|
+
}
|
|
4652
|
+
default:
|
|
4653
|
+
return `${i}${import_picocolors.default.cyan(a2)} ${this.options.map((t, s) => {
|
|
4654
|
+
const c = this.value.includes(t.value), l2 = s === this.cursor;
|
|
4655
|
+
return l2 && c ? n(t, "active-selected") : c ? n(t, "selected") : n(t, l2 ? "active" : "inactive");
|
|
4656
|
+
}).join(`
|
|
4657
|
+
${import_picocolors.default.cyan(a2)} `)}
|
|
4658
|
+
${import_picocolors.default.cyan(d2)}
|
|
4659
|
+
`;
|
|
4660
|
+
}
|
|
4661
|
+
} }).prompt();
|
|
4662
|
+
};
|
|
4663
|
+
var R2 = (r2) => r2.replace(me(), "");
|
|
4664
|
+
var le = (r2 = "", n = "") => {
|
|
4665
|
+
const i = `
|
|
4666
|
+
${r2}
|
|
4667
|
+
`.split(`
|
|
4668
|
+
`), t = R2(n).length, s = Math.max(i.reduce((l2, u) => (u = R2(u), u.length > l2 ? u.length : l2), 0), t) + 2, c = i.map((l2) => `${import_picocolors.default.gray(a2)} ${import_picocolors.default.dim(l2)}${" ".repeat(s - R2(l2).length)}${import_picocolors.default.gray(a2)}`).join(`
|
|
4669
|
+
`);
|
|
4670
|
+
process.stdout.write(`${import_picocolors.default.gray(a2)}
|
|
4671
|
+
${import_picocolors.default.green(S2)} ${import_picocolors.default.reset(n)} ${import_picocolors.default.gray(B.repeat(Math.max(s - t - 1, 1)) + Z2)}
|
|
4672
|
+
${c}
|
|
4673
|
+
${import_picocolors.default.gray(z2 + B.repeat(s + 2) + X2)}
|
|
4674
|
+
`);
|
|
4675
|
+
};
|
|
4676
|
+
var ue = (r2 = "") => {
|
|
4677
|
+
process.stdout.write(`${import_picocolors.default.gray(d2)} ${import_picocolors.default.red(r2)}
|
|
4678
|
+
|
|
4679
|
+
`);
|
|
4680
|
+
};
|
|
4681
|
+
var oe = (r2 = "") => {
|
|
4682
|
+
process.stdout.write(`${import_picocolors.default.gray(K2)} ${r2}
|
|
4683
|
+
`);
|
|
4684
|
+
};
|
|
4685
|
+
var $e = (r2 = "") => {
|
|
4686
|
+
process.stdout.write(`${import_picocolors.default.gray(a2)}
|
|
4687
|
+
${import_picocolors.default.gray(d2)} ${r2}
|
|
4688
|
+
|
|
4689
|
+
`);
|
|
4690
|
+
};
|
|
4691
|
+
var de = () => {
|
|
4692
|
+
const r2 = _2 ? ["◒", "◐", "◓", "◑"] : ["•", "o", "O", "0"], n = _2 ? 80 : 120;
|
|
4693
|
+
let i, t, s = false, c = "";
|
|
4694
|
+
const l2 = (v2 = "") => {
|
|
4695
|
+
s = true, i = OD(), c = v2.replace(/\.+$/, ""), process.stdout.write(`${import_picocolors.default.gray(a2)}
|
|
4696
|
+
`);
|
|
4697
|
+
let g2 = 0, p = 0;
|
|
4698
|
+
t = setInterval(() => {
|
|
4699
|
+
const O2 = import_picocolors.default.magenta(r2[g2]), P2 = ".".repeat(Math.floor(p)).slice(0, 3);
|
|
4700
|
+
process.stdout.write(import_sisteransi2.cursor.move(-999, 0)), process.stdout.write(import_sisteransi2.erase.down(1)), process.stdout.write(`${O2} ${c}${P2}`), g2 = g2 + 1 < r2.length ? g2 + 1 : 0, p = p < r2.length ? p + 0.125 : 0;
|
|
4701
|
+
}, n);
|
|
4702
|
+
}, u = (v2 = "", g2 = 0) => {
|
|
4703
|
+
c = v2 ?? c, s = false, clearInterval(t);
|
|
4704
|
+
const p = g2 === 0 ? import_picocolors.default.green(S2) : g2 === 1 ? import_picocolors.default.red(I2) : import_picocolors.default.red(x2);
|
|
4705
|
+
process.stdout.write(import_sisteransi2.cursor.move(-999, 0)), process.stdout.write(import_sisteransi2.erase.down(1)), process.stdout.write(`${p} ${c}
|
|
4706
|
+
`), i();
|
|
4707
|
+
}, m2 = (v2 = "") => {
|
|
4708
|
+
c = v2 ?? c;
|
|
4709
|
+
}, $2 = (v2) => {
|
|
4710
|
+
const g2 = v2 > 1 ? "Something went wrong" : "Canceled";
|
|
4711
|
+
s && u(g2, v2);
|
|
4712
|
+
};
|
|
4713
|
+
return process.on("uncaughtExceptionMonitor", () => $2(2)), process.on("unhandledRejection", () => $2(2)), process.on("SIGINT", () => $2(1)), process.on("SIGTERM", () => $2(1)), process.on("exit", $2), { start: l2, stop: u, message: m2 };
|
|
4714
|
+
};
|
|
4715
|
+
function me() {
|
|
4716
|
+
const r2 = ["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)", "(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))"].join("|");
|
|
4717
|
+
return new RegExp(r2, "g");
|
|
4718
|
+
}
|
|
4719
|
+
|
|
4720
|
+
// src/core/plan.ts
|
|
4721
|
+
import fs2 from "fs";
|
|
4722
|
+
import path4 from "path";
|
|
4723
|
+
|
|
4724
|
+
// src/core/mappings.ts
|
|
4725
|
+
import path3 from "path";
|
|
4726
|
+
|
|
4727
|
+
// src/core/paths.ts
|
|
4728
|
+
import os2 from "os";
|
|
4729
|
+
import path from "path";
|
|
4730
|
+
function resolveRoots(opts) {
|
|
4731
|
+
const homeDir = opts.homeDir || os2.homedir();
|
|
4732
|
+
const projectRoot = path.resolve(opts.projectRoot || process.cwd());
|
|
4733
|
+
if (opts.scope === "global") {
|
|
4734
|
+
return {
|
|
4735
|
+
canonicalRoot: path.join(homeDir, ".agents"),
|
|
4736
|
+
claudeRoot: path.join(homeDir, ".claude"),
|
|
4737
|
+
factoryRoot: path.join(homeDir, ".factory"),
|
|
4738
|
+
codexRoot: path.join(homeDir, ".codex"),
|
|
4739
|
+
cursorRoot: path.join(homeDir, ".cursor"),
|
|
4740
|
+
opencodeRoot: path.join(homeDir, ".opencode"),
|
|
4741
|
+
opencodeConfigRoot: path.join(homeDir, ".config", "opencode"),
|
|
4742
|
+
projectRoot,
|
|
4743
|
+
homeDir
|
|
4744
|
+
};
|
|
4745
|
+
}
|
|
4746
|
+
return {
|
|
4747
|
+
canonicalRoot: path.join(projectRoot, ".agents"),
|
|
4748
|
+
claudeRoot: path.join(projectRoot, ".claude"),
|
|
4749
|
+
factoryRoot: path.join(projectRoot, ".factory"),
|
|
4750
|
+
codexRoot: path.join(projectRoot, ".codex"),
|
|
4751
|
+
cursorRoot: path.join(projectRoot, ".cursor"),
|
|
4752
|
+
opencodeRoot: path.join(projectRoot, ".opencode"),
|
|
4753
|
+
opencodeConfigRoot: path.join(homeDir, ".config", "opencode"),
|
|
4754
|
+
projectRoot,
|
|
4755
|
+
homeDir
|
|
4756
|
+
};
|
|
4757
|
+
}
|
|
4758
|
+
|
|
4759
|
+
// src/utils/fs.ts
|
|
4760
|
+
import fs from "fs";
|
|
4761
|
+
import path2 from "path";
|
|
4762
|
+
async function pathExists(p) {
|
|
4763
|
+
try {
|
|
4764
|
+
await fs.promises.lstat(p);
|
|
4765
|
+
return true;
|
|
4766
|
+
} catch (err) {
|
|
4767
|
+
if (err && err.code === "ENOENT")
|
|
4768
|
+
return false;
|
|
4769
|
+
throw err;
|
|
4770
|
+
}
|
|
4771
|
+
}
|
|
4772
|
+
async function ensureDir(dir) {
|
|
4773
|
+
await fs.promises.mkdir(dir, { recursive: true });
|
|
4774
|
+
}
|
|
4775
|
+
async function ensureFile(filePath, content) {
|
|
4776
|
+
await ensureDir(path2.dirname(filePath));
|
|
4777
|
+
await fs.promises.writeFile(filePath, content, "utf8");
|
|
4778
|
+
}
|
|
4779
|
+
async function readText(filePath) {
|
|
4780
|
+
return await fs.promises.readFile(filePath, "utf8");
|
|
4781
|
+
}
|
|
4782
|
+
async function copyFile(src, dest, force = false) {
|
|
4783
|
+
if (!force && await pathExists(dest))
|
|
4784
|
+
return "skipped";
|
|
4785
|
+
await ensureDir(path2.dirname(dest));
|
|
4786
|
+
await fs.promises.copyFile(src, dest);
|
|
4787
|
+
return "written";
|
|
4788
|
+
}
|
|
4789
|
+
async function copyDir(src, dest, force = false) {
|
|
4790
|
+
if (!force && await pathExists(dest))
|
|
4791
|
+
return "skipped";
|
|
4792
|
+
await ensureDir(path2.dirname(dest));
|
|
4793
|
+
await fs.promises.cp(src, dest, { recursive: true, force });
|
|
4794
|
+
return "written";
|
|
4795
|
+
}
|
|
4796
|
+
async function removePath(target) {
|
|
4797
|
+
if (!await pathExists(target))
|
|
4798
|
+
return;
|
|
4799
|
+
const stat = await fs.promises.lstat(target);
|
|
4800
|
+
if (stat.isDirectory() && !stat.isSymbolicLink()) {
|
|
4801
|
+
await fs.promises.rm(target, { recursive: true, force: true });
|
|
4802
|
+
} else {
|
|
4803
|
+
await fs.promises.unlink(target);
|
|
4804
|
+
}
|
|
4805
|
+
}
|
|
4806
|
+
async function listDirs(dir) {
|
|
4807
|
+
try {
|
|
4808
|
+
const entries = await fs.promises.readdir(dir, { withFileTypes: true });
|
|
4809
|
+
return entries.filter((e2) => e2.isDirectory()).map((e2) => path2.join(dir, e2.name));
|
|
4810
|
+
} catch (err) {
|
|
4811
|
+
if (err && err.code === "ENOENT")
|
|
4812
|
+
return [];
|
|
4813
|
+
throw err;
|
|
4814
|
+
}
|
|
4815
|
+
}
|
|
4816
|
+
|
|
4817
|
+
// src/core/mappings.ts
|
|
4818
|
+
async function getMappings(opts) {
|
|
4819
|
+
const roots = resolveRoots(opts);
|
|
4820
|
+
const canonical = roots.canonicalRoot;
|
|
4821
|
+
const claudeOverride = path3.join(canonical, "CLAUDE.md");
|
|
4822
|
+
const agentsFallback = path3.join(canonical, "AGENTS.md");
|
|
4823
|
+
const agentsSource = await pathExists(claudeOverride) ? claudeOverride : agentsFallback;
|
|
4824
|
+
const clients = new Set(opts.clients ?? ["claude", "factory", "codex", "cursor", "opencode"]);
|
|
4825
|
+
const mappings = [];
|
|
4826
|
+
const includeAgentFiles = opts.scope === "global";
|
|
4827
|
+
if (includeAgentFiles && clients.has("claude")) {
|
|
4828
|
+
mappings.push({
|
|
4829
|
+
name: "claude-md",
|
|
4830
|
+
source: agentsSource,
|
|
4831
|
+
targets: [path3.join(roots.claudeRoot, "CLAUDE.md")],
|
|
4832
|
+
kind: "file"
|
|
4833
|
+
});
|
|
4834
|
+
}
|
|
4835
|
+
if (includeAgentFiles) {
|
|
4836
|
+
const agentTargets = [
|
|
4837
|
+
clients.has("factory") ? path3.join(roots.factoryRoot, "AGENTS.md") : null,
|
|
4838
|
+
clients.has("codex") ? path3.join(roots.codexRoot, "AGENTS.md") : null,
|
|
4839
|
+
clients.has("opencode") ? path3.join(roots.opencodeConfigRoot, "AGENTS.md") : null
|
|
4840
|
+
].filter(Boolean);
|
|
4841
|
+
if (agentTargets.length > 0) {
|
|
4842
|
+
mappings.push({
|
|
4843
|
+
name: "agents-md",
|
|
4844
|
+
source: agentsFallback,
|
|
4845
|
+
targets: agentTargets,
|
|
4846
|
+
kind: "file"
|
|
4847
|
+
});
|
|
4848
|
+
}
|
|
4849
|
+
}
|
|
4850
|
+
mappings.push({
|
|
4851
|
+
name: "commands",
|
|
4852
|
+
source: path3.join(canonical, "commands"),
|
|
4853
|
+
targets: [
|
|
4854
|
+
clients.has("claude") ? path3.join(roots.claudeRoot, "commands") : null,
|
|
4855
|
+
clients.has("factory") ? path3.join(roots.factoryRoot, "commands") : null,
|
|
4856
|
+
clients.has("codex") ? path3.join(roots.codexRoot, "prompts") : null,
|
|
4857
|
+
clients.has("opencode") ? path3.join(roots.opencodeRoot, "commands") : null,
|
|
4858
|
+
clients.has("cursor") ? path3.join(roots.cursorRoot, "commands") : null
|
|
4859
|
+
].filter(Boolean),
|
|
4860
|
+
kind: "dir"
|
|
4861
|
+
}, {
|
|
4862
|
+
name: "hooks",
|
|
4863
|
+
source: path3.join(canonical, "hooks"),
|
|
4864
|
+
targets: [
|
|
4865
|
+
clients.has("claude") ? path3.join(roots.claudeRoot, "hooks") : null,
|
|
4866
|
+
clients.has("factory") ? path3.join(roots.factoryRoot, "hooks") : null
|
|
4867
|
+
].filter(Boolean),
|
|
4868
|
+
kind: "dir"
|
|
4869
|
+
}, {
|
|
4870
|
+
name: "skills",
|
|
4871
|
+
source: path3.join(canonical, "skills"),
|
|
4872
|
+
targets: [
|
|
4873
|
+
clients.has("claude") ? path3.join(roots.claudeRoot, "skills") : null,
|
|
4874
|
+
clients.has("factory") ? path3.join(roots.factoryRoot, "skills") : null,
|
|
4875
|
+
clients.has("codex") ? path3.join(roots.codexRoot, "skills") : null,
|
|
4876
|
+
clients.has("opencode") ? path3.join(roots.opencodeRoot, "skills") : null,
|
|
4877
|
+
clients.has("cursor") ? path3.join(roots.cursorRoot, "skills") : null
|
|
4878
|
+
].filter(Boolean),
|
|
4879
|
+
kind: "dir"
|
|
4880
|
+
});
|
|
4881
|
+
return mappings;
|
|
4882
|
+
}
|
|
4883
|
+
|
|
4884
|
+
// src/core/plan.ts
|
|
4885
|
+
async function getLinkTargetAbsolute(targetPath) {
|
|
4886
|
+
try {
|
|
4887
|
+
const link = await fs2.promises.readlink(targetPath);
|
|
4888
|
+
if (!path4.isAbsolute(link)) {
|
|
4889
|
+
return path4.resolve(path4.dirname(targetPath), link);
|
|
4890
|
+
}
|
|
4891
|
+
return link;
|
|
4892
|
+
} catch {
|
|
4893
|
+
return null;
|
|
4894
|
+
}
|
|
4895
|
+
}
|
|
4896
|
+
async function ensureSourceTask(source, kind) {
|
|
4897
|
+
const exists = await pathExists(source);
|
|
4898
|
+
if (!exists)
|
|
4899
|
+
return [{ type: "ensure-source", path: source, kind }];
|
|
4900
|
+
const stat = await fs2.promises.lstat(source);
|
|
4901
|
+
if (kind === "file" && stat.isDirectory()) {
|
|
4902
|
+
return [{ type: "conflict", source, target: source, reason: "Expected file but found directory", kind }];
|
|
4903
|
+
}
|
|
4904
|
+
if (kind === "dir" && !stat.isDirectory()) {
|
|
4905
|
+
return [{ type: "conflict", source, target: source, reason: "Expected directory but found file", kind }];
|
|
4906
|
+
}
|
|
4907
|
+
return [];
|
|
4908
|
+
}
|
|
4909
|
+
async function analyzeTarget(source, target, kind, opts) {
|
|
4910
|
+
const exists = await pathExists(target);
|
|
4911
|
+
if (!exists)
|
|
4912
|
+
return { type: "link", source, target, kind };
|
|
4913
|
+
const stat = await fs2.promises.lstat(target);
|
|
4914
|
+
if (stat.isSymbolicLink()) {
|
|
4915
|
+
const resolved = await getLinkTargetAbsolute(target);
|
|
4916
|
+
if (resolved && path4.resolve(resolved) === path4.resolve(source)) {
|
|
4917
|
+
return { type: "noop", source, target };
|
|
4918
|
+
}
|
|
4919
|
+
if (resolved && opts?.relinkableSources) {
|
|
4920
|
+
const relinkable = new Set(opts.relinkableSources.map((p) => path4.resolve(p)));
|
|
4921
|
+
if (relinkable.has(path4.resolve(resolved))) {
|
|
4922
|
+
return { type: "link", source, target, kind, replaceSymlink: true };
|
|
4923
|
+
}
|
|
4924
|
+
}
|
|
4925
|
+
const detail = resolved ? `Symlink points elsewhere: ${resolved}` : "Symlink points elsewhere";
|
|
4926
|
+
return { type: "conflict", source, target, reason: detail, kind };
|
|
4927
|
+
}
|
|
4928
|
+
const targetKind = stat.isDirectory() ? "directory" : stat.isFile() ? "file" : "path";
|
|
4929
|
+
return { type: "conflict", source, target, reason: `Target exists and is not a symlink (${targetKind})`, kind };
|
|
4930
|
+
}
|
|
4931
|
+
async function buildLinkPlan(opts) {
|
|
4932
|
+
const mappings = await getMappings(opts);
|
|
4933
|
+
const tasks = [];
|
|
4934
|
+
for (const mapping of mappings) {
|
|
4935
|
+
tasks.push(...await ensureSourceTask(mapping.source, mapping.kind));
|
|
4936
|
+
const relinkableSources = mapping.name === "claude-md" ? [
|
|
4937
|
+
path4.join(path4.dirname(mapping.source), "AGENTS.md"),
|
|
4938
|
+
path4.join(path4.dirname(mapping.source), "CLAUDE.md")
|
|
4939
|
+
] : undefined;
|
|
4940
|
+
for (const target of mapping.targets) {
|
|
4941
|
+
tasks.push(await analyzeTarget(mapping.source, target, mapping.kind, { relinkableSources }));
|
|
4942
|
+
}
|
|
4943
|
+
}
|
|
4944
|
+
const conflicts = tasks.filter((t) => t.type === "conflict");
|
|
4945
|
+
const changes = tasks.filter((t) => t.type === "link" || t.type === "ensure-source");
|
|
4946
|
+
return { tasks, conflicts, changes };
|
|
4947
|
+
}
|
|
4948
|
+
|
|
4949
|
+
// src/core/status.ts
|
|
4950
|
+
import fs3 from "fs";
|
|
4951
|
+
import path5 from "path";
|
|
3770
4952
|
async function resolveLinkTarget(targetPath) {
|
|
3771
4953
|
try {
|
|
3772
|
-
const link = await
|
|
3773
|
-
if (!
|
|
3774
|
-
return
|
|
4954
|
+
const link = await fs3.promises.readlink(targetPath);
|
|
4955
|
+
if (!path5.isAbsolute(link))
|
|
4956
|
+
return path5.resolve(path5.dirname(targetPath), link);
|
|
3775
4957
|
return link;
|
|
3776
4958
|
} catch {
|
|
3777
4959
|
return null;
|
|
3778
4960
|
}
|
|
3779
4961
|
}
|
|
3780
4962
|
async function getLinkStatus(opts) {
|
|
3781
|
-
const mappings = getMappings(opts);
|
|
4963
|
+
const mappings = await getMappings(opts);
|
|
3782
4964
|
const statuses = [];
|
|
3783
4965
|
for (const mapping of mappings) {
|
|
3784
4966
|
const targets = [];
|
|
@@ -3788,10 +4970,10 @@ async function getLinkStatus(opts) {
|
|
|
3788
4970
|
targets.push({ path: target, status: "missing" });
|
|
3789
4971
|
continue;
|
|
3790
4972
|
}
|
|
3791
|
-
const stat = await
|
|
4973
|
+
const stat = await fs3.promises.lstat(target);
|
|
3792
4974
|
if (stat.isSymbolicLink()) {
|
|
3793
4975
|
const resolved = await resolveLinkTarget(target);
|
|
3794
|
-
if (resolved &&
|
|
4976
|
+
if (resolved && path5.resolve(resolved) === path5.resolve(mapping.source)) {
|
|
3795
4977
|
targets.push({ path: target, status: "linked" });
|
|
3796
4978
|
} else {
|
|
3797
4979
|
targets.push({ path: target, status: "conflict" });
|
|
@@ -3806,12 +4988,12 @@ async function getLinkStatus(opts) {
|
|
|
3806
4988
|
}
|
|
3807
4989
|
|
|
3808
4990
|
// src/core/migrate.ts
|
|
3809
|
-
import
|
|
3810
|
-
import
|
|
4991
|
+
import fs6 from "fs";
|
|
4992
|
+
import path9 from "path";
|
|
3811
4993
|
|
|
3812
4994
|
// src/core/skills.ts
|
|
3813
4995
|
var import_gray_matter = __toESM(require_gray_matter(), 1);
|
|
3814
|
-
import
|
|
4996
|
+
import path6 from "path";
|
|
3815
4997
|
var NAME_RE = /^[a-z0-9-]{1,64}$/;
|
|
3816
4998
|
async function parseSkillFile(skillFile) {
|
|
3817
4999
|
const raw = await readText(skillFile);
|
|
@@ -3833,13 +5015,13 @@ async function parseSkillFile(skillFile) {
|
|
|
3833
5015
|
};
|
|
3834
5016
|
}
|
|
3835
5017
|
async function isSkillDir(dir) {
|
|
3836
|
-
return await pathExists(
|
|
5018
|
+
return await pathExists(path6.join(dir, "SKILL.md"));
|
|
3837
5019
|
}
|
|
3838
5020
|
async function findSkillDirs(root) {
|
|
3839
5021
|
const direct = await isSkillDir(root);
|
|
3840
5022
|
if (direct)
|
|
3841
5023
|
return [root];
|
|
3842
|
-
const skillsDir =
|
|
5024
|
+
const skillsDir = path6.join(root, "skills");
|
|
3843
5025
|
const skillsDirExists = await pathExists(skillsDir);
|
|
3844
5026
|
if (skillsDirExists) {
|
|
3845
5027
|
const children2 = await listDirs(skillsDir);
|
|
@@ -3857,77 +5039,258 @@ async function findSkillDirs(root) {
|
|
|
3857
5039
|
if (await isSkillDir(child))
|
|
3858
5040
|
matches.push(child);
|
|
3859
5041
|
}
|
|
3860
|
-
return matches;
|
|
5042
|
+
return matches;
|
|
5043
|
+
}
|
|
5044
|
+
|
|
5045
|
+
// src/core/apply.ts
|
|
5046
|
+
import fs5 from "fs";
|
|
5047
|
+
import path8 from "path";
|
|
5048
|
+
|
|
5049
|
+
// src/core/backup.ts
|
|
5050
|
+
import fs4 from "fs";
|
|
5051
|
+
import path7 from "path";
|
|
5052
|
+
var MANIFEST_NAME = "manifest.json";
|
|
5053
|
+
function backupPathFor(target, backupRoot) {
|
|
5054
|
+
const root = path7.parse(target).root || path7.sep;
|
|
5055
|
+
const rel = path7.relative(root, target);
|
|
5056
|
+
return path7.join(backupRoot, rel);
|
|
5057
|
+
}
|
|
5058
|
+
function hasParentPath(target, seen) {
|
|
5059
|
+
const resolved = path7.resolve(target);
|
|
5060
|
+
for (const parent of seen) {
|
|
5061
|
+
if (resolved === parent)
|
|
5062
|
+
return true;
|
|
5063
|
+
if (resolved.startsWith(parent + path7.sep))
|
|
5064
|
+
return true;
|
|
5065
|
+
}
|
|
5066
|
+
return false;
|
|
5067
|
+
}
|
|
5068
|
+
async function backupSymlink(target, dest) {
|
|
5069
|
+
const link = await fs4.promises.readlink(target);
|
|
5070
|
+
await ensureDir(path7.dirname(dest));
|
|
5071
|
+
await fs4.promises.symlink(link, dest);
|
|
5072
|
+
await fs4.promises.unlink(target);
|
|
5073
|
+
}
|
|
5074
|
+
async function backupPathImpl(target, dest, kind) {
|
|
5075
|
+
await ensureDir(path7.dirname(dest));
|
|
5076
|
+
try {
|
|
5077
|
+
await fs4.promises.rename(target, dest);
|
|
5078
|
+
return;
|
|
5079
|
+
} catch (err) {
|
|
5080
|
+
if (err?.code !== "EXDEV")
|
|
5081
|
+
throw err;
|
|
5082
|
+
}
|
|
5083
|
+
if (kind === "dir") {
|
|
5084
|
+
await copyDir(target, dest, true);
|
|
5085
|
+
} else {
|
|
5086
|
+
await copyFile(target, dest, true);
|
|
5087
|
+
}
|
|
5088
|
+
await removePath(target);
|
|
5089
|
+
}
|
|
5090
|
+
async function createBackupSession(opts) {
|
|
5091
|
+
const timestamp = opts.timestamp || new Date().toISOString().replace(/[:.]/g, "-");
|
|
5092
|
+
const dir = path7.join(opts.canonicalRoot, "backup", timestamp);
|
|
5093
|
+
await ensureDir(dir);
|
|
5094
|
+
return {
|
|
5095
|
+
dir,
|
|
5096
|
+
manifestPath: path7.join(dir, MANIFEST_NAME),
|
|
5097
|
+
createdAt: new Date().toISOString(),
|
|
5098
|
+
scope: opts.scope,
|
|
5099
|
+
operation: opts.operation,
|
|
5100
|
+
entries: [],
|
|
5101
|
+
_seen: new Set
|
|
5102
|
+
};
|
|
5103
|
+
}
|
|
5104
|
+
async function backupPath(target, session) {
|
|
5105
|
+
if (!await pathExists(target))
|
|
5106
|
+
return false;
|
|
5107
|
+
const resolved = path7.resolve(target);
|
|
5108
|
+
if (hasParentPath(resolved, session._seen))
|
|
5109
|
+
return false;
|
|
5110
|
+
const stat = await fs4.promises.lstat(target);
|
|
5111
|
+
const kind = stat.isSymbolicLink() ? "symlink" : stat.isDirectory() ? "dir" : "file";
|
|
5112
|
+
const dest = backupPathFor(target, session.dir);
|
|
5113
|
+
if (stat.isSymbolicLink()) {
|
|
5114
|
+
await backupSymlink(target, dest);
|
|
5115
|
+
} else {
|
|
5116
|
+
await backupPathImpl(target, dest, kind);
|
|
5117
|
+
}
|
|
5118
|
+
session.entries.push({ originalPath: resolved, backupPath: dest, kind, action: "backup" });
|
|
5119
|
+
session._seen.add(resolved);
|
|
5120
|
+
return true;
|
|
5121
|
+
}
|
|
5122
|
+
function recordCreatedPath(target, kind, session) {
|
|
5123
|
+
const resolved = path7.resolve(target);
|
|
5124
|
+
if (hasParentPath(resolved, session._seen))
|
|
5125
|
+
return;
|
|
5126
|
+
session.entries.push({ originalPath: resolved, kind, action: "create" });
|
|
5127
|
+
session._seen.add(resolved);
|
|
5128
|
+
}
|
|
5129
|
+
async function finalizeBackup(session) {
|
|
5130
|
+
const manifest = {
|
|
5131
|
+
version: 1,
|
|
5132
|
+
createdAt: session.createdAt,
|
|
5133
|
+
scope: session.scope,
|
|
5134
|
+
operation: session.operation,
|
|
5135
|
+
entries: session.entries
|
|
5136
|
+
};
|
|
5137
|
+
await fs4.promises.writeFile(session.manifestPath, JSON.stringify(manifest, null, 2), "utf8");
|
|
5138
|
+
}
|
|
5139
|
+
async function loadBackupManifest(dir) {
|
|
5140
|
+
const manifestPath = path7.join(dir, MANIFEST_NAME);
|
|
5141
|
+
if (!await pathExists(manifestPath))
|
|
5142
|
+
return null;
|
|
5143
|
+
const raw = await fs4.promises.readFile(manifestPath, "utf8");
|
|
5144
|
+
return JSON.parse(raw);
|
|
5145
|
+
}
|
|
5146
|
+
|
|
5147
|
+
// src/core/apply.ts
|
|
5148
|
+
var DEFAULT_AGENTS = `# AGENTS
|
|
5149
|
+
|
|
5150
|
+
Add shared agent instructions here.
|
|
5151
|
+
`;
|
|
5152
|
+
async function createSource(task) {
|
|
5153
|
+
if (task.kind === "dir") {
|
|
5154
|
+
await ensureDir(task.path);
|
|
5155
|
+
return;
|
|
5156
|
+
}
|
|
5157
|
+
await ensureFile(task.path, DEFAULT_AGENTS);
|
|
5158
|
+
}
|
|
5159
|
+
async function createLink(source, target, kind, overwrite, backup) {
|
|
5160
|
+
if (await pathExists(target)) {
|
|
5161
|
+
if (!overwrite)
|
|
5162
|
+
return { created: false, backedUp: false };
|
|
5163
|
+
const backedUp = backup ? await backupPath(target, backup) : false;
|
|
5164
|
+
if (await pathExists(target))
|
|
5165
|
+
await removePath(target);
|
|
5166
|
+
await ensureDir(path8.dirname(target));
|
|
5167
|
+
const type2 = kind === "dir" ? "junction" : "file";
|
|
5168
|
+
await fs5.promises.symlink(source, target, type2);
|
|
5169
|
+
return { created: true, backedUp };
|
|
5170
|
+
}
|
|
5171
|
+
await ensureDir(path8.dirname(target));
|
|
5172
|
+
const type = kind === "dir" ? "junction" : "file";
|
|
5173
|
+
await fs5.promises.symlink(source, target, type);
|
|
5174
|
+
return { created: true, backedUp: false };
|
|
3861
5175
|
}
|
|
3862
|
-
function
|
|
3863
|
-
|
|
5176
|
+
async function applyLinkPlan(plan, opts) {
|
|
5177
|
+
const force = !!opts?.force;
|
|
5178
|
+
const backup = opts.backup;
|
|
5179
|
+
if (!backup)
|
|
5180
|
+
throw new Error("Backup session required.");
|
|
5181
|
+
let applied = 0;
|
|
5182
|
+
let skipped = 0;
|
|
5183
|
+
let conflicts = 0;
|
|
5184
|
+
let backedUp = 0;
|
|
5185
|
+
for (const task of plan.tasks) {
|
|
5186
|
+
if (task.type === "conflict") {
|
|
5187
|
+
conflicts += 1;
|
|
5188
|
+
if (force && task.target !== task.source && task.kind) {
|
|
5189
|
+
const result = await createLink(task.source, task.target, task.kind, true, backup);
|
|
5190
|
+
if (result.backedUp)
|
|
5191
|
+
backedUp += 1;
|
|
5192
|
+
applied += 1;
|
|
5193
|
+
}
|
|
5194
|
+
continue;
|
|
5195
|
+
}
|
|
5196
|
+
if (task.type === "noop") {
|
|
5197
|
+
skipped += 1;
|
|
5198
|
+
continue;
|
|
5199
|
+
}
|
|
5200
|
+
if (task.type === "ensure-source") {
|
|
5201
|
+
await createSource(task);
|
|
5202
|
+
recordCreatedPath(task.path, task.kind, backup);
|
|
5203
|
+
applied += 1;
|
|
5204
|
+
continue;
|
|
5205
|
+
}
|
|
5206
|
+
if (task.type === "link") {
|
|
5207
|
+
const before = await pathExists(task.target);
|
|
5208
|
+
let useForce = force;
|
|
5209
|
+
if (!useForce && task.replaceSymlink && before) {
|
|
5210
|
+
try {
|
|
5211
|
+
const stat = await fs5.promises.lstat(task.target);
|
|
5212
|
+
if (stat.isSymbolicLink())
|
|
5213
|
+
useForce = true;
|
|
5214
|
+
} catch {}
|
|
5215
|
+
}
|
|
5216
|
+
const result = await createLink(task.source, task.target, task.kind, useForce, backup);
|
|
5217
|
+
if (result.backedUp)
|
|
5218
|
+
backedUp += 1;
|
|
5219
|
+
if (!before && result.created) {
|
|
5220
|
+
recordCreatedPath(task.target, "symlink", backup);
|
|
5221
|
+
}
|
|
5222
|
+
if (before && !useForce)
|
|
5223
|
+
skipped += 1;
|
|
5224
|
+
else
|
|
5225
|
+
applied += 1;
|
|
5226
|
+
}
|
|
5227
|
+
}
|
|
5228
|
+
return { applied, skipped, conflicts, backupDir: backup.dir, backedUp };
|
|
3864
5229
|
}
|
|
3865
5230
|
|
|
3866
5231
|
// src/core/migrate.ts
|
|
3867
5232
|
async function isSymlink(p) {
|
|
3868
5233
|
try {
|
|
3869
|
-
const stat = await
|
|
5234
|
+
const stat = await fs6.promises.lstat(p);
|
|
3870
5235
|
return stat.isSymbolicLink();
|
|
3871
5236
|
} catch {
|
|
3872
5237
|
return false;
|
|
3873
5238
|
}
|
|
3874
5239
|
}
|
|
3875
|
-
async function
|
|
5240
|
+
async function listFiles(dir) {
|
|
3876
5241
|
try {
|
|
3877
|
-
const entries = await
|
|
3878
|
-
return entries.filter((
|
|
5242
|
+
const entries = await fs6.promises.readdir(dir, { withFileTypes: true });
|
|
5243
|
+
return entries.filter((e2) => e2.isFile()).map((e2) => path9.join(dir, e2.name));
|
|
3879
5244
|
} catch {
|
|
3880
5245
|
return [];
|
|
3881
5246
|
}
|
|
3882
5247
|
}
|
|
3883
|
-
async function movePath(src, dest, kind) {
|
|
3884
|
-
await ensureDir(path8.dirname(dest));
|
|
3885
|
-
try {
|
|
3886
|
-
await fs5.promises.rename(src, dest);
|
|
3887
|
-
return;
|
|
3888
|
-
} catch (err) {
|
|
3889
|
-
if (err?.code !== "EXDEV")
|
|
3890
|
-
throw err;
|
|
3891
|
-
}
|
|
3892
|
-
if (kind === "file") {
|
|
3893
|
-
await copyFile(src, dest, true);
|
|
3894
|
-
} else {
|
|
3895
|
-
await copyDir(src, dest, true);
|
|
3896
|
-
}
|
|
3897
|
-
await removePath(src);
|
|
3898
|
-
}
|
|
3899
5248
|
function conflictLabel(targetPath, canonicalRoot) {
|
|
3900
5249
|
if (targetPath.startsWith(canonicalRoot)) {
|
|
3901
|
-
const rel =
|
|
3902
|
-
return rel ||
|
|
5250
|
+
const rel = path9.relative(canonicalRoot, targetPath);
|
|
5251
|
+
return rel || path9.basename(targetPath);
|
|
3903
5252
|
}
|
|
3904
|
-
return
|
|
5253
|
+
return path9.basename(targetPath);
|
|
3905
5254
|
}
|
|
3906
5255
|
async function scanMigration(opts) {
|
|
3907
5256
|
const roots = resolveRoots(opts);
|
|
3908
5257
|
const canonicalRoot = roots.canonicalRoot;
|
|
3909
5258
|
const candidatesByTarget = new Map;
|
|
3910
|
-
const
|
|
3911
|
-
const
|
|
3912
|
-
const
|
|
3913
|
-
const
|
|
5259
|
+
const clients = new Set(opts.clients ?? ["claude", "factory", "codex", "cursor", "opencode"]);
|
|
5260
|
+
const includeAgentFiles = opts.scope === "global";
|
|
5261
|
+
const canonicalCommands = path9.join(canonicalRoot, "commands");
|
|
5262
|
+
const canonicalHooks = path9.join(canonicalRoot, "hooks");
|
|
5263
|
+
const canonicalSkills = path9.join(canonicalRoot, "skills");
|
|
5264
|
+
const canonicalAgents = path9.join(canonicalRoot, "AGENTS.md");
|
|
5265
|
+
const canonicalClaude = path9.join(canonicalRoot, "CLAUDE.md");
|
|
3914
5266
|
const sources = {
|
|
3915
5267
|
commands: [
|
|
3916
|
-
{ label: "Claude commands", dir:
|
|
3917
|
-
{ label: "Factory commands", dir:
|
|
3918
|
-
{ label: "Codex prompts", dir:
|
|
3919
|
-
|
|
5268
|
+
clients.has("claude") ? { label: "Claude commands", dir: path9.join(roots.claudeRoot, "commands") } : null,
|
|
5269
|
+
clients.has("factory") ? { label: "Factory commands", dir: path9.join(roots.factoryRoot, "commands") } : null,
|
|
5270
|
+
clients.has("codex") ? { label: "Codex prompts", dir: path9.join(roots.codexRoot, "prompts") } : null,
|
|
5271
|
+
clients.has("cursor") ? { label: "Cursor commands", dir: path9.join(roots.cursorRoot, "commands") } : null,
|
|
5272
|
+
clients.has("opencode") ? { label: "OpenCode commands", dir: path9.join(roots.opencodeRoot, "commands") } : null
|
|
5273
|
+
].filter(Boolean),
|
|
3920
5274
|
hooks: [
|
|
3921
|
-
{ label: "Claude hooks", dir:
|
|
3922
|
-
{ label: "Factory hooks", dir:
|
|
3923
|
-
],
|
|
5275
|
+
clients.has("claude") ? { label: "Claude hooks", dir: path9.join(roots.claudeRoot, "hooks") } : null,
|
|
5276
|
+
clients.has("factory") ? { label: "Factory hooks", dir: path9.join(roots.factoryRoot, "hooks") } : null
|
|
5277
|
+
].filter(Boolean),
|
|
3924
5278
|
skills: [
|
|
3925
|
-
{ label: "Claude skills", dir:
|
|
3926
|
-
{ label: "Factory skills", dir:
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
{ label: "
|
|
3930
|
-
]
|
|
5279
|
+
clients.has("claude") ? { label: "Claude skills", dir: path9.join(roots.claudeRoot, "skills") } : null,
|
|
5280
|
+
clients.has("factory") ? { label: "Factory skills", dir: path9.join(roots.factoryRoot, "skills") } : null,
|
|
5281
|
+
clients.has("codex") ? { label: "Codex skills", dir: path9.join(roots.codexRoot, "skills") } : null,
|
|
5282
|
+
clients.has("cursor") ? { label: "Cursor skills", dir: path9.join(roots.cursorRoot, "skills") } : null,
|
|
5283
|
+
clients.has("opencode") ? { label: "OpenCode skills", dir: path9.join(roots.opencodeRoot, "skills") } : null
|
|
5284
|
+
].filter(Boolean),
|
|
5285
|
+
agents: includeAgentFiles ? [
|
|
5286
|
+
clients.has("claude") ? { label: "Claude AGENTS.md", file: path9.join(roots.claudeRoot, "AGENTS.md") } : null,
|
|
5287
|
+
clients.has("factory") ? { label: "Factory AGENTS.md", file: path9.join(roots.factoryRoot, "AGENTS.md") } : null,
|
|
5288
|
+
clients.has("codex") ? { label: "Codex AGENTS.md", file: path9.join(roots.codexRoot, "AGENTS.md") } : null,
|
|
5289
|
+
clients.has("opencode") ? { label: "OpenCode AGENTS.md", file: path9.join(roots.opencodeConfigRoot, "AGENTS.md") } : null
|
|
5290
|
+
].filter(Boolean) : [],
|
|
5291
|
+
claude: includeAgentFiles ? [
|
|
5292
|
+
clients.has("claude") ? { label: "Claude CLAUDE.md", file: path9.join(roots.claudeRoot, "CLAUDE.md") } : null
|
|
5293
|
+
].filter(Boolean) : []
|
|
3931
5294
|
};
|
|
3932
5295
|
const addCandidate = (candidate) => {
|
|
3933
5296
|
const list = candidatesByTarget.get(candidate.targetPath) || [];
|
|
@@ -3937,18 +5300,18 @@ async function scanMigration(opts) {
|
|
|
3937
5300
|
for (const src of sources.commands) {
|
|
3938
5301
|
if (!await pathExists(src.dir) || await isSymlink(src.dir))
|
|
3939
5302
|
continue;
|
|
3940
|
-
const files = await
|
|
5303
|
+
const files = await listFiles(src.dir);
|
|
3941
5304
|
for (const file of files) {
|
|
3942
|
-
const targetPath =
|
|
5305
|
+
const targetPath = path9.join(canonicalCommands, path9.basename(file));
|
|
3943
5306
|
addCandidate({ label: src.label, targetPath, kind: "file", action: "copy", sourcePath: file });
|
|
3944
5307
|
}
|
|
3945
5308
|
}
|
|
3946
5309
|
for (const src of sources.hooks) {
|
|
3947
5310
|
if (!await pathExists(src.dir) || await isSymlink(src.dir))
|
|
3948
5311
|
continue;
|
|
3949
|
-
const files = await
|
|
5312
|
+
const files = await listFiles(src.dir);
|
|
3950
5313
|
for (const file of files) {
|
|
3951
|
-
const targetPath =
|
|
5314
|
+
const targetPath = path9.join(canonicalHooks, path9.basename(file));
|
|
3952
5315
|
addCandidate({ label: src.label, targetPath, kind: "file", action: "copy", sourcePath: file });
|
|
3953
5316
|
}
|
|
3954
5317
|
}
|
|
@@ -3958,8 +5321,8 @@ async function scanMigration(opts) {
|
|
|
3958
5321
|
const skillDirs = await findSkillDirs(src.dir);
|
|
3959
5322
|
for (const dir of skillDirs) {
|
|
3960
5323
|
try {
|
|
3961
|
-
const meta = await parseSkillFile(
|
|
3962
|
-
const targetPath =
|
|
5324
|
+
const meta = await parseSkillFile(path9.join(dir, "SKILL.md"));
|
|
5325
|
+
const targetPath = path9.join(canonicalSkills, meta.name);
|
|
3963
5326
|
addCandidate({ label: src.label, targetPath, kind: "dir", action: "copy", sourcePath: dir });
|
|
3964
5327
|
} catch {}
|
|
3965
5328
|
}
|
|
@@ -3969,6 +5332,11 @@ async function scanMigration(opts) {
|
|
|
3969
5332
|
continue;
|
|
3970
5333
|
addCandidate({ label: src.label, targetPath: canonicalAgents, kind: "file", action: "copy", sourcePath: src.file });
|
|
3971
5334
|
}
|
|
5335
|
+
for (const src of sources.claude) {
|
|
5336
|
+
if (!await pathExists(src.file) || await isSymlink(src.file))
|
|
5337
|
+
continue;
|
|
5338
|
+
addCandidate({ label: src.label, targetPath: canonicalClaude, kind: "file", action: "copy", sourcePath: src.file });
|
|
5339
|
+
}
|
|
3972
5340
|
const auto = [];
|
|
3973
5341
|
const conflicts = [];
|
|
3974
5342
|
for (const [targetPath, list] of candidatesByTarget.entries()) {
|
|
@@ -3976,7 +5344,7 @@ async function scanMigration(opts) {
|
|
|
3976
5344
|
if (canonicalExists) {
|
|
3977
5345
|
let kind = "file";
|
|
3978
5346
|
try {
|
|
3979
|
-
const stat = await
|
|
5347
|
+
const stat = await fs6.promises.lstat(targetPath);
|
|
3980
5348
|
kind = stat.isDirectory() ? "dir" : "file";
|
|
3981
5349
|
} catch {}
|
|
3982
5350
|
list.unshift({
|
|
@@ -3998,27 +5366,23 @@ async function scanMigration(opts) {
|
|
|
3998
5366
|
candidates: list
|
|
3999
5367
|
});
|
|
4000
5368
|
}
|
|
4001
|
-
|
|
4002
|
-
{ label: "claude/commands", path: path8.join(roots.claudeRoot, "commands"), kind: "dir" },
|
|
4003
|
-
{ label: "factory/commands", path: path8.join(roots.factoryRoot, "commands"), kind: "dir" },
|
|
4004
|
-
{ label: "codex/prompts", path: path8.join(roots.codexRoot, "prompts"), kind: "dir" },
|
|
4005
|
-
{ label: "claude/hooks", path: path8.join(roots.claudeRoot, "hooks"), kind: "dir" },
|
|
4006
|
-
{ label: "factory/hooks", path: path8.join(roots.factoryRoot, "hooks"), kind: "dir" },
|
|
4007
|
-
{ label: "claude/skills", path: path8.join(roots.claudeRoot, "skills"), kind: "dir" },
|
|
4008
|
-
{ label: "factory/skills", path: path8.join(roots.factoryRoot, "skills"), kind: "dir" },
|
|
4009
|
-
{ label: "claude/CLAUDE.md", path: path8.join(roots.claudeRoot, "CLAUDE.md"), kind: "file" }
|
|
4010
|
-
];
|
|
4011
|
-
return { auto, conflicts, backupPaths, canonicalRoot };
|
|
5369
|
+
return { auto, conflicts, canonicalRoot };
|
|
4012
5370
|
}
|
|
4013
5371
|
async function applyMigration(plan, selections, opts) {
|
|
4014
|
-
const
|
|
4015
|
-
|
|
4016
|
-
|
|
5372
|
+
const backup = opts.backup;
|
|
5373
|
+
if (!backup)
|
|
5374
|
+
throw new Error("Backup session required.");
|
|
4017
5375
|
let copied = 0;
|
|
4018
5376
|
let skipped = 0;
|
|
4019
5377
|
const copyCandidate = async (candidate) => {
|
|
4020
5378
|
if (candidate.action !== "copy" || !candidate.sourcePath)
|
|
4021
5379
|
return false;
|
|
5380
|
+
const existed = await pathExists(candidate.targetPath);
|
|
5381
|
+
if (existed) {
|
|
5382
|
+
await backupPath(candidate.targetPath, backup);
|
|
5383
|
+
} else {
|
|
5384
|
+
recordCreatedPath(candidate.targetPath, candidate.kind === "dir" ? "dir" : "file", backup);
|
|
5385
|
+
}
|
|
4022
5386
|
if (candidate.kind === "file") {
|
|
4023
5387
|
await copyFile(candidate.sourcePath, candidate.targetPath, true);
|
|
4024
5388
|
} else {
|
|
@@ -4043,1229 +5407,467 @@ async function applyMigration(plan, selections, opts) {
|
|
|
4043
5407
|
else
|
|
4044
5408
|
skipped += 1;
|
|
4045
5409
|
}
|
|
4046
|
-
for (const item of plan.backupPaths) {
|
|
4047
|
-
if (!await pathExists(item.path))
|
|
4048
|
-
continue;
|
|
4049
|
-
if (await isSymlink(item.path))
|
|
4050
|
-
continue;
|
|
4051
|
-
const dest = path8.join(backupDir, item.label);
|
|
4052
|
-
await movePath(item.path, dest, item.kind);
|
|
4053
|
-
}
|
|
4054
5410
|
const linkPlan = await buildLinkPlan(opts);
|
|
4055
|
-
await applyLinkPlan(linkPlan);
|
|
4056
|
-
return {
|
|
5411
|
+
const linkResult = await applyLinkPlan(linkPlan, { force: !!opts.forceLinks, backup });
|
|
5412
|
+
return {
|
|
5413
|
+
copied,
|
|
5414
|
+
skipped,
|
|
5415
|
+
backupDir: backup.dir,
|
|
5416
|
+
links: {
|
|
5417
|
+
applied: linkResult.applied,
|
|
5418
|
+
skipped: linkResult.skipped,
|
|
5419
|
+
conflicts: linkResult.conflicts,
|
|
5420
|
+
backedUp: linkResult.backedUp
|
|
5421
|
+
}
|
|
5422
|
+
};
|
|
4057
5423
|
}
|
|
4058
5424
|
|
|
4059
|
-
// src/
|
|
4060
|
-
import fs8 from "fs";
|
|
4061
|
-
import path13 from "path";
|
|
4062
|
-
|
|
4063
|
-
// src/installers/source.ts
|
|
5425
|
+
// src/core/undo.ts
|
|
4064
5426
|
import fs7 from "fs";
|
|
4065
|
-
import os3 from "os";
|
|
4066
|
-
import path12 from "path";
|
|
4067
|
-
|
|
4068
|
-
// src/utils/paths.ts
|
|
4069
|
-
import os2 from "os";
|
|
4070
|
-
import path9 from "path";
|
|
4071
|
-
function expandHome(p) {
|
|
4072
|
-
if (!p)
|
|
4073
|
-
return p;
|
|
4074
|
-
if (p === "~")
|
|
4075
|
-
return os2.homedir();
|
|
4076
|
-
if (p.startsWith("~/"))
|
|
4077
|
-
return path9.join(os2.homedir(), p.slice(2));
|
|
4078
|
-
return p;
|
|
4079
|
-
}
|
|
4080
|
-
function isUrl(input) {
|
|
4081
|
-
return /^https?:\/\//i.test(input);
|
|
4082
|
-
}
|
|
4083
|
-
function isGitUrl(input) {
|
|
4084
|
-
return /^(git@|https?:\/\/).+\.git$/i.test(input) || input.startsWith("git://");
|
|
4085
|
-
}
|
|
4086
|
-
function isFileUrl(input) {
|
|
4087
|
-
return /^file:\/\//i.test(input);
|
|
4088
|
-
}
|
|
4089
|
-
function normalizeFileUrl(input) {
|
|
4090
|
-
if (!isFileUrl(input))
|
|
4091
|
-
return input;
|
|
4092
|
-
const url = new URL(input);
|
|
4093
|
-
return url.pathname;
|
|
4094
|
-
}
|
|
4095
|
-
|
|
4096
|
-
// src/utils/http.ts
|
|
4097
|
-
import fs6 from "fs";
|
|
4098
5427
|
import path10 from "path";
|
|
4099
|
-
async function
|
|
4100
|
-
const
|
|
4101
|
-
if (!
|
|
4102
|
-
|
|
4103
|
-
|
|
4104
|
-
|
|
4105
|
-
async function fetchJson(url) {
|
|
4106
|
-
const text = await fetchText(url);
|
|
4107
|
-
return JSON.parse(text);
|
|
5428
|
+
async function listBackupDirs(canonicalRoot) {
|
|
5429
|
+
const root = path10.join(canonicalRoot, "backup");
|
|
5430
|
+
if (!await pathExists(root))
|
|
5431
|
+
return [];
|
|
5432
|
+
const entries = await fs7.promises.readdir(root, { withFileTypes: true });
|
|
5433
|
+
return entries.filter((e2) => e2.isDirectory()).map((e2) => path10.join(root, e2.name));
|
|
4108
5434
|
}
|
|
4109
|
-
async function
|
|
4110
|
-
const
|
|
4111
|
-
|
|
4112
|
-
|
|
4113
|
-
|
|
4114
|
-
|
|
4115
|
-
|
|
5435
|
+
async function findLatestBackup(canonicalRoot) {
|
|
5436
|
+
const dirs = await listBackupDirs(canonicalRoot);
|
|
5437
|
+
const manifests = [];
|
|
5438
|
+
for (const dir of dirs) {
|
|
5439
|
+
const manifest = await loadBackupManifest(dir);
|
|
5440
|
+
if (manifest)
|
|
5441
|
+
manifests.push({ dir, manifest });
|
|
5442
|
+
}
|
|
5443
|
+
if (!manifests.length)
|
|
5444
|
+
return null;
|
|
5445
|
+
manifests.sort((a3, b3) => a3.manifest.createdAt.localeCompare(b3.manifest.createdAt));
|
|
5446
|
+
return manifests[manifests.length - 1] || null;
|
|
4116
5447
|
}
|
|
4117
|
-
|
|
4118
|
-
|
|
4119
|
-
|
|
4120
|
-
|
|
4121
|
-
|
|
4122
|
-
|
|
4123
|
-
|
|
4124
|
-
return await new Promise((resolve, reject) => {
|
|
4125
|
-
const child = spawn(cmd, args, { cwd: opts?.cwd, stdio: ["ignore", "pipe", "pipe"] });
|
|
4126
|
-
let stdout = "";
|
|
4127
|
-
let stderr = "";
|
|
4128
|
-
child.stdout.on("data", (d) => stdout += d.toString());
|
|
4129
|
-
child.stderr.on("data", (d) => stderr += d.toString());
|
|
4130
|
-
child.on("error", reject);
|
|
4131
|
-
child.on("close", (code) => {
|
|
4132
|
-
if (code === 0)
|
|
4133
|
-
resolve({ stdout, stderr });
|
|
4134
|
-
else
|
|
4135
|
-
reject(new Error(`${cmd} ${args.join(" ")} failed with code ${code}: ${stderr || stdout}`));
|
|
4136
|
-
});
|
|
4137
|
-
});
|
|
5448
|
+
async function restoreSymlink(entry) {
|
|
5449
|
+
if (!entry.backupPath)
|
|
5450
|
+
return;
|
|
5451
|
+
const link = await fs7.promises.readlink(entry.backupPath);
|
|
5452
|
+
await ensureDir(path10.dirname(entry.originalPath));
|
|
5453
|
+
await fs7.promises.symlink(link, entry.originalPath);
|
|
5454
|
+
await fs7.promises.unlink(entry.backupPath);
|
|
4138
5455
|
}
|
|
4139
|
-
|
|
4140
|
-
|
|
4141
|
-
|
|
4142
|
-
const lower = archivePath.toLowerCase();
|
|
4143
|
-
if (lower.endsWith(".zip")) {
|
|
4144
|
-
await runCommand("unzip", ["-q", archivePath, "-d", destDir]);
|
|
5456
|
+
async function restorePath(entry) {
|
|
5457
|
+
if (entry.action === "create") {
|
|
5458
|
+
await removePath(entry.originalPath);
|
|
4145
5459
|
return;
|
|
4146
5460
|
}
|
|
4147
|
-
if (
|
|
4148
|
-
|
|
5461
|
+
if (!entry.backupPath)
|
|
5462
|
+
return;
|
|
5463
|
+
if (entry.kind === "symlink") {
|
|
5464
|
+
await restoreSymlink(entry);
|
|
4149
5465
|
return;
|
|
4150
5466
|
}
|
|
4151
|
-
|
|
4152
|
-
|
|
5467
|
+
await ensureDir(path10.dirname(entry.originalPath));
|
|
5468
|
+
try {
|
|
5469
|
+
await fs7.promises.rename(entry.backupPath, entry.originalPath);
|
|
4153
5470
|
return;
|
|
5471
|
+
} catch (err) {
|
|
5472
|
+
if (err?.code !== "EXDEV")
|
|
5473
|
+
throw err;
|
|
4154
5474
|
}
|
|
4155
|
-
|
|
4156
|
-
}
|
|
4157
|
-
|
|
4158
|
-
|
|
4159
|
-
async function makeTempDir(prefix) {
|
|
4160
|
-
return await fs7.promises.mkdtemp(path12.join(os3.tmpdir(), prefix));
|
|
4161
|
-
}
|
|
4162
|
-
async function cloneGitRepo(repo, dest, ref) {
|
|
4163
|
-
await runCommand("git", ["clone", "--depth", "1", repo, dest]);
|
|
4164
|
-
if (ref) {
|
|
4165
|
-
await runCommand("git", ["checkout", ref], { cwd: dest });
|
|
5475
|
+
if (entry.kind === "dir") {
|
|
5476
|
+
await fs7.promises.cp(entry.backupPath, entry.originalPath, { recursive: true, force: true });
|
|
5477
|
+
} else {
|
|
5478
|
+
await fs7.promises.copyFile(entry.backupPath, entry.originalPath);
|
|
4166
5479
|
}
|
|
5480
|
+
await removePath(entry.backupPath);
|
|
4167
5481
|
}
|
|
4168
|
-
function
|
|
4169
|
-
|
|
4170
|
-
|
|
4171
|
-
|
|
4172
|
-
|
|
4173
|
-
|
|
4174
|
-
return "url";
|
|
4175
|
-
return "local";
|
|
5482
|
+
async function backupExistingOriginals(entries, session) {
|
|
5483
|
+
for (const entry of entries) {
|
|
5484
|
+
if (!await pathExists(entry.originalPath))
|
|
5485
|
+
continue;
|
|
5486
|
+
await backupPath(entry.originalPath, session);
|
|
5487
|
+
}
|
|
4176
5488
|
}
|
|
4177
|
-
async function
|
|
4178
|
-
const
|
|
4179
|
-
const
|
|
4180
|
-
if (
|
|
4181
|
-
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
|
|
4185
|
-
|
|
4186
|
-
|
|
4187
|
-
|
|
4188
|
-
|
|
4189
|
-
|
|
4190
|
-
|
|
4191
|
-
|
|
4192
|
-
|
|
4193
|
-
|
|
4194
|
-
|
|
4195
|
-
|
|
4196
|
-
|
|
4197
|
-
|
|
4198
|
-
|
|
4199
|
-
|
|
4200
|
-
|
|
4201
|
-
|
|
4202
|
-
|
|
4203
|
-
}
|
|
4204
|
-
if (
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
|
|
4208
|
-
|
|
4209
|
-
|
|
4210
|
-
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
}
|
|
4215
|
-
throw new Error(`Unsupported source type: ${inferred}`);
|
|
5489
|
+
async function undoLastChange(opts) {
|
|
5490
|
+
const roots = resolveRoots(opts);
|
|
5491
|
+
const latest = await findLatestBackup(roots.canonicalRoot);
|
|
5492
|
+
if (!latest)
|
|
5493
|
+
throw new Error("No backups found to undo.");
|
|
5494
|
+
const undoSession = await createBackupSession({
|
|
5495
|
+
canonicalRoot: roots.canonicalRoot,
|
|
5496
|
+
scope: opts.scope,
|
|
5497
|
+
operation: "undo"
|
|
5498
|
+
});
|
|
5499
|
+
const entries = latest.manifest.entries || [];
|
|
5500
|
+
await backupExistingOriginals(entries, undoSession);
|
|
5501
|
+
let restored = 0;
|
|
5502
|
+
let restoredBackups = 0;
|
|
5503
|
+
let removedCreated = 0;
|
|
5504
|
+
let removedSymlinks = 0;
|
|
5505
|
+
for (const entry of entries) {
|
|
5506
|
+
if (entry.action === "create") {
|
|
5507
|
+
if (await pathExists(entry.originalPath)) {
|
|
5508
|
+
await restorePath(entry);
|
|
5509
|
+
restored += 1;
|
|
5510
|
+
removedCreated += 1;
|
|
5511
|
+
if (entry.kind === "symlink")
|
|
5512
|
+
removedSymlinks += 1;
|
|
5513
|
+
}
|
|
5514
|
+
continue;
|
|
5515
|
+
}
|
|
5516
|
+
if (!entry.backupPath)
|
|
5517
|
+
continue;
|
|
5518
|
+
if (!await pathExists(entry.backupPath))
|
|
5519
|
+
continue;
|
|
5520
|
+
await restorePath(entry);
|
|
5521
|
+
restored += 1;
|
|
5522
|
+
restoredBackups += 1;
|
|
5523
|
+
}
|
|
5524
|
+
await finalizeBackup(undoSession);
|
|
5525
|
+
return { restored, restoredBackups, removedCreated, removedSymlinks, backupDir: undoSession.dir, undoneDir: latest.dir };
|
|
4216
5526
|
}
|
|
4217
5527
|
|
|
4218
|
-
// src/
|
|
4219
|
-
|
|
5528
|
+
// src/core/preflight.ts
|
|
5529
|
+
import fs8 from "fs";
|
|
5530
|
+
import path11 from "path";
|
|
5531
|
+
async function needsLinkBackup(task, forceLinks) {
|
|
5532
|
+
if (task.type === "conflict")
|
|
5533
|
+
return forceLinks && task.target !== task.source;
|
|
5534
|
+
if (task.type !== "link")
|
|
5535
|
+
return false;
|
|
5536
|
+
if (!await pathExists(task.target))
|
|
5537
|
+
return false;
|
|
5538
|
+
if (forceLinks)
|
|
5539
|
+
return true;
|
|
5540
|
+
if (!task.replaceSymlink)
|
|
5541
|
+
return false;
|
|
4220
5542
|
try {
|
|
4221
|
-
const
|
|
4222
|
-
|
|
4223
|
-
const parts2 = url.pathname.split("/").filter(Boolean);
|
|
4224
|
-
if (parts2.length < 4)
|
|
4225
|
-
return null;
|
|
4226
|
-
const [owner2, repo2, ref2, ...rest2] = parts2;
|
|
4227
|
-
const filePath2 = rest2.join("/");
|
|
4228
|
-
const subdir2 = filePath2.toLowerCase().endsWith("skill.md") ? filePath2.split("/").slice(0, -1).join("/") : filePath2;
|
|
4229
|
-
return { repoUrl: `https://github.com/${owner2}/${repo2}.git`, ref: ref2, subdir: subdir2 };
|
|
4230
|
-
}
|
|
4231
|
-
if (url.hostname !== "github.com")
|
|
4232
|
-
return null;
|
|
4233
|
-
const parts = url.pathname.split("/").filter(Boolean);
|
|
4234
|
-
if (parts.length < 4)
|
|
4235
|
-
return null;
|
|
4236
|
-
const [owner, repo, kind, ref, ...rest] = parts;
|
|
4237
|
-
if (kind !== "blob" && kind !== "tree")
|
|
4238
|
-
return null;
|
|
4239
|
-
const filePath = rest.join("/");
|
|
4240
|
-
const subdir = filePath.toLowerCase().endsWith("skill.md") ? filePath.split("/").slice(0, -1).join("/") : filePath;
|
|
4241
|
-
return { repoUrl: `https://github.com/${owner}/${repo}.git`, ref, subdir };
|
|
5543
|
+
const stat = await fs8.promises.lstat(task.target);
|
|
5544
|
+
return stat.isSymbolicLink();
|
|
4242
5545
|
} catch {
|
|
4243
|
-
return
|
|
5546
|
+
return false;
|
|
4244
5547
|
}
|
|
4245
5548
|
}
|
|
4246
|
-
function
|
|
4247
|
-
|
|
4248
|
-
|
|
4249
|
-
|
|
4250
|
-
|
|
4251
|
-
|
|
4252
|
-
const dash = parts.indexOf("-");
|
|
4253
|
-
if (dash === -1)
|
|
4254
|
-
return null;
|
|
4255
|
-
const kind = parts[dash + 1];
|
|
4256
|
-
if (kind !== "blob" && kind !== "tree" && kind !== "raw")
|
|
4257
|
-
return null;
|
|
4258
|
-
const ref = parts[dash + 2];
|
|
4259
|
-
const rest = parts.slice(dash + 3).join("/");
|
|
4260
|
-
const namespacePath = parts.slice(0, dash).join("/");
|
|
4261
|
-
if (!namespacePath)
|
|
4262
|
-
return null;
|
|
4263
|
-
const subdir = rest.toLowerCase().endsWith("skill.md") ? rest.split("/").slice(0, -1).join("/") : rest;
|
|
4264
|
-
return { repoUrl: `https://gitlab.com/${namespacePath}.git`, ref, subdir };
|
|
4265
|
-
} catch {
|
|
4266
|
-
return null;
|
|
5549
|
+
function collectMigrationCandidates(plan, selections) {
|
|
5550
|
+
const candidates = [...plan.auto];
|
|
5551
|
+
for (const conflict of plan.conflicts) {
|
|
5552
|
+
const choice = selections.get(conflict.targetPath);
|
|
5553
|
+
if (choice && choice.action === "copy")
|
|
5554
|
+
candidates.push(choice);
|
|
4267
5555
|
}
|
|
5556
|
+
return candidates;
|
|
4268
5557
|
}
|
|
4269
|
-
function
|
|
4270
|
-
|
|
4271
|
-
|
|
4272
|
-
|
|
4273
|
-
|
|
4274
|
-
|
|
4275
|
-
|
|
4276
|
-
const
|
|
4277
|
-
const
|
|
4278
|
-
|
|
4279
|
-
|
|
4280
|
-
|
|
4281
|
-
|
|
4282
|
-
try {
|
|
4283
|
-
const stat = await fs8.promises.lstat(rootDir);
|
|
4284
|
-
if (stat.isFile()) {
|
|
4285
|
-
if (path13.basename(rootDir).toLowerCase() !== "skill.md") {
|
|
4286
|
-
throw new Error("Expected a skills folder or SKILL.md file");
|
|
4287
|
-
}
|
|
4288
|
-
rootDir = path13.dirname(rootDir);
|
|
4289
|
-
}
|
|
4290
|
-
} catch {}
|
|
4291
|
-
const skillDirs = await findSkillDirs(rootDir);
|
|
4292
|
-
if (!skillDirs.length)
|
|
4293
|
-
throw new Error("No SKILL.md found in source");
|
|
4294
|
-
const installed = [];
|
|
4295
|
-
const skipped = [];
|
|
4296
|
-
const metas = [];
|
|
4297
|
-
for (const dir of skillDirs) {
|
|
4298
|
-
const skillFile = path13.join(dir, "SKILL.md");
|
|
4299
|
-
const meta = await parseSkillFile(skillFile);
|
|
4300
|
-
metas.push(meta);
|
|
4301
|
-
const dest = skillDestDir(canonicalSkills, meta.name);
|
|
4302
|
-
const exists = await pathExists(dest);
|
|
4303
|
-
if (exists && !opts.force) {
|
|
4304
|
-
skipped.push(meta.name);
|
|
4305
|
-
continue;
|
|
4306
|
-
}
|
|
4307
|
-
await copyDir(dir, dest, true);
|
|
4308
|
-
installed.push(meta.name);
|
|
5558
|
+
async function preflightBackup(opts) {
|
|
5559
|
+
const targets = new Set;
|
|
5560
|
+
for (const task of opts.linkPlan.tasks) {
|
|
5561
|
+
if (await needsLinkBackup(task, opts.forceLinks)) {
|
|
5562
|
+
targets.add(path11.resolve(task.target));
|
|
5563
|
+
}
|
|
5564
|
+
}
|
|
5565
|
+
const migrationCandidates = collectMigrationCandidates(opts.migratePlan, opts.selections);
|
|
5566
|
+
for (const candidate of migrationCandidates) {
|
|
5567
|
+
if (!candidate.sourcePath)
|
|
5568
|
+
continue;
|
|
5569
|
+
if (await pathExists(candidate.targetPath)) {
|
|
5570
|
+
targets.add(path11.resolve(candidate.targetPath));
|
|
4309
5571
|
}
|
|
4310
|
-
return { installed, skipped, skills: metas };
|
|
4311
|
-
} finally {
|
|
4312
|
-
await resolved.cleanup();
|
|
4313
5572
|
}
|
|
5573
|
+
for (const target of targets) {
|
|
5574
|
+
const exists = await pathExists(target);
|
|
5575
|
+
if (!exists)
|
|
5576
|
+
continue;
|
|
5577
|
+
const stat = await fs8.promises.lstat(target);
|
|
5578
|
+
if (stat.isSymbolicLink()) {
|
|
5579
|
+
await fs8.promises.readlink(target);
|
|
5580
|
+
}
|
|
5581
|
+
const dest = backupPathFor(target, opts.backup.dir);
|
|
5582
|
+
await ensureDir(path11.dirname(dest));
|
|
5583
|
+
await fs8.promises.access(path11.dirname(dest), fs8.constants.W_OK);
|
|
5584
|
+
}
|
|
5585
|
+
return { targets: targets.size };
|
|
4314
5586
|
}
|
|
4315
5587
|
|
|
4316
|
-
// src/
|
|
4317
|
-
|
|
4318
|
-
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
const url = new URL(input);
|
|
4322
|
-
if (url.hostname !== "raw.githubusercontent.com")
|
|
4323
|
-
return null;
|
|
4324
|
-
const parts = url.pathname.split("/").filter(Boolean);
|
|
4325
|
-
if (parts.length < 4)
|
|
4326
|
-
return null;
|
|
4327
|
-
const [owner, repo, ref, ...rest] = parts;
|
|
4328
|
-
const filePath = rest.join("/");
|
|
4329
|
-
return { kind: "github", owner, repo, ref, basePath: path14.posix.dirname(filePath) };
|
|
4330
|
-
} catch {
|
|
4331
|
-
return null;
|
|
4332
|
-
}
|
|
5588
|
+
// src/cli.tsx
|
|
5589
|
+
var appTitle = "dotagents";
|
|
5590
|
+
function exitCancelled() {
|
|
5591
|
+
ue("Cancelled");
|
|
5592
|
+
process.exit(0);
|
|
4333
5593
|
}
|
|
4334
|
-
function
|
|
4335
|
-
|
|
4336
|
-
|
|
4337
|
-
|
|
4338
|
-
|
|
4339
|
-
|
|
4340
|
-
|
|
4341
|
-
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
|
|
4347
|
-
|
|
4348
|
-
|
|
4349
|
-
}
|
|
5594
|
+
function mergeAgentStatus(items) {
|
|
5595
|
+
const claudeEntry = items.find((s) => s.name === "claude-md") || null;
|
|
5596
|
+
const agentsEntry = items.find((s) => s.name === "agents-md") || null;
|
|
5597
|
+
if (!claudeEntry && !agentsEntry)
|
|
5598
|
+
return items;
|
|
5599
|
+
const merged = {
|
|
5600
|
+
name: "agents-md",
|
|
5601
|
+
source: claudeEntry?.source || agentsEntry?.source || "",
|
|
5602
|
+
targets: [
|
|
5603
|
+
...claudeEntry?.targets || [],
|
|
5604
|
+
...agentsEntry?.targets || []
|
|
5605
|
+
]
|
|
5606
|
+
};
|
|
5607
|
+
const withoutAgents = items.filter((s) => s.name !== "claude-md" && s.name !== "agents-md");
|
|
5608
|
+
return [merged, ...withoutAgents];
|
|
4350
5609
|
}
|
|
4351
|
-
|
|
4352
|
-
if (
|
|
4353
|
-
const
|
|
4354
|
-
|
|
4355
|
-
|
|
4356
|
-
|
|
4357
|
-
|
|
4358
|
-
|
|
4359
|
-
if (fs9.existsSync(resolved) && fs9.statSync(resolved).isDirectory()) {
|
|
4360
|
-
file = path14.join(resolved, ".claude-plugin", "marketplace.json");
|
|
4361
|
-
}
|
|
4362
|
-
if (!fs9.existsSync(file))
|
|
4363
|
-
throw new Error(`marketplace.json not found: ${file}`);
|
|
4364
|
-
const raw = await fs9.promises.readFile(file, "utf8");
|
|
4365
|
-
const json = JSON.parse(raw);
|
|
4366
|
-
return { json, context: { baseDir: path14.dirname(file) } };
|
|
5610
|
+
function displayName(entry) {
|
|
5611
|
+
if (entry.name === "agents-md") {
|
|
5612
|
+
const sourceFile = path12.basename(entry.source);
|
|
5613
|
+
if (sourceFile === "CLAUDE.md")
|
|
5614
|
+
return "AGENTS.md (Claude override)";
|
|
5615
|
+
return "AGENTS.md";
|
|
5616
|
+
}
|
|
5617
|
+
return entry.name;
|
|
4367
5618
|
}
|
|
4368
|
-
function
|
|
4369
|
-
|
|
4370
|
-
|
|
4371
|
-
|
|
4372
|
-
|
|
4373
|
-
|
|
4374
|
-
|
|
4375
|
-
const repoRoot = pluginRoot ? pluginRoot : "";
|
|
4376
|
-
const primary = path14.posix.normalize(path14.posix.join(repoRoot, entry.source));
|
|
4377
|
-
const candidates = [primary];
|
|
4378
|
-
if (ctx.basePath) {
|
|
4379
|
-
candidates.push(path14.posix.normalize(path14.posix.join(ctx.basePath, entry.source)));
|
|
4380
|
-
}
|
|
4381
|
-
return { source: `https://github.com/${ctx.owner}/${ctx.repo}.git`, type: "git", subdirCandidates: candidates, ref: ctx.ref };
|
|
4382
|
-
}
|
|
4383
|
-
const candidate = path14.resolve(root, entry.source);
|
|
4384
|
-
return { source: candidate, type: "local" };
|
|
4385
|
-
}
|
|
4386
|
-
const src = entry.source;
|
|
4387
|
-
if (src.source === "github" && src.repo) {
|
|
4388
|
-
return { source: `https://github.com/${src.repo}.git`, type: "git", ref: src.ref };
|
|
4389
|
-
}
|
|
4390
|
-
if (src.source === "git" && src.url) {
|
|
4391
|
-
return { source: src.url, type: "git", ref: src.ref };
|
|
4392
|
-
}
|
|
4393
|
-
if (src.source === "url" && src.url) {
|
|
4394
|
-
return { source: src.url, type: "url" };
|
|
4395
|
-
}
|
|
4396
|
-
throw new Error(`Unsupported plugin source for ${entry.name}`);
|
|
5619
|
+
function buildStatusSummary(status) {
|
|
5620
|
+
return status.map((s) => {
|
|
5621
|
+
const linked = s.targets.filter((t) => t.status === "linked").length;
|
|
5622
|
+
const missing = s.targets.filter((t) => t.status === "missing").length;
|
|
5623
|
+
const conflict = s.targets.filter((t) => t.status === "conflict").length;
|
|
5624
|
+
return { name: displayName(s), linked, missing, conflict };
|
|
5625
|
+
});
|
|
4397
5626
|
}
|
|
4398
|
-
|
|
4399
|
-
const
|
|
4400
|
-
const
|
|
4401
|
-
|
|
4402
|
-
|
|
4403
|
-
|
|
4404
|
-
|
|
4405
|
-
|
|
5627
|
+
function formatSummaryTable(rows) {
|
|
5628
|
+
const header = { name: "Section", conflict: "Conflicts", missing: "Need link", linked: "Linked" };
|
|
5629
|
+
const width = {
|
|
5630
|
+
name: Math.max(header.name.length, ...rows.map((r2) => r2.name.length)),
|
|
5631
|
+
conflict: Math.max(header.conflict.length, ...rows.map((r2) => String(r2.conflict).length)),
|
|
5632
|
+
missing: Math.max(header.missing.length, ...rows.map((r2) => String(r2.missing).length)),
|
|
5633
|
+
linked: Math.max(header.linked.length, ...rows.map((r2) => String(r2.linked).length))
|
|
5634
|
+
};
|
|
5635
|
+
const pad = (value, len) => value.padEnd(len, " ");
|
|
5636
|
+
const lines = [
|
|
5637
|
+
`${pad(header.name, width.name)} ${pad(header.conflict, width.conflict)} ${pad(header.missing, width.missing)} ${pad(header.linked, width.linked)}`,
|
|
5638
|
+
...rows.map((r2) => `${pad(r2.name, width.name)} ${pad(String(r2.conflict), width.conflict)} ${pad(String(r2.missing), width.missing)} ${pad(String(r2.linked), width.linked)}`)
|
|
5639
|
+
];
|
|
5640
|
+
return lines;
|
|
4406
5641
|
}
|
|
4407
|
-
|
|
4408
|
-
const
|
|
4409
|
-
const
|
|
4410
|
-
|
|
4411
|
-
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
|
|
4415
|
-
const selected = opts.plugins === "all" ? json.plugins : json.plugins.filter((p) => opts.plugins.includes(p.name));
|
|
4416
|
-
const installedCommands = [];
|
|
4417
|
-
const installedHooks = [];
|
|
4418
|
-
const installedSkills = [];
|
|
4419
|
-
const skippedCommands = [];
|
|
4420
|
-
const skippedHooks = [];
|
|
4421
|
-
const skippedSkills = [];
|
|
4422
|
-
for (const plugin of selected) {
|
|
4423
|
-
const { source, type, subdir, subdirCandidates, ref } = resolvePluginPath(plugin, context, json.pluginRoot);
|
|
4424
|
-
const resolved = await resolveSource(source, type, { ref });
|
|
4425
|
-
try {
|
|
4426
|
-
let pluginDir = resolved.dir;
|
|
4427
|
-
if (subdirCandidates && subdirCandidates.length) {
|
|
4428
|
-
const found = subdirCandidates.map((candidate) => path14.join(resolved.dir, candidate)).find((candidate) => fs9.existsSync(candidate));
|
|
4429
|
-
if (!found) {
|
|
4430
|
-
throw new Error(`Plugin path not found in repo: ${subdirCandidates.join(", ")}`);
|
|
4431
|
-
}
|
|
4432
|
-
pluginDir = found;
|
|
4433
|
-
} else if (subdir) {
|
|
4434
|
-
pluginDir = path14.join(resolved.dir, subdir);
|
|
4435
|
-
}
|
|
4436
|
-
const scan = await scanPluginDir(pluginDir);
|
|
4437
|
-
for (const cmd of scan.commands) {
|
|
4438
|
-
const name = path14.basename(cmd);
|
|
4439
|
-
const dest = path14.join(commandsDest, name);
|
|
4440
|
-
const result = await copyFile(cmd, dest, !!opts.force);
|
|
4441
|
-
if (result === "written")
|
|
4442
|
-
installedCommands.push(`${plugin.name}:${name}`);
|
|
4443
|
-
else
|
|
4444
|
-
skippedCommands.push(`${plugin.name}:${name}`);
|
|
4445
|
-
}
|
|
4446
|
-
for (const hook of scan.hooks) {
|
|
4447
|
-
const name = path14.basename(hook);
|
|
4448
|
-
const dest = path14.join(hooksDest, name);
|
|
4449
|
-
const result = await copyFile(hook, dest, !!opts.force);
|
|
4450
|
-
if (result === "written")
|
|
4451
|
-
installedHooks.push(`${plugin.name}:${name}`);
|
|
4452
|
-
else
|
|
4453
|
-
skippedHooks.push(`${plugin.name}:${name}`);
|
|
4454
|
-
}
|
|
4455
|
-
if (scan.skillsDir) {
|
|
4456
|
-
const skillResult = await installSkillsFromSource({
|
|
4457
|
-
source: scan.skillsDir,
|
|
4458
|
-
sourceType: "local",
|
|
4459
|
-
scope: opts.scope,
|
|
4460
|
-
projectRoot: opts.projectRoot,
|
|
4461
|
-
homeDir: opts.homeDir,
|
|
4462
|
-
force: opts.force
|
|
4463
|
-
});
|
|
4464
|
-
installedSkills.push(...skillResult.installed.map((n) => `${plugin.name}:${n}`));
|
|
4465
|
-
skippedSkills.push(...skillResult.skipped.map((n) => `${plugin.name}:${n}`));
|
|
4466
|
-
}
|
|
4467
|
-
} finally {
|
|
4468
|
-
await resolved.cleanup();
|
|
5642
|
+
function renderStatusLines(status, conflictReasons) {
|
|
5643
|
+
const lines = [];
|
|
5644
|
+
for (const entry of status) {
|
|
5645
|
+
lines.push(source_default.cyan(displayName(entry)));
|
|
5646
|
+
for (const target of entry.targets) {
|
|
5647
|
+
const icon = target.status === "linked" ? source_default.green("✓") : target.status === "missing" ? source_default.yellow("•") : source_default.red("⚠");
|
|
5648
|
+
const reason = target.status === "conflict" ? conflictReasons.get(target.path) : undefined;
|
|
5649
|
+
lines.push(` ${icon} ${target.path}${reason ? source_default.dim(` — ${reason}`) : ""}`);
|
|
4469
5650
|
}
|
|
4470
5651
|
}
|
|
4471
|
-
return
|
|
4472
|
-
installedCommands,
|
|
4473
|
-
installedHooks,
|
|
4474
|
-
installedSkills,
|
|
4475
|
-
skippedCommands,
|
|
4476
|
-
skippedHooks,
|
|
4477
|
-
skippedSkills
|
|
4478
|
-
};
|
|
4479
|
-
}
|
|
4480
|
-
|
|
4481
|
-
// src/tui/ui/HelpBar.tsx
|
|
4482
|
-
import { Box, Text } from "ink";
|
|
4483
|
-
import { jsxDEV } from "react/jsx-dev-runtime";
|
|
4484
|
-
function HelpBar({ text }) {
|
|
4485
|
-
return /* @__PURE__ */ jsxDEV(Box, {
|
|
4486
|
-
marginTop: 1,
|
|
4487
|
-
children: /* @__PURE__ */ jsxDEV(Text, {
|
|
4488
|
-
dimColor: true,
|
|
4489
|
-
children: text
|
|
4490
|
-
}, undefined, false, undefined, this)
|
|
4491
|
-
}, undefined, false, undefined, this);
|
|
5652
|
+
return lines;
|
|
4492
5653
|
}
|
|
4493
|
-
|
|
4494
|
-
|
|
4495
|
-
|
|
4496
|
-
|
|
4497
|
-
|
|
4498
|
-
|
|
4499
|
-
|
|
4500
|
-
|
|
4501
|
-
const max = Math.max(0, a.h - s.height);
|
|
4502
|
-
const nextScrollTop = Math.min(s.scrollTop, max);
|
|
4503
|
-
if (s.innerHeight === a.h && nextScrollTop === s.scrollTop)
|
|
4504
|
-
return s;
|
|
4505
|
-
return { ...s, innerHeight: a.h, scrollTop: nextScrollTop };
|
|
4506
|
-
}
|
|
4507
|
-
case "SET_HEIGHT": {
|
|
4508
|
-
const max = Math.max(0, s.innerHeight - a.h);
|
|
4509
|
-
const nextScrollTop = Math.min(s.scrollTop, max);
|
|
4510
|
-
if (s.height === a.h && nextScrollTop === s.scrollTop)
|
|
4511
|
-
return s;
|
|
4512
|
-
return { ...s, height: a.h, scrollTop: nextScrollTop };
|
|
4513
|
-
}
|
|
4514
|
-
case "SCROLL": {
|
|
4515
|
-
const max = Math.max(0, s.innerHeight - s.height);
|
|
4516
|
-
const nextScrollTop = Math.max(0, Math.min(max, s.scrollTop + a.delta));
|
|
4517
|
-
if (nextScrollTop === s.scrollTop)
|
|
4518
|
-
return s;
|
|
4519
|
-
return { ...s, scrollTop: nextScrollTop };
|
|
4520
|
-
}
|
|
4521
|
-
case "TOP": {
|
|
4522
|
-
if (s.scrollTop === 0)
|
|
4523
|
-
return s;
|
|
4524
|
-
return { ...s, scrollTop: 0 };
|
|
4525
|
-
}
|
|
4526
|
-
case "BOTTOM": {
|
|
4527
|
-
const max = Math.max(0, s.innerHeight - s.height);
|
|
4528
|
-
if (s.scrollTop === max)
|
|
4529
|
-
return s;
|
|
4530
|
-
return { ...s, scrollTop: max };
|
|
4531
|
-
}
|
|
4532
|
-
default:
|
|
4533
|
-
return s;
|
|
4534
|
-
}
|
|
4535
|
-
};
|
|
4536
|
-
function ScrollArea({ height, children }) {
|
|
4537
|
-
const innerRef = useRef(null);
|
|
4538
|
-
const { stdout } = useStdout();
|
|
4539
|
-
const [state, dispatch] = useReducer(reducer, { innerHeight: 0, height, scrollTop: 0 });
|
|
4540
|
-
useEffect(() => {
|
|
4541
|
-
dispatch({ type: "SET_HEIGHT", h: height });
|
|
4542
|
-
}, [height]);
|
|
4543
|
-
useEffect(() => {
|
|
4544
|
-
if (!innerRef.current)
|
|
4545
|
-
return;
|
|
4546
|
-
const dim = measureElement(innerRef.current);
|
|
4547
|
-
dispatch({ type: "SET_INNER", h: dim.height });
|
|
4548
|
-
});
|
|
4549
|
-
useEffect(() => {
|
|
4550
|
-
const onResize = () => dispatch({ type: "SET_HEIGHT", h: stdout.rows });
|
|
4551
|
-
return () => void onResize();
|
|
4552
|
-
}, [stdout]);
|
|
4553
|
-
useInput((input, key) => {
|
|
4554
|
-
if (key.pageDown || key.downArrow && key.meta)
|
|
4555
|
-
dispatch({ type: "SCROLL", delta: Math.max(1, Math.floor(state.height * 0.8)) });
|
|
4556
|
-
if (key.pageUp || key.upArrow && key.meta)
|
|
4557
|
-
dispatch({ type: "SCROLL", delta: -Math.max(1, Math.floor(state.height * 0.8)) });
|
|
4558
|
-
if (input === "g")
|
|
4559
|
-
dispatch({ type: "TOP" });
|
|
4560
|
-
if (input === "G")
|
|
4561
|
-
dispatch({ type: "BOTTOM" });
|
|
5654
|
+
async function selectScope() {
|
|
5655
|
+
const scope = await ie({
|
|
5656
|
+
message: "Choose a workspace",
|
|
5657
|
+
options: [
|
|
5658
|
+
{ label: "Global (~/.agents)", value: "global" },
|
|
5659
|
+
{ label: "Project (.agents)", value: "project" },
|
|
5660
|
+
{ label: "Exit", value: "exit" }
|
|
5661
|
+
]
|
|
4562
5662
|
});
|
|
4563
|
-
|
|
4564
|
-
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
|
|
4570
|
-
flexDirection: "column",
|
|
4571
|
-
marginTop: -state.scrollTop,
|
|
4572
|
-
children
|
|
4573
|
-
}, undefined, false, undefined, this)
|
|
4574
|
-
}, undefined, false, undefined, this);
|
|
5663
|
+
if (lD(scope))
|
|
5664
|
+
exitCancelled();
|
|
5665
|
+
if (scope === "exit") {
|
|
5666
|
+
$e("Bye");
|
|
5667
|
+
process.exit(0);
|
|
5668
|
+
}
|
|
5669
|
+
return scope;
|
|
4575
5670
|
}
|
|
4576
|
-
|
|
4577
|
-
|
|
4578
|
-
import { Box as Box3, useStdout as useStdout2 } from "ink";
|
|
4579
|
-
import { jsxDEV as jsxDEV3 } from "react/jsx-dev-runtime";
|
|
4580
|
-
function Screen({ children }) {
|
|
4581
|
-
const { stdout } = useStdout2();
|
|
4582
|
-
const height = stdout?.rows;
|
|
4583
|
-
return /* @__PURE__ */ jsxDEV3(Box3, {
|
|
4584
|
-
flexDirection: "column",
|
|
4585
|
-
height,
|
|
4586
|
-
children
|
|
4587
|
-
}, undefined, false, undefined, this);
|
|
5671
|
+
function scopeLabel(scope) {
|
|
5672
|
+
return scope === "global" ? "Global (~/.agents)" : "Project (.agents)";
|
|
4588
5673
|
}
|
|
4589
|
-
|
|
4590
|
-
|
|
4591
|
-
|
|
4592
|
-
|
|
4593
|
-
|
|
4594
|
-
|
|
4595
|
-
|
|
4596
|
-
const
|
|
4597
|
-
|
|
4598
|
-
|
|
4599
|
-
|
|
4600
|
-
|
|
4601
|
-
|
|
4602
|
-
|
|
4603
|
-
const
|
|
4604
|
-
|
|
4605
|
-
|
|
4606
|
-
|
|
4607
|
-
|
|
4608
|
-
const [showDetails, setShowDetails] = useState(false);
|
|
4609
|
-
const [conflictsOnly, setConflictsOnly] = useState(false);
|
|
4610
|
-
const { stdout } = useStdout3();
|
|
4611
|
-
useInput2((input, key) => {
|
|
4612
|
-
if (input === "q")
|
|
4613
|
-
exit();
|
|
4614
|
-
if (step === "status" && input === "d")
|
|
4615
|
-
setShowDetails((prev) => !prev);
|
|
4616
|
-
if (step === "status" && input === "c")
|
|
4617
|
-
setConflictsOnly(true);
|
|
4618
|
-
if (step === "status" && input === "a")
|
|
4619
|
-
setConflictsOnly(false);
|
|
4620
|
-
if (key.escape) {
|
|
4621
|
-
if (step === "action")
|
|
4622
|
-
return setStep("scope");
|
|
4623
|
-
if (step === "status")
|
|
4624
|
-
return setStep("action");
|
|
4625
|
-
if (step === "migrate-choice") {
|
|
4626
|
-
setMigratePlan(null);
|
|
4627
|
-
setMigrateSelections(new Map);
|
|
4628
|
-
return setStep("action");
|
|
4629
|
-
}
|
|
4630
|
-
if (step === "skill-source-type")
|
|
4631
|
-
return setStep("action");
|
|
4632
|
-
if (step === "skill-input")
|
|
4633
|
-
return setStep("skill-source-type");
|
|
4634
|
-
if (step === "plugin-marketplace-input")
|
|
4635
|
-
return setStep("action");
|
|
4636
|
-
if (step === "plugin-select")
|
|
4637
|
-
return setStep("plugin-marketplace-input");
|
|
4638
|
-
if (step === "done")
|
|
4639
|
-
return setStep("action");
|
|
4640
|
-
}
|
|
4641
|
-
if (step === "done" && key.return)
|
|
4642
|
-
setStep("action");
|
|
5674
|
+
function pluralize(count, singular, plural) {
|
|
5675
|
+
return count === 1 ? singular : plural || `${singular}s`;
|
|
5676
|
+
}
|
|
5677
|
+
function formatCount(count, singular, plural) {
|
|
5678
|
+
return `${count} ${pluralize(count, singular, plural)}`;
|
|
5679
|
+
}
|
|
5680
|
+
async function selectClients() {
|
|
5681
|
+
const options2 = [
|
|
5682
|
+
{ label: "Claude", value: "claude" },
|
|
5683
|
+
{ label: "Factory", value: "factory" },
|
|
5684
|
+
{ label: "Codex", value: "codex" },
|
|
5685
|
+
{ label: "Cursor", value: "cursor" },
|
|
5686
|
+
{ label: "OpenCode", value: "opencode" }
|
|
5687
|
+
];
|
|
5688
|
+
const selected = await ae({
|
|
5689
|
+
message: "Select clients to manage",
|
|
5690
|
+
options: options2.map((opt) => ({ label: opt.label, value: opt.value })),
|
|
5691
|
+
initialValues: options2.map((opt) => opt.value),
|
|
5692
|
+
required: true
|
|
4643
5693
|
});
|
|
4644
|
-
|
|
4645
|
-
|
|
4646
|
-
|
|
4647
|
-
|
|
4648
|
-
|
|
4649
|
-
|
|
4650
|
-
|
|
4651
|
-
|
|
4652
|
-
|
|
4653
|
-
|
|
4654
|
-
|
|
4655
|
-
const conflicts = plan?.conflicts.length || 0;
|
|
4656
|
-
const changes = plan?.changes.length || 0;
|
|
4657
|
-
const actionItems = useMemo(() => {
|
|
4658
|
-
const items = [
|
|
4659
|
-
{ label: "Apply/repair links", value: "apply" }
|
|
4660
|
-
];
|
|
4661
|
-
if (conflicts > 0)
|
|
4662
|
-
items.push({ label: "Force apply (overwrite conflicts)", value: "force-apply" });
|
|
4663
|
-
items.push({ label: "View status", value: "view-status" });
|
|
4664
|
-
items.push({ label: "Migrate existing content", value: "migrate" });
|
|
4665
|
-
items.push({ label: "Add skill", value: "add-skill" });
|
|
4666
|
-
items.push({ label: "Install plugin", value: "install-plugin" });
|
|
4667
|
-
items.push({ label: "Exit", value: "exit" });
|
|
4668
|
-
return items;
|
|
4669
|
-
}, [conflicts]);
|
|
4670
|
-
const displayName = (name) => {
|
|
4671
|
-
if (name === "agents-md")
|
|
4672
|
-
return "AGENTS.md";
|
|
4673
|
-
return name;
|
|
5694
|
+
if (lD(selected))
|
|
5695
|
+
exitCancelled();
|
|
5696
|
+
return selected;
|
|
5697
|
+
}
|
|
5698
|
+
function formatClients(clients) {
|
|
5699
|
+
const names = {
|
|
5700
|
+
claude: "Claude",
|
|
5701
|
+
factory: "Factory",
|
|
5702
|
+
codex: "Codex",
|
|
5703
|
+
cursor: "Cursor",
|
|
5704
|
+
opencode: "OpenCode"
|
|
4674
5705
|
};
|
|
4675
|
-
|
|
4676
|
-
|
|
4677
|
-
|
|
4678
|
-
|
|
4679
|
-
|
|
4680
|
-
|
|
5706
|
+
return clients.map((c) => names[c]).join(", ");
|
|
5707
|
+
}
|
|
5708
|
+
async function showStatus(scope, clients, status, planConflicts) {
|
|
5709
|
+
const conflicts = new Map(planConflicts.map((c) => [c.target, c.reason]));
|
|
5710
|
+
const lines = renderStatusLines(mergeAgentStatus(status), conflicts);
|
|
5711
|
+
le(lines.join(`
|
|
5712
|
+
`), `Status · ${scopeLabel(scope)} · ${formatClients(clients)}`);
|
|
5713
|
+
}
|
|
5714
|
+
async function resolveMigrationConflicts(plan) {
|
|
5715
|
+
const selections = new Map;
|
|
5716
|
+
for (let i = 0;i < plan.conflicts.length; i += 1) {
|
|
5717
|
+
const conflict = plan.conflicts[i];
|
|
5718
|
+
const choice = await ie({
|
|
5719
|
+
message: `Resolve migration conflict ${i + 1} of ${plan.conflicts.length}: ${conflict.label}`,
|
|
5720
|
+
options: conflict.candidates.map((c) => ({ label: c.label, value: c }))
|
|
4681
5721
|
});
|
|
4682
|
-
|
|
4683
|
-
|
|
4684
|
-
|
|
4685
|
-
|
|
4686
|
-
|
|
4687
|
-
|
|
4688
|
-
|
|
4689
|
-
|
|
4690
|
-
|
|
4691
|
-
|
|
4692
|
-
|
|
4693
|
-
|
|
4694
|
-
|
|
4695
|
-
|
|
4696
|
-
|
|
4697
|
-
|
|
4698
|
-
|
|
4699
|
-
|
|
4700
|
-
|
|
4701
|
-
|
|
4702
|
-
|
|
4703
|
-
|
|
4704
|
-
|
|
4705
|
-
|
|
4706
|
-
|
|
4707
|
-
const
|
|
4708
|
-
|
|
4709
|
-
|
|
4710
|
-
|
|
4711
|
-
|
|
4712
|
-
|
|
4713
|
-
try {
|
|
4714
|
-
const stat = await fs10.promises.lstat(task.target);
|
|
4715
|
-
if (stat.isDirectory() && !stat.isSymbolicLink()) {
|
|
4716
|
-
const entries = await fs10.promises.readdir(task.target);
|
|
4717
|
-
const shown = entries.slice(0, 6);
|
|
4718
|
-
const more = entries.length > 6 ? `… +${entries.length - 6} more` : "";
|
|
4719
|
-
const contents = entries.length === 0 ? "(empty)" : `${shown.join(", ")}${more ? `, ${more}` : ""}`;
|
|
4720
|
-
map.set(task.target, { reason: task.reason, contents: `Contains: ${contents}` });
|
|
4721
|
-
}
|
|
4722
|
-
} catch {}
|
|
4723
|
-
}
|
|
4724
|
-
if (!cancelled)
|
|
4725
|
-
setConflictDetails(map);
|
|
4726
|
-
};
|
|
4727
|
-
load();
|
|
4728
|
-
return () => {
|
|
4729
|
-
cancelled = true;
|
|
4730
|
-
};
|
|
4731
|
-
}, [plan]);
|
|
4732
|
-
const renderStatusList = () => {
|
|
4733
|
-
const sections = status.map((s) => {
|
|
4734
|
-
const targets = conflictsOnly ? s.targets.filter((t) => t.status === "conflict") : s.targets;
|
|
4735
|
-
if (conflictsOnly && targets.length === 0)
|
|
4736
|
-
return null;
|
|
4737
|
-
return /* @__PURE__ */ jsxDEV4(Box4, {
|
|
4738
|
-
flexDirection: "column",
|
|
4739
|
-
marginTop: 1,
|
|
4740
|
-
children: [
|
|
4741
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
4742
|
-
color: "cyan",
|
|
4743
|
-
children: displayName(s.name)
|
|
4744
|
-
}, undefined, false, undefined, this),
|
|
4745
|
-
targets.map((t) => /* @__PURE__ */ jsxDEV4(Box4, {
|
|
4746
|
-
flexDirection: "column",
|
|
4747
|
-
children: [
|
|
4748
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
4749
|
-
children: [
|
|
4750
|
-
t.status === "linked" ? "✓" : t.status === "missing" ? "•" : "⚠",
|
|
4751
|
-
" ",
|
|
4752
|
-
t.path
|
|
4753
|
-
]
|
|
4754
|
-
}, undefined, true, undefined, this),
|
|
4755
|
-
showDetails && t.status === "conflict" && conflictDetails.has(t.path) ? /* @__PURE__ */ jsxDEV4(Fragment, {
|
|
4756
|
-
children: [
|
|
4757
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
4758
|
-
color: "red",
|
|
4759
|
-
children: [
|
|
4760
|
-
" ",
|
|
4761
|
-
conflictDetails.get(t.path)?.reason
|
|
4762
|
-
]
|
|
4763
|
-
}, undefined, true, undefined, this),
|
|
4764
|
-
conflictDetails.get(t.path)?.contents ? /* @__PURE__ */ jsxDEV4(Text2, {
|
|
4765
|
-
dimColor: true,
|
|
4766
|
-
children: [
|
|
4767
|
-
" ",
|
|
4768
|
-
conflictDetails.get(t.path)?.contents
|
|
4769
|
-
]
|
|
4770
|
-
}, undefined, true, undefined, this) : null
|
|
4771
|
-
]
|
|
4772
|
-
}, undefined, true, undefined, this) : null
|
|
4773
|
-
]
|
|
4774
|
-
}, t.path, true, undefined, this))
|
|
4775
|
-
]
|
|
4776
|
-
}, s.name, true, undefined, this);
|
|
4777
|
-
}).filter(Boolean);
|
|
4778
|
-
if (!sections.length) {
|
|
4779
|
-
return /* @__PURE__ */ jsxDEV4(Box4, {
|
|
4780
|
-
marginTop: 1,
|
|
4781
|
-
children: /* @__PURE__ */ jsxDEV4(Text2, {
|
|
4782
|
-
dimColor: true,
|
|
4783
|
-
children: "No conflicts found."
|
|
4784
|
-
}, undefined, false, undefined, this)
|
|
4785
|
-
}, undefined, false, undefined, this);
|
|
4786
|
-
}
|
|
4787
|
-
return /* @__PURE__ */ jsxDEV4(Box4, {
|
|
4788
|
-
flexDirection: "column",
|
|
4789
|
-
children: sections
|
|
4790
|
-
}, undefined, false, undefined, this);
|
|
4791
|
-
};
|
|
4792
|
-
if (step === "scope") {
|
|
4793
|
-
return /* @__PURE__ */ jsxDEV4(Screen, {
|
|
4794
|
-
children: [
|
|
4795
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
4796
|
-
color: "green",
|
|
4797
|
-
children: appTitle
|
|
4798
|
-
}, undefined, false, undefined, this),
|
|
4799
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
4800
|
-
children: "Choose a workspace:"
|
|
4801
|
-
}, undefined, false, undefined, this),
|
|
4802
|
-
/* @__PURE__ */ jsxDEV4(SelectInput, {
|
|
4803
|
-
items: [
|
|
4804
|
-
{ label: "Global home", value: "global" },
|
|
4805
|
-
{ label: "Project folder", value: "project" },
|
|
4806
|
-
{ label: "Exit", value: "exit" }
|
|
4807
|
-
],
|
|
4808
|
-
onSelect: (item) => {
|
|
4809
|
-
if (item.value === "exit")
|
|
4810
|
-
return exit();
|
|
4811
|
-
setScope(item.value);
|
|
4812
|
-
setStep("action");
|
|
4813
|
-
}
|
|
4814
|
-
}, undefined, false, undefined, this)
|
|
4815
|
-
]
|
|
4816
|
-
}, undefined, true, undefined, this);
|
|
4817
|
-
}
|
|
4818
|
-
if (step === "action") {
|
|
4819
|
-
return /* @__PURE__ */ jsxDEV4(Screen, {
|
|
4820
|
-
children: [
|
|
4821
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
4822
|
-
color: "green",
|
|
4823
|
-
children: appTitle
|
|
4824
|
-
}, undefined, false, undefined, this),
|
|
4825
|
-
/* @__PURE__ */ jsxDEV4(Box4, {
|
|
4826
|
-
flexDirection: "column",
|
|
4827
|
-
marginTop: 1,
|
|
4828
|
-
children: [
|
|
4829
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
4830
|
-
children: [
|
|
4831
|
-
"Scope: ",
|
|
4832
|
-
scopeLabel
|
|
4833
|
-
]
|
|
4834
|
-
}, undefined, true, undefined, this),
|
|
4835
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
4836
|
-
children: [
|
|
4837
|
-
"Pending changes: ",
|
|
4838
|
-
changes,
|
|
4839
|
-
" · Conflicts: ",
|
|
4840
|
-
conflicts
|
|
4841
|
-
]
|
|
4842
|
-
}, undefined, true, undefined, this),
|
|
4843
|
-
summaryTable.map((line) => /* @__PURE__ */ jsxDEV4(Text2, {
|
|
4844
|
-
children: line
|
|
4845
|
-
}, line, false, undefined, this))
|
|
4846
|
-
]
|
|
4847
|
-
}, undefined, true, undefined, this),
|
|
4848
|
-
/* @__PURE__ */ jsxDEV4(Box4, {
|
|
4849
|
-
marginTop: 1,
|
|
4850
|
-
flexDirection: "column",
|
|
4851
|
-
children: [
|
|
4852
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
4853
|
-
children: "Choose an action:"
|
|
4854
|
-
}, undefined, false, undefined, this),
|
|
4855
|
-
/* @__PURE__ */ jsxDEV4(SelectInput, {
|
|
4856
|
-
items: actionItems,
|
|
4857
|
-
onSelect: (item) => {
|
|
4858
|
-
if (item.value === "exit")
|
|
4859
|
-
return exit();
|
|
4860
|
-
if (item.value === "view-status") {
|
|
4861
|
-
setStep("status");
|
|
4862
|
-
return;
|
|
4863
|
-
}
|
|
4864
|
-
if (item.value === "migrate") {
|
|
4865
|
-
if (!scope)
|
|
4866
|
-
return;
|
|
4867
|
-
setBusy("Scanning existing content...");
|
|
4868
|
-
setStep("applying");
|
|
4869
|
-
(async () => {
|
|
4870
|
-
try {
|
|
4871
|
-
const plan2 = await scanMigration({ scope });
|
|
4872
|
-
setMigratePlan(plan2);
|
|
4873
|
-
setMigrateIndex(0);
|
|
4874
|
-
setMigrateSelections(new Map);
|
|
4875
|
-
if (plan2.conflicts.length > 0) {
|
|
4876
|
-
setBusy(null);
|
|
4877
|
-
setStep("migrate-choice");
|
|
4878
|
-
return;
|
|
4879
|
-
}
|
|
4880
|
-
setBusy("Migrating...");
|
|
4881
|
-
const result = await applyMigration(plan2, new Map, { scope });
|
|
4882
|
-
setMessage(`Migrated ${result.copied} items. Backup: ${result.backupDir}`);
|
|
4883
|
-
await refreshStatus(scope);
|
|
4884
|
-
setStep("done");
|
|
4885
|
-
} catch (err) {
|
|
4886
|
-
setMessage(err?.message || String(err));
|
|
4887
|
-
setStep("done");
|
|
4888
|
-
} finally {
|
|
4889
|
-
setBusy(null);
|
|
4890
|
-
}
|
|
4891
|
-
})();
|
|
4892
|
-
return;
|
|
4893
|
-
}
|
|
4894
|
-
if (item.value === "apply" || item.value === "force-apply") {
|
|
4895
|
-
setBusy(item.value === "force-apply" ? "Applying (force)..." : "Applying...");
|
|
4896
|
-
setStep("applying");
|
|
4897
|
-
(async () => {
|
|
4898
|
-
try {
|
|
4899
|
-
if (!plan || !scope)
|
|
4900
|
-
return;
|
|
4901
|
-
const result = await applyLinkPlan(plan, { force: item.value === "force-apply" });
|
|
4902
|
-
setMessage(`Applied: ${result.applied}, Skipped: ${result.skipped}, Conflicts: ${result.conflicts}`);
|
|
4903
|
-
await refreshStatus(scope);
|
|
4904
|
-
} catch (err) {
|
|
4905
|
-
setMessage(err?.message || String(err));
|
|
4906
|
-
} finally {
|
|
4907
|
-
setBusy(null);
|
|
4908
|
-
setStep("done");
|
|
4909
|
-
}
|
|
4910
|
-
})();
|
|
4911
|
-
return;
|
|
4912
|
-
}
|
|
4913
|
-
if (item.value === "add-skill") {
|
|
4914
|
-
setSkillInput("");
|
|
4915
|
-
setStep("skill-source-type");
|
|
4916
|
-
return;
|
|
4917
|
-
}
|
|
4918
|
-
if (item.value === "install-plugin") {
|
|
4919
|
-
setMarketplaceInput("");
|
|
4920
|
-
setStep("plugin-marketplace-input");
|
|
4921
|
-
return;
|
|
4922
|
-
}
|
|
4923
|
-
}
|
|
4924
|
-
}, undefined, false, undefined, this),
|
|
4925
|
-
/* @__PURE__ */ jsxDEV4(HelpBar, {
|
|
4926
|
-
text: "Use ↑↓ to navigate, Enter to select, Esc to go back, q to quit"
|
|
4927
|
-
}, undefined, false, undefined, this)
|
|
4928
|
-
]
|
|
4929
|
-
}, undefined, true, undefined, this)
|
|
4930
|
-
]
|
|
4931
|
-
}, undefined, true, undefined, this);
|
|
4932
|
-
}
|
|
4933
|
-
if (step === "status") {
|
|
4934
|
-
const listHeight = Math.max(6, (stdout?.rows ?? 24) - 8);
|
|
4935
|
-
return /* @__PURE__ */ jsxDEV4(Screen, {
|
|
4936
|
-
children: [
|
|
4937
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
4938
|
-
color: "green",
|
|
4939
|
-
children: appTitle
|
|
4940
|
-
}, undefined, false, undefined, this),
|
|
4941
|
-
/* @__PURE__ */ jsxDEV4(Box4, {
|
|
4942
|
-
flexDirection: "column",
|
|
4943
|
-
marginTop: 1,
|
|
4944
|
-
children: [
|
|
4945
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
4946
|
-
children: [
|
|
4947
|
-
"Scope: ",
|
|
4948
|
-
scopeLabel
|
|
4949
|
-
]
|
|
4950
|
-
}, undefined, true, undefined, this),
|
|
4951
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
4952
|
-
children: [
|
|
4953
|
-
"Pending changes: ",
|
|
4954
|
-
changes,
|
|
4955
|
-
" · Conflicts: ",
|
|
4956
|
-
conflicts
|
|
4957
|
-
]
|
|
4958
|
-
}, undefined, true, undefined, this),
|
|
4959
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
4960
|
-
dimColor: true,
|
|
4961
|
-
children: "Legend: ✓ linked • need link ⚠ conflict"
|
|
4962
|
-
}, undefined, false, undefined, this),
|
|
4963
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
4964
|
-
dimColor: true,
|
|
4965
|
-
children: [
|
|
4966
|
-
"Mode: ",
|
|
4967
|
-
conflictsOnly ? "Conflicts only" : "All",
|
|
4968
|
-
" · Details: ",
|
|
4969
|
-
showDetails ? "On" : "Off"
|
|
4970
|
-
]
|
|
4971
|
-
}, undefined, true, undefined, this)
|
|
4972
|
-
]
|
|
4973
|
-
}, undefined, true, undefined, this),
|
|
4974
|
-
/* @__PURE__ */ jsxDEV4(ScrollArea, {
|
|
4975
|
-
height: listHeight,
|
|
4976
|
-
children: renderStatusList()
|
|
4977
|
-
}, undefined, false, undefined, this),
|
|
4978
|
-
/* @__PURE__ */ jsxDEV4(HelpBar, {
|
|
4979
|
-
text: "d: details · c: conflicts only · a: show all · Esc: back · q: quit"
|
|
4980
|
-
}, undefined, false, undefined, this)
|
|
4981
|
-
]
|
|
4982
|
-
}, undefined, true, undefined, this);
|
|
4983
|
-
}
|
|
4984
|
-
if (step === "migrate-choice" && migratePlan) {
|
|
4985
|
-
const conflict = migratePlan.conflicts[migrateIndex];
|
|
4986
|
-
if (!conflict) {
|
|
4987
|
-
return /* @__PURE__ */ jsxDEV4(Screen, {
|
|
4988
|
-
children: [
|
|
4989
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
4990
|
-
color: "green",
|
|
4991
|
-
children: appTitle
|
|
4992
|
-
}, undefined, false, undefined, this),
|
|
4993
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
4994
|
-
dimColor: true,
|
|
4995
|
-
children: "No conflicts to resolve."
|
|
4996
|
-
}, undefined, false, undefined, this),
|
|
4997
|
-
/* @__PURE__ */ jsxDEV4(HelpBar, {
|
|
4998
|
-
text: "Esc: back · q: quit"
|
|
4999
|
-
}, undefined, false, undefined, this)
|
|
5000
|
-
]
|
|
5001
|
-
}, undefined, true, undefined, this);
|
|
5002
|
-
}
|
|
5003
|
-
const items = conflict.candidates.map((c) => ({
|
|
5004
|
-
label: c.label,
|
|
5005
|
-
value: c
|
|
5006
|
-
}));
|
|
5007
|
-
return /* @__PURE__ */ jsxDEV4(Screen, {
|
|
5008
|
-
children: [
|
|
5009
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5010
|
-
color: "green",
|
|
5011
|
-
children: appTitle
|
|
5012
|
-
}, undefined, false, undefined, this),
|
|
5013
|
-
/* @__PURE__ */ jsxDEV4(Box4, {
|
|
5014
|
-
flexDirection: "column",
|
|
5015
|
-
marginTop: 1,
|
|
5016
|
-
children: [
|
|
5017
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5018
|
-
children: [
|
|
5019
|
-
"Resolve conflict ",
|
|
5020
|
-
migrateIndex + 1,
|
|
5021
|
-
" of ",
|
|
5022
|
-
migratePlan.conflicts.length
|
|
5023
|
-
]
|
|
5024
|
-
}, undefined, true, undefined, this),
|
|
5025
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5026
|
-
dimColor: true,
|
|
5027
|
-
children: conflict.label
|
|
5028
|
-
}, undefined, false, undefined, this)
|
|
5029
|
-
]
|
|
5030
|
-
}, undefined, true, undefined, this),
|
|
5031
|
-
/* @__PURE__ */ jsxDEV4(Box4, {
|
|
5032
|
-
marginTop: 1,
|
|
5033
|
-
flexDirection: "column",
|
|
5034
|
-
children: [
|
|
5035
|
-
/* @__PURE__ */ jsxDEV4(SelectInput, {
|
|
5036
|
-
items,
|
|
5037
|
-
onSelect: (item) => {
|
|
5038
|
-
if (!scope)
|
|
5039
|
-
return;
|
|
5040
|
-
const next = new Map(migrateSelections);
|
|
5041
|
-
next.set(conflict.targetPath, item.value);
|
|
5042
|
-
setMigrateSelections(next);
|
|
5043
|
-
if (migrateIndex + 1 < migratePlan.conflicts.length) {
|
|
5044
|
-
setMigrateIndex(migrateIndex + 1);
|
|
5045
|
-
return;
|
|
5046
|
-
}
|
|
5047
|
-
setBusy("Migrating...");
|
|
5048
|
-
setStep("applying");
|
|
5049
|
-
(async () => {
|
|
5050
|
-
try {
|
|
5051
|
-
const result = await applyMigration(migratePlan, next, { scope });
|
|
5052
|
-
setMessage(`Migrated ${result.copied} items. Backup: ${result.backupDir}`);
|
|
5053
|
-
await refreshStatus(scope);
|
|
5054
|
-
} catch (err) {
|
|
5055
|
-
setMessage(err?.message || String(err));
|
|
5056
|
-
} finally {
|
|
5057
|
-
setBusy(null);
|
|
5058
|
-
setMigratePlan(null);
|
|
5059
|
-
setMigrateIndex(0);
|
|
5060
|
-
setMigrateSelections(new Map);
|
|
5061
|
-
setStep("done");
|
|
5062
|
-
}
|
|
5063
|
-
})();
|
|
5064
|
-
}
|
|
5065
|
-
}, undefined, false, undefined, this),
|
|
5066
|
-
/* @__PURE__ */ jsxDEV4(HelpBar, {
|
|
5067
|
-
text: "Use ↑↓ to choose, Enter to select, Esc to cancel"
|
|
5068
|
-
}, undefined, false, undefined, this)
|
|
5069
|
-
]
|
|
5070
|
-
}, undefined, true, undefined, this)
|
|
5071
|
-
]
|
|
5072
|
-
}, undefined, true, undefined, this);
|
|
5073
|
-
}
|
|
5074
|
-
if (step === "applying") {
|
|
5075
|
-
return /* @__PURE__ */ jsxDEV4(Screen, {
|
|
5076
|
-
children: /* @__PURE__ */ jsxDEV4(Text2, {
|
|
5077
|
-
color: "yellow",
|
|
5078
|
-
children: [
|
|
5079
|
-
/* @__PURE__ */ jsxDEV4(Spinner, {
|
|
5080
|
-
type: "dots"
|
|
5081
|
-
}, undefined, false, undefined, this),
|
|
5082
|
-
" ",
|
|
5083
|
-
busy || "Working..."
|
|
5084
|
-
]
|
|
5085
|
-
}, undefined, true, undefined, this)
|
|
5086
|
-
}, undefined, false, undefined, this);
|
|
5087
|
-
}
|
|
5088
|
-
if (step === "skill-source-type") {
|
|
5089
|
-
return /* @__PURE__ */ jsxDEV4(Screen, {
|
|
5090
|
-
children: [
|
|
5091
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5092
|
-
children: "Select skill source type:"
|
|
5093
|
-
}, undefined, false, undefined, this),
|
|
5094
|
-
/* @__PURE__ */ jsxDEV4(SelectInput, {
|
|
5095
|
-
items: [
|
|
5096
|
-
{ label: "Local path", value: "local" },
|
|
5097
|
-
{ label: "URL", value: "url" },
|
|
5098
|
-
{ label: "Back", value: "back" }
|
|
5099
|
-
],
|
|
5100
|
-
onSelect: (item) => {
|
|
5101
|
-
if (item.value === "back") {
|
|
5102
|
-
setStep("action");
|
|
5103
|
-
return;
|
|
5104
|
-
}
|
|
5105
|
-
setSkillType(item.value);
|
|
5106
|
-
setStep("skill-input");
|
|
5107
|
-
}
|
|
5108
|
-
}, undefined, false, undefined, this),
|
|
5109
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5110
|
-
dimColor: true,
|
|
5111
|
-
children: "Press Esc to go back, or q to quit."
|
|
5112
|
-
}, undefined, false, undefined, this)
|
|
5113
|
-
]
|
|
5114
|
-
}, undefined, true, undefined, this);
|
|
5115
|
-
}
|
|
5116
|
-
if (step === "skill-input") {
|
|
5117
|
-
return /* @__PURE__ */ jsxDEV4(Screen, {
|
|
5118
|
-
children: [
|
|
5119
|
-
skillType === "local" ? /* @__PURE__ */ jsxDEV4(Fragment, {
|
|
5120
|
-
children: [
|
|
5121
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5122
|
-
children: "Paste a skills folder path and we’ll install all skills inside."
|
|
5123
|
-
}, undefined, false, undefined, this),
|
|
5124
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5125
|
-
children: "Or paste a SKILL.md file and we’ll install the full skill."
|
|
5126
|
-
}, undefined, false, undefined, this)
|
|
5127
|
-
]
|
|
5128
|
-
}, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV4(Fragment, {
|
|
5129
|
-
children: [
|
|
5130
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5131
|
-
children: "Paste a skills folder URL and we’ll fetch all skills inside."
|
|
5132
|
-
}, undefined, false, undefined, this),
|
|
5133
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5134
|
-
children: "Or paste a SKILL.md URL and we’ll install the full skill."
|
|
5135
|
-
}, undefined, false, undefined, this)
|
|
5136
|
-
]
|
|
5137
|
-
}, undefined, true, undefined, this),
|
|
5138
|
-
/* @__PURE__ */ jsxDEV4(TextInput, {
|
|
5139
|
-
value: skillInput,
|
|
5140
|
-
onChange: setSkillInput,
|
|
5141
|
-
onSubmit: () => {
|
|
5142
|
-
if (!scope)
|
|
5143
|
-
return;
|
|
5144
|
-
setBusy("Installing skill(s)...");
|
|
5145
|
-
setStep("applying");
|
|
5146
|
-
(async () => {
|
|
5147
|
-
try {
|
|
5148
|
-
const result = await installSkillsFromSource({
|
|
5149
|
-
source: skillInput,
|
|
5150
|
-
sourceType: skillType,
|
|
5151
|
-
scope
|
|
5152
|
-
});
|
|
5153
|
-
setMessage(`Installed: ${result.installed.join(", ") || "none"} · Skipped: ${result.skipped.join(", ") || "none"}`);
|
|
5154
|
-
await refreshStatus(scope);
|
|
5155
|
-
} catch (err) {
|
|
5156
|
-
setMessage(err?.message || String(err));
|
|
5157
|
-
} finally {
|
|
5158
|
-
setBusy(null);
|
|
5159
|
-
setStep("done");
|
|
5160
|
-
}
|
|
5161
|
-
})();
|
|
5162
|
-
}
|
|
5163
|
-
}, undefined, false, undefined, this),
|
|
5164
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5165
|
-
dimColor: true,
|
|
5166
|
-
children: "Press Enter to continue, Esc to go back, or q to quit."
|
|
5167
|
-
}, undefined, false, undefined, this)
|
|
5168
|
-
]
|
|
5169
|
-
}, undefined, true, undefined, this);
|
|
5170
|
-
}
|
|
5171
|
-
if (step === "plugin-marketplace-input") {
|
|
5172
|
-
return /* @__PURE__ */ jsxDEV4(Screen, {
|
|
5173
|
-
children: [
|
|
5174
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5175
|
-
children: "Enter marketplace path or URL:"
|
|
5176
|
-
}, undefined, false, undefined, this),
|
|
5177
|
-
/* @__PURE__ */ jsxDEV4(TextInput, {
|
|
5178
|
-
value: marketplaceInput,
|
|
5179
|
-
onChange: setMarketplaceInput,
|
|
5180
|
-
onSubmit: () => {
|
|
5181
|
-
if (!scope)
|
|
5182
|
-
return;
|
|
5183
|
-
setBusy("Loading marketplace...");
|
|
5184
|
-
setStep("applying");
|
|
5185
|
-
(async () => {
|
|
5186
|
-
try {
|
|
5187
|
-
const loaded = await loadMarketplace(marketplaceInput);
|
|
5188
|
-
const plugins = loaded.json.plugins.map((p) => p.name);
|
|
5189
|
-
setMarketplacePlugins(plugins);
|
|
5190
|
-
setBusy(null);
|
|
5191
|
-
setStep("plugin-select");
|
|
5192
|
-
} catch (err) {
|
|
5193
|
-
setMessage(err?.message || String(err));
|
|
5194
|
-
setBusy(null);
|
|
5195
|
-
setStep("done");
|
|
5196
|
-
}
|
|
5197
|
-
})();
|
|
5198
|
-
}
|
|
5199
|
-
}, undefined, false, undefined, this),
|
|
5200
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5201
|
-
dimColor: true,
|
|
5202
|
-
children: "Press Enter to continue, Esc to go back, or q to quit."
|
|
5203
|
-
}, undefined, false, undefined, this)
|
|
5204
|
-
]
|
|
5205
|
-
}, undefined, true, undefined, this);
|
|
5206
|
-
}
|
|
5207
|
-
if (step === "plugin-select") {
|
|
5208
|
-
return /* @__PURE__ */ jsxDEV4(Screen, {
|
|
5209
|
-
children: [
|
|
5210
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5211
|
-
children: "Select plugin to install:"
|
|
5212
|
-
}, undefined, false, undefined, this),
|
|
5213
|
-
/* @__PURE__ */ jsxDEV4(SelectInput, {
|
|
5214
|
-
items: [
|
|
5215
|
-
{ label: "All plugins", value: "all" },
|
|
5216
|
-
...marketplacePlugins.map((p) => ({ label: p, value: p })),
|
|
5217
|
-
{ label: "Back", value: "back" }
|
|
5218
|
-
],
|
|
5219
|
-
onSelect: (item) => {
|
|
5220
|
-
if (!scope)
|
|
5221
|
-
return;
|
|
5222
|
-
if (item.value === "back") {
|
|
5223
|
-
setStep("action");
|
|
5224
|
-
return;
|
|
5225
|
-
}
|
|
5226
|
-
setBusy("Installing plugin(s)...");
|
|
5227
|
-
setStep("applying");
|
|
5228
|
-
(async () => {
|
|
5229
|
-
try {
|
|
5230
|
-
const result = await installMarketplace({
|
|
5231
|
-
marketplace: marketplaceInput,
|
|
5232
|
-
plugins: item.value === "all" ? "all" : [String(item.value)],
|
|
5233
|
-
scope
|
|
5234
|
-
});
|
|
5235
|
-
setMessage(`Installed commands: ${result.installedCommands.length}, hooks: ${result.installedHooks.length}, skills: ${result.installedSkills.length}`);
|
|
5236
|
-
await refreshStatus(scope);
|
|
5237
|
-
} catch (err) {
|
|
5238
|
-
setMessage(err?.message || String(err));
|
|
5239
|
-
} finally {
|
|
5240
|
-
setBusy(null);
|
|
5241
|
-
setStep("done");
|
|
5242
|
-
}
|
|
5243
|
-
})();
|
|
5244
|
-
}
|
|
5245
|
-
}, undefined, false, undefined, this),
|
|
5246
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5247
|
-
dimColor: true,
|
|
5248
|
-
children: "Press Esc to go back, or q to quit."
|
|
5249
|
-
}, undefined, false, undefined, this)
|
|
5250
|
-
]
|
|
5251
|
-
}, undefined, true, undefined, this);
|
|
5252
|
-
}
|
|
5253
|
-
if (step === "done") {
|
|
5254
|
-
return /* @__PURE__ */ jsxDEV4(Screen, {
|
|
5255
|
-
children: [
|
|
5256
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5257
|
-
children: message || "Done."
|
|
5258
|
-
}, undefined, false, undefined, this),
|
|
5259
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5260
|
-
dimColor: true,
|
|
5261
|
-
children: "Press Enter to continue, Esc to go back, or q to quit."
|
|
5262
|
-
}, undefined, false, undefined, this)
|
|
5722
|
+
if (lD(choice))
|
|
5723
|
+
return null;
|
|
5724
|
+
selections.set(conflict.targetPath, choice);
|
|
5725
|
+
}
|
|
5726
|
+
return selections;
|
|
5727
|
+
}
|
|
5728
|
+
async function runChange(scope, clients) {
|
|
5729
|
+
const spin = de();
|
|
5730
|
+
spin.start("Scanning current setup...");
|
|
5731
|
+
const roots = resolveRoots({ scope });
|
|
5732
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
5733
|
+
const migrate = await scanMigration({ scope, clients });
|
|
5734
|
+
const link = await buildLinkPlan({ scope, clients });
|
|
5735
|
+
const backupDir = path12.join(roots.canonicalRoot, "backup", timestamp);
|
|
5736
|
+
spin.stop("Scan complete");
|
|
5737
|
+
const planSummary = [
|
|
5738
|
+
`Migration: ${migrate.auto.length} auto · ${migrate.conflicts.length} conflicts (choose sources)`,
|
|
5739
|
+
`Links: ${link.changes.length} changes · ${link.conflicts.length} conflicts (existing files/dirs)`,
|
|
5740
|
+
`Backup: ${backupDir}`,
|
|
5741
|
+
'Undo: Use "Undo last change" after this completes.'
|
|
5742
|
+
].join(`
|
|
5743
|
+
`);
|
|
5744
|
+
le(planSummary, "Plan summary");
|
|
5745
|
+
let overwriteConflicts = true;
|
|
5746
|
+
if (link.conflicts.length > 0) {
|
|
5747
|
+
const choice = await ie({
|
|
5748
|
+
message: "Apply changes",
|
|
5749
|
+
options: [
|
|
5750
|
+
{ label: "Apply changes + overwrite conflicts", value: "force" },
|
|
5751
|
+
{ label: "Apply changes (leave conflicts)", value: "skip" },
|
|
5752
|
+
{ label: "Back", value: "back" }
|
|
5263
5753
|
]
|
|
5264
|
-
}
|
|
5754
|
+
});
|
|
5755
|
+
if (lD(choice))
|
|
5756
|
+
return;
|
|
5757
|
+
if (choice === "back")
|
|
5758
|
+
return;
|
|
5759
|
+
overwriteConflicts = choice === "force";
|
|
5760
|
+
} else {
|
|
5761
|
+
const ok = await se({ message: "Apply changes now?" });
|
|
5762
|
+
if (lD(ok) || !ok)
|
|
5763
|
+
return;
|
|
5265
5764
|
}
|
|
5266
|
-
|
|
5267
|
-
|
|
5268
|
-
|
|
5269
|
-
|
|
5270
|
-
|
|
5271
|
-
|
|
5765
|
+
let selections = new Map;
|
|
5766
|
+
if (migrate.conflicts.length > 0) {
|
|
5767
|
+
const resolved = await resolveMigrationConflicts(migrate);
|
|
5768
|
+
if (!resolved)
|
|
5769
|
+
return;
|
|
5770
|
+
selections = resolved;
|
|
5771
|
+
}
|
|
5772
|
+
const applySpinner = de();
|
|
5773
|
+
applySpinner.start("Applying changes...");
|
|
5774
|
+
try {
|
|
5775
|
+
const backup = await createBackupSession({
|
|
5776
|
+
canonicalRoot: roots.canonicalRoot,
|
|
5777
|
+
scope,
|
|
5778
|
+
operation: "change-to-agents",
|
|
5779
|
+
timestamp
|
|
5780
|
+
});
|
|
5781
|
+
await preflightBackup({
|
|
5782
|
+
backup,
|
|
5783
|
+
linkPlan: link,
|
|
5784
|
+
migratePlan: migrate,
|
|
5785
|
+
selections,
|
|
5786
|
+
forceLinks: overwriteConflicts
|
|
5787
|
+
});
|
|
5788
|
+
const result = await applyMigration(migrate, selections, { scope, clients, backup, forceLinks: overwriteConflicts });
|
|
5789
|
+
await finalizeBackup(backup);
|
|
5790
|
+
const migrationSummary = `Migrated ${formatCount(result.copied, "item")}`;
|
|
5791
|
+
const linkSummary = `Linked ${formatCount(result.links.applied, "path")}`;
|
|
5792
|
+
const conflictSummary = result.links.conflicts > 0 ? overwriteConflicts ? `overwrote ${formatCount(result.links.conflicts, "conflict")}` : `left ${formatCount(result.links.conflicts, "conflict")} untouched` : "";
|
|
5793
|
+
const pieces = [migrationSummary, linkSummary];
|
|
5794
|
+
if (conflictSummary)
|
|
5795
|
+
pieces.push(conflictSummary);
|
|
5796
|
+
applySpinner.stop(`${pieces.join(" · ")}. Backup: ${result.backupDir}`);
|
|
5797
|
+
} catch (err) {
|
|
5798
|
+
applySpinner.stop("Change failed");
|
|
5799
|
+
le(String(err?.message || err), "Error");
|
|
5800
|
+
}
|
|
5801
|
+
}
|
|
5802
|
+
async function run() {
|
|
5803
|
+
oe(source_default.cyan(appTitle));
|
|
5804
|
+
const scope = await selectScope();
|
|
5805
|
+
let clients = await selectClients();
|
|
5806
|
+
while (true) {
|
|
5807
|
+
const status = mergeAgentStatus(await getLinkStatus({ scope, clients }));
|
|
5808
|
+
const plan = await buildLinkPlan({ scope, clients });
|
|
5809
|
+
const conflicts = plan.conflicts.length || 0;
|
|
5810
|
+
const changes = plan.changes.length || 0;
|
|
5811
|
+
const summary = buildStatusSummary(status);
|
|
5812
|
+
const summaryLines = formatSummaryTable(summary);
|
|
5813
|
+
le([
|
|
5814
|
+
`Scope: ${scopeLabel(scope)}`,
|
|
5815
|
+
`Clients: ${formatClients(clients)}`,
|
|
5816
|
+
`Pending changes: ${changes} · Conflicts: ${conflicts}`,
|
|
5817
|
+
...summaryLines
|
|
5818
|
+
].join(`
|
|
5819
|
+
`), "Overview");
|
|
5820
|
+
const options2 = [];
|
|
5821
|
+
if (changes > 0)
|
|
5822
|
+
options2.push({ label: `Apply ${changes} changes to .agents`, value: "change" });
|
|
5823
|
+
options2.push({ label: "View status", value: "status" });
|
|
5824
|
+
options2.push({ label: "Change clients", value: "clients" });
|
|
5825
|
+
options2.push({ label: "Undo last change", value: "undo" });
|
|
5826
|
+
options2.push({ label: "Exit", value: "exit" });
|
|
5827
|
+
const action = await ie({ message: "Choose an action", options: options2 });
|
|
5828
|
+
if (lD(action))
|
|
5829
|
+
exitCancelled();
|
|
5830
|
+
if (action === "exit")
|
|
5831
|
+
break;
|
|
5832
|
+
if (action === "status") {
|
|
5833
|
+
await showStatus(scope, clients, status, plan.conflicts);
|
|
5834
|
+
continue;
|
|
5835
|
+
}
|
|
5836
|
+
if (action === "clients") {
|
|
5837
|
+
clients = await selectClients();
|
|
5838
|
+
continue;
|
|
5839
|
+
}
|
|
5840
|
+
if (action === "undo") {
|
|
5841
|
+
const spin = de();
|
|
5842
|
+
spin.start("Undoing last change...");
|
|
5843
|
+
try {
|
|
5844
|
+
const result = await undoLastChange({ scope });
|
|
5845
|
+
const restoredSummary = `Restored ${formatCount(result.restoredBackups, "backup")}`;
|
|
5846
|
+
const removedSummary = `Removed ${formatCount(result.removedCreated, "created path")}`;
|
|
5847
|
+
const symlinkSummary = result.removedSymlinks > 0 ? `${formatCount(result.removedSymlinks, "symlink")} removed` : "";
|
|
5848
|
+
let totalSummary = "";
|
|
5849
|
+
if (result.restoredBackups === 0 && result.removedCreated === 0) {
|
|
5850
|
+
totalSummary = "Nothing to undo.";
|
|
5851
|
+
} else if (result.restoredBackups === 0) {
|
|
5852
|
+
totalSummary = [removedSummary, symlinkSummary, "No backups to restore."].filter(Boolean).join(" · ");
|
|
5853
|
+
} else {
|
|
5854
|
+
totalSummary = [restoredSummary, removedSummary, symlinkSummary].filter(Boolean).join(" · ");
|
|
5855
|
+
}
|
|
5856
|
+
spin.stop(`${totalSummary} Reverted: ${result.undoneDir}`);
|
|
5857
|
+
le(`Undo backup: ${result.backupDir}`, "Undo log");
|
|
5858
|
+
} catch (err) {
|
|
5859
|
+
spin.stop("Undo failed");
|
|
5860
|
+
le(String(err?.message || err), "Error");
|
|
5861
|
+
}
|
|
5862
|
+
continue;
|
|
5863
|
+
}
|
|
5864
|
+
if (action === "change") {
|
|
5865
|
+
await runChange(scope, clients);
|
|
5866
|
+
}
|
|
5867
|
+
}
|
|
5868
|
+
$e("Bye");
|
|
5869
|
+
}
|
|
5870
|
+
run().catch((err) => {
|
|
5871
|
+
le(String(err?.message || err), "Fatal error");
|
|
5872
|
+
process.exit(1);
|
|
5873
|
+
});
|