@iannuttall/dotagents 0.1.1 → 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 +30 -8
- package/dist/cli.js +2117 -1673
- 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,361 +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 path15 from "path";
|
|
3502
|
-
import { Box as Box4, Text as Text2, useApp, useInput as useInput2, useStdout as useStdout3 } from "ink";
|
|
3503
|
-
import SelectInput from "ink-select-input";
|
|
3504
|
-
import TextInput from "ink-text-input";
|
|
3505
|
-
import Spinner from "ink-spinner";
|
|
3506
|
-
|
|
3507
|
-
// src/core/plan.ts
|
|
3508
|
-
import fs2 from "fs";
|
|
3509
|
-
import path4 from "path";
|
|
3510
|
-
|
|
3511
|
-
// src/core/mappings.ts
|
|
3512
|
-
import path2 from "path";
|
|
3624
|
+
import path12 from "path";
|
|
3513
3625
|
|
|
3514
|
-
//
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
|
|
3518
|
-
|
|
3519
|
-
|
|
3520
|
-
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
|
|
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]
|
|
3529
3682
|
}
|
|
3530
|
-
|
|
3531
|
-
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
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
|
|
3550
3754
|
},
|
|
3551
|
-
{
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
|
|
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
|
|
3560
3788
|
},
|
|
3561
|
-
{
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
targets: [
|
|
3565
|
-
path2.join(roots.claudeRoot, "hooks"),
|
|
3566
|
-
path2.join(roots.factoryRoot, "hooks")
|
|
3567
|
-
],
|
|
3568
|
-
kind: "dir"
|
|
3789
|
+
rgbToAnsi: {
|
|
3790
|
+
value: (red, green, blue) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)),
|
|
3791
|
+
enumerable: false
|
|
3569
3792
|
},
|
|
3570
|
-
{
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
targets: [
|
|
3574
|
-
path2.join(roots.claudeRoot, "skills"),
|
|
3575
|
-
path2.join(roots.factoryRoot, "skills"),
|
|
3576
|
-
path2.join(roots.codexRoot, "skills")
|
|
3577
|
-
],
|
|
3578
|
-
kind: "dir"
|
|
3793
|
+
hexToAnsi: {
|
|
3794
|
+
value: (hex) => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)),
|
|
3795
|
+
enumerable: false
|
|
3579
3796
|
}
|
|
3580
|
-
|
|
3797
|
+
});
|
|
3798
|
+
return styles;
|
|
3581
3799
|
}
|
|
3800
|
+
var ansiStyles = assembleStyles();
|
|
3801
|
+
var ansi_styles_default = ansiStyles;
|
|
3582
3802
|
|
|
3583
|
-
//
|
|
3584
|
-
import
|
|
3585
|
-
import
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
return false;
|
|
3593
|
-
throw err;
|
|
3594
|
-
}
|
|
3595
|
-
}
|
|
3596
|
-
async function ensureDir(dir) {
|
|
3597
|
-
await fs.promises.mkdir(dir, { recursive: true });
|
|
3598
|
-
}
|
|
3599
|
-
async function ensureFile(filePath, content) {
|
|
3600
|
-
await ensureDir(path3.dirname(filePath));
|
|
3601
|
-
await fs.promises.writeFile(filePath, content, "utf8");
|
|
3602
|
-
}
|
|
3603
|
-
async function readText(filePath) {
|
|
3604
|
-
return await fs.promises.readFile(filePath, "utf8");
|
|
3605
|
-
}
|
|
3606
|
-
async function copyFile(src, dest, force = false) {
|
|
3607
|
-
if (!force && await pathExists(dest))
|
|
3608
|
-
return "skipped";
|
|
3609
|
-
await ensureDir(path3.dirname(dest));
|
|
3610
|
-
await fs.promises.copyFile(src, dest);
|
|
3611
|
-
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);
|
|
3612
3812
|
}
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
|
|
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;
|
|
3619
3819
|
}
|
|
3620
|
-
|
|
3621
|
-
if (
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
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);
|
|
3628
3829
|
}
|
|
3629
3830
|
}
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
|
|
3633
|
-
return entries.filter((e) => e.isFile()).map((e) => path3.join(dir, e.name));
|
|
3634
|
-
} catch (err) {
|
|
3635
|
-
if (err && err.code === "ENOENT")
|
|
3636
|
-
return [];
|
|
3637
|
-
throw err;
|
|
3831
|
+
function translateLevel(level) {
|
|
3832
|
+
if (level === 0) {
|
|
3833
|
+
return false;
|
|
3638
3834
|
}
|
|
3835
|
+
return {
|
|
3836
|
+
level,
|
|
3837
|
+
hasBasic: true,
|
|
3838
|
+
has256: level >= 2,
|
|
3839
|
+
has16m: level >= 3
|
|
3840
|
+
};
|
|
3639
3841
|
}
|
|
3640
|
-
|
|
3641
|
-
const
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
async function listDirs(dir) {
|
|
3645
|
-
try {
|
|
3646
|
-
const entries = await fs.promises.readdir(dir, { withFileTypes: true });
|
|
3647
|
-
return entries.filter((e) => e.isDirectory()).map((e) => path3.join(dir, e.name));
|
|
3648
|
-
} catch (err) {
|
|
3649
|
-
if (err && err.code === "ENOENT")
|
|
3650
|
-
return [];
|
|
3651
|
-
throw err;
|
|
3842
|
+
function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
|
|
3843
|
+
const noFlagForceColor = envForceColor();
|
|
3844
|
+
if (noFlagForceColor !== undefined) {
|
|
3845
|
+
flagForceColor = noFlagForceColor;
|
|
3652
3846
|
}
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
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;
|
|
3661
3857
|
}
|
|
3662
|
-
return link;
|
|
3663
|
-
} catch {
|
|
3664
|
-
return null;
|
|
3665
3858
|
}
|
|
3666
|
-
|
|
3667
|
-
|
|
3668
|
-
const exists = await pathExists(source);
|
|
3669
|
-
if (!exists)
|
|
3670
|
-
return [{ type: "ensure-source", path: source, kind }];
|
|
3671
|
-
const stat = await fs2.promises.lstat(source);
|
|
3672
|
-
if (kind === "file" && stat.isDirectory()) {
|
|
3673
|
-
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;
|
|
3674
3861
|
}
|
|
3675
|
-
if (
|
|
3676
|
-
return
|
|
3862
|
+
if (haveStream && !streamIsTTY && forceColor === undefined) {
|
|
3863
|
+
return 0;
|
|
3677
3864
|
}
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
if (
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
3686
|
-
const resolved = await getLinkTargetAbsolute(target);
|
|
3687
|
-
if (resolved && path4.resolve(resolved) === path4.resolve(source)) {
|
|
3688
|
-
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;
|
|
3689
3873
|
}
|
|
3690
|
-
|
|
3691
|
-
return { type: "conflict", source, target, reason: detail, kind };
|
|
3874
|
+
return 1;
|
|
3692
3875
|
}
|
|
3693
|
-
|
|
3694
|
-
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
|
|
3698
|
-
|
|
3699
|
-
for (const mapping of mappings) {
|
|
3700
|
-
tasks.push(...await ensureSourceTask(mapping.source, mapping.kind));
|
|
3701
|
-
for (const target of mapping.targets) {
|
|
3702
|
-
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;
|
|
3703
3882
|
}
|
|
3883
|
+
return min;
|
|
3704
3884
|
}
|
|
3705
|
-
|
|
3706
|
-
|
|
3707
|
-
|
|
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);
|
|
3708
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;
|
|
3709
3934
|
|
|
3710
|
-
//
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
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
|
+
}
|
|
3714
3967
|
|
|
3715
|
-
|
|
3716
|
-
|
|
3717
|
-
|
|
3718
|
-
|
|
3719
|
-
|
|
3720
|
-
|
|
3721
|
-
|
|
3722
|
-
|
|
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);
|
|
3723
3995
|
}
|
|
3724
|
-
|
|
3725
|
-
|
|
3726
|
-
|
|
3727
|
-
|
|
3728
|
-
|
|
3729
|
-
|
|
3730
|
-
|
|
3731
|
-
const segment = splitPaths[0]?.[i];
|
|
3732
|
-
if (!segment)
|
|
3733
|
-
break;
|
|
3734
|
-
if (splitPaths.every((parts) => parts[i] === segment)) {
|
|
3735
|
-
shared.push(segment);
|
|
3736
|
-
} else {
|
|
3737
|
-
break;
|
|
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;
|
|
3738
4003
|
}
|
|
3739
|
-
}
|
|
3740
|
-
if (shared.length === 0)
|
|
3741
|
-
return null;
|
|
3742
|
-
if (shared[0] === "")
|
|
3743
|
-
return path5.sep + shared.slice(1).join(path5.sep);
|
|
3744
|
-
return shared.join(path5.sep);
|
|
3745
|
-
}
|
|
3746
|
-
function inferBackupDir(plan) {
|
|
3747
|
-
const sourceDirs = plan.tasks.map((task) => task.type === "ensure-source" ? task.path : task.source).filter(Boolean).map((p) => path5.dirname(p));
|
|
3748
|
-
const root = commonPath(sourceDirs);
|
|
3749
|
-
if (!root)
|
|
3750
|
-
return null;
|
|
3751
|
-
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
3752
|
-
return path5.join(root, "backup", timestamp);
|
|
4004
|
+
};
|
|
3753
4005
|
}
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
|
|
3759
|
-
return false;
|
|
3760
|
-
const root = path5.parse(target).root || path5.sep;
|
|
3761
|
-
const rel = path5.relative(root, target);
|
|
3762
|
-
const dest = path5.join(backupDir, rel);
|
|
3763
|
-
await ensureDir(path5.dirname(dest));
|
|
3764
|
-
try {
|
|
3765
|
-
await fs3.promises.rename(target, dest);
|
|
3766
|
-
return true;
|
|
3767
|
-
} catch (err) {
|
|
3768
|
-
if (err?.code !== "EXDEV")
|
|
3769
|
-
throw err;
|
|
4006
|
+
styles2.visible = {
|
|
4007
|
+
get() {
|
|
4008
|
+
const builder = createBuilder(this, this[STYLER], true);
|
|
4009
|
+
Object.defineProperty(this, "visible", { value: builder });
|
|
4010
|
+
return builder;
|
|
3770
4011
|
}
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
|
|
3774
|
-
|
|
4012
|
+
};
|
|
4013
|
+
var getModelAnsi = (model, level, type, ...arguments_) => {
|
|
4014
|
+
if (model === "rgb") {
|
|
4015
|
+
if (level === "ansi16m") {
|
|
4016
|
+
return ansi_styles_default[type].ansi16m(...arguments_);
|
|
4017
|
+
}
|
|
4018
|
+
if (level === "ansi256") {
|
|
4019
|
+
return ansi_styles_default[type].ansi256(ansi_styles_default.rgbToAnsi256(...arguments_));
|
|
4020
|
+
}
|
|
4021
|
+
return ansi_styles_default[type].ansi(ansi_styles_default.rgbToAnsi(...arguments_));
|
|
3775
4022
|
}
|
|
3776
|
-
|
|
3777
|
-
|
|
3778
|
-
}
|
|
3779
|
-
async function createLink(source, target, kind, force, backupDir) {
|
|
3780
|
-
if (await pathExists(target)) {
|
|
3781
|
-
if (!force)
|
|
3782
|
-
return { created: false, backedUp: false };
|
|
3783
|
-
const backedUp = backupDir ? await backupTarget(target, backupDir) : false;
|
|
3784
|
-
await removePath(target);
|
|
3785
|
-
await ensureDir(path5.dirname(target));
|
|
3786
|
-
const type2 = kind === "dir" ? "junction" : "file";
|
|
3787
|
-
await fs3.promises.symlink(source, target, type2);
|
|
3788
|
-
return { created: true, backedUp };
|
|
4023
|
+
if (model === "hex") {
|
|
4024
|
+
return getModelAnsi("rgb", level, type, ...ansi_styles_default.hexToRgb(...arguments_));
|
|
3789
4025
|
}
|
|
3790
|
-
|
|
3791
|
-
|
|
3792
|
-
|
|
3793
|
-
|
|
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
|
+
};
|
|
4037
|
+
}
|
|
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
|
+
};
|
|
4047
|
+
}
|
|
4048
|
+
};
|
|
3794
4049
|
}
|
|
3795
|
-
|
|
3796
|
-
|
|
3797
|
-
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
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)
|
|
3811
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;
|
|
3812
4191
|
}
|
|
3813
|
-
|
|
3814
|
-
|
|
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);
|
|
3815
4257
|
continue;
|
|
3816
4258
|
}
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
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);
|
|
3820
4282
|
continue;
|
|
3821
4283
|
}
|
|
3822
|
-
if (
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
3826
|
-
|
|
3827
|
-
|
|
3828
|
-
|
|
3829
|
-
|
|
3830
|
-
|
|
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;
|
|
3831
4424
|
}
|
|
3832
4425
|
}
|
|
3833
|
-
|
|
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 };
|
|
3834
4947
|
}
|
|
3835
4948
|
|
|
3836
4949
|
// src/core/status.ts
|
|
3837
|
-
import
|
|
3838
|
-
import
|
|
4950
|
+
import fs3 from "fs";
|
|
4951
|
+
import path5 from "path";
|
|
3839
4952
|
async function resolveLinkTarget(targetPath) {
|
|
3840
4953
|
try {
|
|
3841
|
-
const link = await
|
|
3842
|
-
if (!
|
|
3843
|
-
return
|
|
4954
|
+
const link = await fs3.promises.readlink(targetPath);
|
|
4955
|
+
if (!path5.isAbsolute(link))
|
|
4956
|
+
return path5.resolve(path5.dirname(targetPath), link);
|
|
3844
4957
|
return link;
|
|
3845
4958
|
} catch {
|
|
3846
4959
|
return null;
|
|
3847
4960
|
}
|
|
3848
4961
|
}
|
|
3849
4962
|
async function getLinkStatus(opts) {
|
|
3850
|
-
const mappings = getMappings(opts);
|
|
4963
|
+
const mappings = await getMappings(opts);
|
|
3851
4964
|
const statuses = [];
|
|
3852
4965
|
for (const mapping of mappings) {
|
|
3853
4966
|
const targets = [];
|
|
@@ -3857,10 +4970,10 @@ async function getLinkStatus(opts) {
|
|
|
3857
4970
|
targets.push({ path: target, status: "missing" });
|
|
3858
4971
|
continue;
|
|
3859
4972
|
}
|
|
3860
|
-
const stat = await
|
|
4973
|
+
const stat = await fs3.promises.lstat(target);
|
|
3861
4974
|
if (stat.isSymbolicLink()) {
|
|
3862
4975
|
const resolved = await resolveLinkTarget(target);
|
|
3863
|
-
if (resolved &&
|
|
4976
|
+
if (resolved && path5.resolve(resolved) === path5.resolve(mapping.source)) {
|
|
3864
4977
|
targets.push({ path: target, status: "linked" });
|
|
3865
4978
|
} else {
|
|
3866
4979
|
targets.push({ path: target, status: "conflict" });
|
|
@@ -3875,12 +4988,12 @@ async function getLinkStatus(opts) {
|
|
|
3875
4988
|
}
|
|
3876
4989
|
|
|
3877
4990
|
// src/core/migrate.ts
|
|
3878
|
-
import
|
|
3879
|
-
import
|
|
4991
|
+
import fs6 from "fs";
|
|
4992
|
+
import path9 from "path";
|
|
3880
4993
|
|
|
3881
4994
|
// src/core/skills.ts
|
|
3882
4995
|
var import_gray_matter = __toESM(require_gray_matter(), 1);
|
|
3883
|
-
import
|
|
4996
|
+
import path6 from "path";
|
|
3884
4997
|
var NAME_RE = /^[a-z0-9-]{1,64}$/;
|
|
3885
4998
|
async function parseSkillFile(skillFile) {
|
|
3886
4999
|
const raw = await readText(skillFile);
|
|
@@ -3902,13 +5015,13 @@ async function parseSkillFile(skillFile) {
|
|
|
3902
5015
|
};
|
|
3903
5016
|
}
|
|
3904
5017
|
async function isSkillDir(dir) {
|
|
3905
|
-
return await pathExists(
|
|
5018
|
+
return await pathExists(path6.join(dir, "SKILL.md"));
|
|
3906
5019
|
}
|
|
3907
5020
|
async function findSkillDirs(root) {
|
|
3908
5021
|
const direct = await isSkillDir(root);
|
|
3909
5022
|
if (direct)
|
|
3910
5023
|
return [root];
|
|
3911
|
-
const skillsDir =
|
|
5024
|
+
const skillsDir = path6.join(root, "skills");
|
|
3912
5025
|
const skillsDirExists = await pathExists(skillsDir);
|
|
3913
5026
|
if (skillsDirExists) {
|
|
3914
5027
|
const children2 = await listDirs(skillsDir);
|
|
@@ -3917,87 +5030,267 @@ async function findSkillDirs(root) {
|
|
|
3917
5030
|
if (await isSkillDir(child))
|
|
3918
5031
|
matches2.push(child);
|
|
3919
5032
|
}
|
|
3920
|
-
if (matches2.length)
|
|
3921
|
-
return matches2;
|
|
3922
|
-
}
|
|
3923
|
-
const children = await listDirs(root);
|
|
3924
|
-
const matches = [];
|
|
3925
|
-
for (const child of children) {
|
|
3926
|
-
if (await isSkillDir(child))
|
|
3927
|
-
matches.push(child);
|
|
5033
|
+
if (matches2.length)
|
|
5034
|
+
return matches2;
|
|
5035
|
+
}
|
|
5036
|
+
const children = await listDirs(root);
|
|
5037
|
+
const matches = [];
|
|
5038
|
+
for (const child of children) {
|
|
5039
|
+
if (await isSkillDir(child))
|
|
5040
|
+
matches.push(child);
|
|
5041
|
+
}
|
|
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 };
|
|
5175
|
+
}
|
|
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
|
+
}
|
|
3928
5227
|
}
|
|
3929
|
-
return
|
|
3930
|
-
}
|
|
3931
|
-
function skillDestDir(canonicalSkillsRoot, name) {
|
|
3932
|
-
return path7.join(canonicalSkillsRoot, name);
|
|
5228
|
+
return { applied, skipped, conflicts, backupDir: backup.dir, backedUp };
|
|
3933
5229
|
}
|
|
3934
5230
|
|
|
3935
5231
|
// src/core/migrate.ts
|
|
3936
5232
|
async function isSymlink(p) {
|
|
3937
5233
|
try {
|
|
3938
|
-
const stat = await
|
|
5234
|
+
const stat = await fs6.promises.lstat(p);
|
|
3939
5235
|
return stat.isSymbolicLink();
|
|
3940
5236
|
} catch {
|
|
3941
5237
|
return false;
|
|
3942
5238
|
}
|
|
3943
5239
|
}
|
|
3944
|
-
async function
|
|
5240
|
+
async function listFiles(dir) {
|
|
3945
5241
|
try {
|
|
3946
|
-
const entries = await
|
|
3947
|
-
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));
|
|
3948
5244
|
} catch {
|
|
3949
5245
|
return [];
|
|
3950
5246
|
}
|
|
3951
5247
|
}
|
|
3952
|
-
async function movePath(src, dest, kind) {
|
|
3953
|
-
await ensureDir(path8.dirname(dest));
|
|
3954
|
-
try {
|
|
3955
|
-
await fs5.promises.rename(src, dest);
|
|
3956
|
-
return;
|
|
3957
|
-
} catch (err) {
|
|
3958
|
-
if (err?.code !== "EXDEV")
|
|
3959
|
-
throw err;
|
|
3960
|
-
}
|
|
3961
|
-
if (kind === "file") {
|
|
3962
|
-
await copyFile(src, dest, true);
|
|
3963
|
-
} else {
|
|
3964
|
-
await copyDir(src, dest, true);
|
|
3965
|
-
}
|
|
3966
|
-
await removePath(src);
|
|
3967
|
-
}
|
|
3968
5248
|
function conflictLabel(targetPath, canonicalRoot) {
|
|
3969
5249
|
if (targetPath.startsWith(canonicalRoot)) {
|
|
3970
|
-
const rel =
|
|
3971
|
-
return rel ||
|
|
5250
|
+
const rel = path9.relative(canonicalRoot, targetPath);
|
|
5251
|
+
return rel || path9.basename(targetPath);
|
|
3972
5252
|
}
|
|
3973
|
-
return
|
|
5253
|
+
return path9.basename(targetPath);
|
|
3974
5254
|
}
|
|
3975
5255
|
async function scanMigration(opts) {
|
|
3976
5256
|
const roots = resolveRoots(opts);
|
|
3977
5257
|
const canonicalRoot = roots.canonicalRoot;
|
|
3978
5258
|
const candidatesByTarget = new Map;
|
|
3979
|
-
const
|
|
3980
|
-
const
|
|
3981
|
-
const
|
|
3982
|
-
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");
|
|
3983
5266
|
const sources = {
|
|
3984
5267
|
commands: [
|
|
3985
|
-
{ label: "Claude commands", dir:
|
|
3986
|
-
{ label: "Factory commands", dir:
|
|
3987
|
-
{ label: "Codex prompts", dir:
|
|
3988
|
-
|
|
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),
|
|
3989
5274
|
hooks: [
|
|
3990
|
-
{ label: "Claude hooks", dir:
|
|
3991
|
-
{ label: "Factory hooks", dir:
|
|
3992
|
-
],
|
|
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),
|
|
3993
5278
|
skills: [
|
|
3994
|
-
{ label: "Claude skills", dir:
|
|
3995
|
-
{ label: "Factory skills", dir:
|
|
3996
|
-
{ label: "Codex skills", dir:
|
|
3997
|
-
|
|
3998
|
-
|
|
3999
|
-
|
|
4000
|
-
|
|
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) : []
|
|
4001
5294
|
};
|
|
4002
5295
|
const addCandidate = (candidate) => {
|
|
4003
5296
|
const list = candidatesByTarget.get(candidate.targetPath) || [];
|
|
@@ -4007,18 +5300,18 @@ async function scanMigration(opts) {
|
|
|
4007
5300
|
for (const src of sources.commands) {
|
|
4008
5301
|
if (!await pathExists(src.dir) || await isSymlink(src.dir))
|
|
4009
5302
|
continue;
|
|
4010
|
-
const files = await
|
|
5303
|
+
const files = await listFiles(src.dir);
|
|
4011
5304
|
for (const file of files) {
|
|
4012
|
-
const targetPath =
|
|
5305
|
+
const targetPath = path9.join(canonicalCommands, path9.basename(file));
|
|
4013
5306
|
addCandidate({ label: src.label, targetPath, kind: "file", action: "copy", sourcePath: file });
|
|
4014
5307
|
}
|
|
4015
5308
|
}
|
|
4016
5309
|
for (const src of sources.hooks) {
|
|
4017
5310
|
if (!await pathExists(src.dir) || await isSymlink(src.dir))
|
|
4018
5311
|
continue;
|
|
4019
|
-
const files = await
|
|
5312
|
+
const files = await listFiles(src.dir);
|
|
4020
5313
|
for (const file of files) {
|
|
4021
|
-
const targetPath =
|
|
5314
|
+
const targetPath = path9.join(canonicalHooks, path9.basename(file));
|
|
4022
5315
|
addCandidate({ label: src.label, targetPath, kind: "file", action: "copy", sourcePath: file });
|
|
4023
5316
|
}
|
|
4024
5317
|
}
|
|
@@ -4028,8 +5321,8 @@ async function scanMigration(opts) {
|
|
|
4028
5321
|
const skillDirs = await findSkillDirs(src.dir);
|
|
4029
5322
|
for (const dir of skillDirs) {
|
|
4030
5323
|
try {
|
|
4031
|
-
const meta = await parseSkillFile(
|
|
4032
|
-
const targetPath =
|
|
5324
|
+
const meta = await parseSkillFile(path9.join(dir, "SKILL.md"));
|
|
5325
|
+
const targetPath = path9.join(canonicalSkills, meta.name);
|
|
4033
5326
|
addCandidate({ label: src.label, targetPath, kind: "dir", action: "copy", sourcePath: dir });
|
|
4034
5327
|
} catch {}
|
|
4035
5328
|
}
|
|
@@ -4039,6 +5332,11 @@ async function scanMigration(opts) {
|
|
|
4039
5332
|
continue;
|
|
4040
5333
|
addCandidate({ label: src.label, targetPath: canonicalAgents, kind: "file", action: "copy", sourcePath: src.file });
|
|
4041
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
|
+
}
|
|
4042
5340
|
const auto = [];
|
|
4043
5341
|
const conflicts = [];
|
|
4044
5342
|
for (const [targetPath, list] of candidatesByTarget.entries()) {
|
|
@@ -4046,7 +5344,7 @@ async function scanMigration(opts) {
|
|
|
4046
5344
|
if (canonicalExists) {
|
|
4047
5345
|
let kind = "file";
|
|
4048
5346
|
try {
|
|
4049
|
-
const stat = await
|
|
5347
|
+
const stat = await fs6.promises.lstat(targetPath);
|
|
4050
5348
|
kind = stat.isDirectory() ? "dir" : "file";
|
|
4051
5349
|
} catch {}
|
|
4052
5350
|
list.unshift({
|
|
@@ -4068,28 +5366,23 @@ async function scanMigration(opts) {
|
|
|
4068
5366
|
candidates: list
|
|
4069
5367
|
});
|
|
4070
5368
|
}
|
|
4071
|
-
|
|
4072
|
-
{ label: "claude/commands", path: path8.join(roots.claudeRoot, "commands"), kind: "dir" },
|
|
4073
|
-
{ label: "factory/commands", path: path8.join(roots.factoryRoot, "commands"), kind: "dir" },
|
|
4074
|
-
{ label: "codex/prompts", path: path8.join(roots.codexRoot, "prompts"), kind: "dir" },
|
|
4075
|
-
{ label: "claude/hooks", path: path8.join(roots.claudeRoot, "hooks"), kind: "dir" },
|
|
4076
|
-
{ label: "factory/hooks", path: path8.join(roots.factoryRoot, "hooks"), kind: "dir" },
|
|
4077
|
-
{ label: "claude/skills", path: path8.join(roots.claudeRoot, "skills"), kind: "dir" },
|
|
4078
|
-
{ label: "factory/skills", path: path8.join(roots.factoryRoot, "skills"), kind: "dir" },
|
|
4079
|
-
{ label: "codex/skills", path: path8.join(roots.codexRoot, "skills"), kind: "dir" },
|
|
4080
|
-
{ label: "claude/CLAUDE.md", path: path8.join(roots.claudeRoot, "CLAUDE.md"), kind: "file" }
|
|
4081
|
-
];
|
|
4082
|
-
return { auto, conflicts, backupPaths, canonicalRoot };
|
|
5369
|
+
return { auto, conflicts, canonicalRoot };
|
|
4083
5370
|
}
|
|
4084
5371
|
async function applyMigration(plan, selections, opts) {
|
|
4085
|
-
const
|
|
4086
|
-
|
|
4087
|
-
|
|
5372
|
+
const backup = opts.backup;
|
|
5373
|
+
if (!backup)
|
|
5374
|
+
throw new Error("Backup session required.");
|
|
4088
5375
|
let copied = 0;
|
|
4089
5376
|
let skipped = 0;
|
|
4090
5377
|
const copyCandidate = async (candidate) => {
|
|
4091
5378
|
if (candidate.action !== "copy" || !candidate.sourcePath)
|
|
4092
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
|
+
}
|
|
4093
5386
|
if (candidate.kind === "file") {
|
|
4094
5387
|
await copyFile(candidate.sourcePath, candidate.targetPath, true);
|
|
4095
5388
|
} else {
|
|
@@ -4114,1316 +5407,467 @@ async function applyMigration(plan, selections, opts) {
|
|
|
4114
5407
|
else
|
|
4115
5408
|
skipped += 1;
|
|
4116
5409
|
}
|
|
4117
|
-
for (const item of plan.backupPaths) {
|
|
4118
|
-
if (!await pathExists(item.path))
|
|
4119
|
-
continue;
|
|
4120
|
-
if (await isSymlink(item.path))
|
|
4121
|
-
continue;
|
|
4122
|
-
const dest = path8.join(backupDir, item.label);
|
|
4123
|
-
await movePath(item.path, dest, item.kind);
|
|
4124
|
-
}
|
|
4125
5410
|
const linkPlan = await buildLinkPlan(opts);
|
|
4126
|
-
await applyLinkPlan(linkPlan);
|
|
4127
|
-
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
|
+
};
|
|
4128
5423
|
}
|
|
4129
5424
|
|
|
4130
|
-
// src/
|
|
4131
|
-
import fs8 from "fs";
|
|
4132
|
-
import path13 from "path";
|
|
4133
|
-
|
|
4134
|
-
// src/installers/source.ts
|
|
5425
|
+
// src/core/undo.ts
|
|
4135
5426
|
import fs7 from "fs";
|
|
4136
|
-
import os3 from "os";
|
|
4137
|
-
import path12 from "path";
|
|
4138
|
-
|
|
4139
|
-
// src/utils/paths.ts
|
|
4140
|
-
import os2 from "os";
|
|
4141
|
-
import path9 from "path";
|
|
4142
|
-
function expandHome(p) {
|
|
4143
|
-
if (!p)
|
|
4144
|
-
return p;
|
|
4145
|
-
if (p === "~")
|
|
4146
|
-
return os2.homedir();
|
|
4147
|
-
if (p.startsWith("~/"))
|
|
4148
|
-
return path9.join(os2.homedir(), p.slice(2));
|
|
4149
|
-
return p;
|
|
4150
|
-
}
|
|
4151
|
-
function isUrl(input) {
|
|
4152
|
-
return /^https?:\/\//i.test(input);
|
|
4153
|
-
}
|
|
4154
|
-
function isGitUrl(input) {
|
|
4155
|
-
return /^(git@|https?:\/\/).+\.git$/i.test(input) || input.startsWith("git://");
|
|
4156
|
-
}
|
|
4157
|
-
function isFileUrl(input) {
|
|
4158
|
-
return /^file:\/\//i.test(input);
|
|
4159
|
-
}
|
|
4160
|
-
function normalizeFileUrl(input) {
|
|
4161
|
-
if (!isFileUrl(input))
|
|
4162
|
-
return input;
|
|
4163
|
-
const url = new URL(input);
|
|
4164
|
-
return url.pathname;
|
|
4165
|
-
}
|
|
4166
|
-
|
|
4167
|
-
// src/utils/http.ts
|
|
4168
|
-
import fs6 from "fs";
|
|
4169
5427
|
import path10 from "path";
|
|
4170
|
-
async function
|
|
4171
|
-
const
|
|
4172
|
-
if (!
|
|
4173
|
-
|
|
4174
|
-
|
|
4175
|
-
|
|
4176
|
-
async function fetchJson(url) {
|
|
4177
|
-
const text = await fetchText(url);
|
|
4178
|
-
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));
|
|
4179
5434
|
}
|
|
4180
|
-
async function
|
|
4181
|
-
const
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
|
|
4185
|
-
|
|
4186
|
-
|
|
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;
|
|
4187
5447
|
}
|
|
4188
|
-
|
|
4189
|
-
|
|
4190
|
-
|
|
4191
|
-
|
|
4192
|
-
|
|
4193
|
-
|
|
4194
|
-
|
|
4195
|
-
return await new Promise((resolve, reject) => {
|
|
4196
|
-
const child = spawn(cmd, args, { cwd: opts?.cwd, stdio: ["ignore", "pipe", "pipe"] });
|
|
4197
|
-
let stdout = "";
|
|
4198
|
-
let stderr = "";
|
|
4199
|
-
child.stdout.on("data", (d) => stdout += d.toString());
|
|
4200
|
-
child.stderr.on("data", (d) => stderr += d.toString());
|
|
4201
|
-
child.on("error", reject);
|
|
4202
|
-
child.on("close", (code) => {
|
|
4203
|
-
if (code === 0)
|
|
4204
|
-
resolve({ stdout, stderr });
|
|
4205
|
-
else
|
|
4206
|
-
reject(new Error(`${cmd} ${args.join(" ")} failed with code ${code}: ${stderr || stdout}`));
|
|
4207
|
-
});
|
|
4208
|
-
});
|
|
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);
|
|
4209
5455
|
}
|
|
4210
|
-
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
const lower = archivePath.toLowerCase();
|
|
4214
|
-
if (lower.endsWith(".zip")) {
|
|
4215
|
-
await runCommand("unzip", ["-q", archivePath, "-d", destDir]);
|
|
5456
|
+
async function restorePath(entry) {
|
|
5457
|
+
if (entry.action === "create") {
|
|
5458
|
+
await removePath(entry.originalPath);
|
|
4216
5459
|
return;
|
|
4217
5460
|
}
|
|
4218
|
-
if (
|
|
4219
|
-
|
|
5461
|
+
if (!entry.backupPath)
|
|
5462
|
+
return;
|
|
5463
|
+
if (entry.kind === "symlink") {
|
|
5464
|
+
await restoreSymlink(entry);
|
|
4220
5465
|
return;
|
|
4221
5466
|
}
|
|
4222
|
-
|
|
4223
|
-
|
|
5467
|
+
await ensureDir(path10.dirname(entry.originalPath));
|
|
5468
|
+
try {
|
|
5469
|
+
await fs7.promises.rename(entry.backupPath, entry.originalPath);
|
|
4224
5470
|
return;
|
|
5471
|
+
} catch (err) {
|
|
5472
|
+
if (err?.code !== "EXDEV")
|
|
5473
|
+
throw err;
|
|
4225
5474
|
}
|
|
4226
|
-
|
|
4227
|
-
}
|
|
4228
|
-
|
|
4229
|
-
|
|
4230
|
-
async function makeTempDir(prefix) {
|
|
4231
|
-
return await fs7.promises.mkdtemp(path12.join(os3.tmpdir(), prefix));
|
|
4232
|
-
}
|
|
4233
|
-
async function cloneGitRepo(repo, dest, ref) {
|
|
4234
|
-
await runCommand("git", ["clone", "--depth", "1", repo, dest]);
|
|
4235
|
-
if (ref) {
|
|
4236
|
-
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);
|
|
4237
5479
|
}
|
|
5480
|
+
await removePath(entry.backupPath);
|
|
4238
5481
|
}
|
|
4239
|
-
function
|
|
4240
|
-
|
|
4241
|
-
|
|
4242
|
-
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
return "url";
|
|
4246
|
-
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
|
+
}
|
|
4247
5488
|
}
|
|
4248
|
-
async function
|
|
4249
|
-
const
|
|
4250
|
-
const
|
|
4251
|
-
if (
|
|
4252
|
-
|
|
4253
|
-
|
|
4254
|
-
|
|
4255
|
-
|
|
4256
|
-
|
|
4257
|
-
|
|
4258
|
-
|
|
4259
|
-
|
|
4260
|
-
|
|
4261
|
-
|
|
4262
|
-
|
|
4263
|
-
|
|
4264
|
-
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
|
|
4272
|
-
|
|
4273
|
-
|
|
4274
|
-
}
|
|
4275
|
-
if (
|
|
4276
|
-
|
|
4277
|
-
|
|
4278
|
-
|
|
4279
|
-
|
|
4280
|
-
|
|
4281
|
-
|
|
4282
|
-
|
|
4283
|
-
|
|
4284
|
-
|
|
4285
|
-
}
|
|
4286
|
-
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 };
|
|
4287
5526
|
}
|
|
4288
5527
|
|
|
4289
|
-
// src/
|
|
4290
|
-
|
|
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;
|
|
4291
5542
|
try {
|
|
4292
|
-
const
|
|
4293
|
-
|
|
4294
|
-
const parts2 = url.pathname.split("/").filter(Boolean);
|
|
4295
|
-
if (parts2.length < 4)
|
|
4296
|
-
return null;
|
|
4297
|
-
const [owner2, repo2, ref2, ...rest2] = parts2;
|
|
4298
|
-
const filePath2 = rest2.join("/");
|
|
4299
|
-
const subdir2 = filePath2.toLowerCase().endsWith("skill.md") ? filePath2.split("/").slice(0, -1).join("/") : filePath2;
|
|
4300
|
-
return { repoUrl: `https://github.com/${owner2}/${repo2}.git`, ref: ref2, subdir: subdir2 };
|
|
4301
|
-
}
|
|
4302
|
-
if (url.hostname !== "github.com")
|
|
4303
|
-
return null;
|
|
4304
|
-
const parts = url.pathname.split("/").filter(Boolean);
|
|
4305
|
-
if (parts.length < 4)
|
|
4306
|
-
return null;
|
|
4307
|
-
const [owner, repo, kind, ref, ...rest] = parts;
|
|
4308
|
-
if (kind !== "blob" && kind !== "tree")
|
|
4309
|
-
return null;
|
|
4310
|
-
const filePath = rest.join("/");
|
|
4311
|
-
const subdir = filePath.toLowerCase().endsWith("skill.md") ? filePath.split("/").slice(0, -1).join("/") : filePath;
|
|
4312
|
-
return { repoUrl: `https://github.com/${owner}/${repo}.git`, ref, subdir };
|
|
5543
|
+
const stat = await fs8.promises.lstat(task.target);
|
|
5544
|
+
return stat.isSymbolicLink();
|
|
4313
5545
|
} catch {
|
|
4314
|
-
return
|
|
5546
|
+
return false;
|
|
4315
5547
|
}
|
|
4316
5548
|
}
|
|
4317
|
-
function
|
|
4318
|
-
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
|
|
4323
|
-
const dash = parts.indexOf("-");
|
|
4324
|
-
if (dash === -1)
|
|
4325
|
-
return null;
|
|
4326
|
-
const kind = parts[dash + 1];
|
|
4327
|
-
if (kind !== "blob" && kind !== "tree" && kind !== "raw")
|
|
4328
|
-
return null;
|
|
4329
|
-
const ref = parts[dash + 2];
|
|
4330
|
-
const rest = parts.slice(dash + 3).join("/");
|
|
4331
|
-
const namespacePath = parts.slice(0, dash).join("/");
|
|
4332
|
-
if (!namespacePath)
|
|
4333
|
-
return null;
|
|
4334
|
-
const subdir = rest.toLowerCase().endsWith("skill.md") ? rest.split("/").slice(0, -1).join("/") : rest;
|
|
4335
|
-
return { repoUrl: `https://gitlab.com/${namespacePath}.git`, ref, subdir };
|
|
4336
|
-
} catch {
|
|
4337
|
-
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);
|
|
4338
5555
|
}
|
|
5556
|
+
return candidates;
|
|
4339
5557
|
}
|
|
4340
|
-
function
|
|
4341
|
-
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
|
|
4347
|
-
const
|
|
4348
|
-
const
|
|
4349
|
-
|
|
4350
|
-
|
|
4351
|
-
|
|
4352
|
-
|
|
4353
|
-
|
|
4354
|
-
|
|
4355
|
-
|
|
4356
|
-
|
|
4357
|
-
|
|
4358
|
-
|
|
4359
|
-
|
|
4360
|
-
|
|
4361
|
-
|
|
4362
|
-
const skillDirs = await findSkillDirs(rootDir);
|
|
4363
|
-
if (!skillDirs.length)
|
|
4364
|
-
throw new Error("No SKILL.md found in source");
|
|
4365
|
-
const installed = [];
|
|
4366
|
-
const skipped = [];
|
|
4367
|
-
const metas = [];
|
|
4368
|
-
for (const dir of skillDirs) {
|
|
4369
|
-
const skillFile = path13.join(dir, "SKILL.md");
|
|
4370
|
-
const meta = await parseSkillFile(skillFile);
|
|
4371
|
-
metas.push(meta);
|
|
4372
|
-
const dest = skillDestDir(canonicalSkills, meta.name);
|
|
4373
|
-
const exists = await pathExists(dest);
|
|
4374
|
-
if (exists && !opts.force) {
|
|
4375
|
-
skipped.push(meta.name);
|
|
4376
|
-
continue;
|
|
4377
|
-
}
|
|
4378
|
-
await copyDir(dir, dest, true);
|
|
4379
|
-
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));
|
|
5571
|
+
}
|
|
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);
|
|
4380
5580
|
}
|
|
4381
|
-
|
|
4382
|
-
|
|
4383
|
-
await
|
|
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);
|
|
4384
5584
|
}
|
|
5585
|
+
return { targets: targets.size };
|
|
4385
5586
|
}
|
|
4386
5587
|
|
|
4387
|
-
// src/
|
|
4388
|
-
|
|
4389
|
-
|
|
4390
|
-
|
|
4391
|
-
|
|
4392
|
-
const url = new URL(input);
|
|
4393
|
-
if (url.hostname !== "raw.githubusercontent.com")
|
|
4394
|
-
return null;
|
|
4395
|
-
const parts = url.pathname.split("/").filter(Boolean);
|
|
4396
|
-
if (parts.length < 4)
|
|
4397
|
-
return null;
|
|
4398
|
-
const [owner, repo, ref, ...rest] = parts;
|
|
4399
|
-
const filePath = rest.join("/");
|
|
4400
|
-
return { kind: "github", owner, repo, ref, basePath: path14.posix.dirname(filePath) };
|
|
4401
|
-
} catch {
|
|
4402
|
-
return null;
|
|
4403
|
-
}
|
|
5588
|
+
// src/cli.tsx
|
|
5589
|
+
var appTitle = "dotagents";
|
|
5590
|
+
function exitCancelled() {
|
|
5591
|
+
ue("Cancelled");
|
|
5592
|
+
process.exit(0);
|
|
4404
5593
|
}
|
|
4405
|
-
function
|
|
4406
|
-
|
|
4407
|
-
|
|
4408
|
-
|
|
4409
|
-
|
|
4410
|
-
|
|
4411
|
-
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
|
|
4415
|
-
|
|
4416
|
-
|
|
4417
|
-
|
|
4418
|
-
|
|
4419
|
-
|
|
4420
|
-
}
|
|
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];
|
|
4421
5609
|
}
|
|
4422
|
-
|
|
4423
|
-
if (
|
|
4424
|
-
const
|
|
4425
|
-
|
|
4426
|
-
|
|
4427
|
-
|
|
4428
|
-
|
|
4429
|
-
|
|
4430
|
-
if (fs9.existsSync(resolved) && fs9.statSync(resolved).isDirectory()) {
|
|
4431
|
-
file = path14.join(resolved, ".claude-plugin", "marketplace.json");
|
|
4432
|
-
}
|
|
4433
|
-
if (!fs9.existsSync(file))
|
|
4434
|
-
throw new Error(`marketplace.json not found: ${file}`);
|
|
4435
|
-
const raw = await fs9.promises.readFile(file, "utf8");
|
|
4436
|
-
const json = JSON.parse(raw);
|
|
4437
|
-
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;
|
|
4438
5618
|
}
|
|
4439
|
-
function
|
|
4440
|
-
|
|
4441
|
-
|
|
4442
|
-
|
|
4443
|
-
|
|
4444
|
-
|
|
4445
|
-
|
|
4446
|
-
const repoRoot = pluginRoot ? pluginRoot : "";
|
|
4447
|
-
const primary = path14.posix.normalize(path14.posix.join(repoRoot, entry.source));
|
|
4448
|
-
const candidates = [primary];
|
|
4449
|
-
if (ctx.basePath) {
|
|
4450
|
-
candidates.push(path14.posix.normalize(path14.posix.join(ctx.basePath, entry.source)));
|
|
4451
|
-
}
|
|
4452
|
-
return { source: `https://github.com/${ctx.owner}/${ctx.repo}.git`, type: "git", subdirCandidates: candidates, ref: ctx.ref };
|
|
4453
|
-
}
|
|
4454
|
-
const candidate = path14.resolve(root, entry.source);
|
|
4455
|
-
return { source: candidate, type: "local" };
|
|
4456
|
-
}
|
|
4457
|
-
const src = entry.source;
|
|
4458
|
-
if (src.source === "github" && src.repo) {
|
|
4459
|
-
return { source: `https://github.com/${src.repo}.git`, type: "git", ref: src.ref };
|
|
4460
|
-
}
|
|
4461
|
-
if (src.source === "git" && src.url) {
|
|
4462
|
-
return { source: src.url, type: "git", ref: src.ref };
|
|
4463
|
-
}
|
|
4464
|
-
if (src.source === "url" && src.url) {
|
|
4465
|
-
return { source: src.url, type: "url" };
|
|
4466
|
-
}
|
|
4467
|
-
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
|
+
});
|
|
4468
5626
|
}
|
|
4469
|
-
|
|
4470
|
-
const
|
|
4471
|
-
const
|
|
4472
|
-
|
|
4473
|
-
|
|
4474
|
-
|
|
4475
|
-
|
|
4476
|
-
|
|
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;
|
|
4477
5641
|
}
|
|
4478
|
-
|
|
4479
|
-
const
|
|
4480
|
-
const
|
|
4481
|
-
|
|
4482
|
-
|
|
4483
|
-
|
|
4484
|
-
|
|
4485
|
-
|
|
4486
|
-
const selected = opts.plugins === "all" ? json.plugins : json.plugins.filter((p) => opts.plugins.includes(p.name));
|
|
4487
|
-
const installedCommands = [];
|
|
4488
|
-
const installedHooks = [];
|
|
4489
|
-
const installedSkills = [];
|
|
4490
|
-
const skippedCommands = [];
|
|
4491
|
-
const skippedHooks = [];
|
|
4492
|
-
const skippedSkills = [];
|
|
4493
|
-
for (const plugin of selected) {
|
|
4494
|
-
const { source, type, subdir, subdirCandidates, ref } = resolvePluginPath(plugin, context, json.pluginRoot);
|
|
4495
|
-
const resolved = await resolveSource(source, type, { ref });
|
|
4496
|
-
try {
|
|
4497
|
-
let pluginDir = resolved.dir;
|
|
4498
|
-
if (subdirCandidates && subdirCandidates.length) {
|
|
4499
|
-
const found = subdirCandidates.map((candidate) => path14.join(resolved.dir, candidate)).find((candidate) => fs9.existsSync(candidate));
|
|
4500
|
-
if (!found) {
|
|
4501
|
-
throw new Error(`Plugin path not found in repo: ${subdirCandidates.join(", ")}`);
|
|
4502
|
-
}
|
|
4503
|
-
pluginDir = found;
|
|
4504
|
-
} else if (subdir) {
|
|
4505
|
-
pluginDir = path14.join(resolved.dir, subdir);
|
|
4506
|
-
}
|
|
4507
|
-
const scan = await scanPluginDir(pluginDir);
|
|
4508
|
-
for (const cmd of scan.commands) {
|
|
4509
|
-
const name = path14.basename(cmd);
|
|
4510
|
-
const dest = path14.join(commandsDest, name);
|
|
4511
|
-
const result = await copyFile(cmd, dest, !!opts.force);
|
|
4512
|
-
if (result === "written")
|
|
4513
|
-
installedCommands.push(`${plugin.name}:${name}`);
|
|
4514
|
-
else
|
|
4515
|
-
skippedCommands.push(`${plugin.name}:${name}`);
|
|
4516
|
-
}
|
|
4517
|
-
for (const hook of scan.hooks) {
|
|
4518
|
-
const name = path14.basename(hook);
|
|
4519
|
-
const dest = path14.join(hooksDest, name);
|
|
4520
|
-
const result = await copyFile(hook, dest, !!opts.force);
|
|
4521
|
-
if (result === "written")
|
|
4522
|
-
installedHooks.push(`${plugin.name}:${name}`);
|
|
4523
|
-
else
|
|
4524
|
-
skippedHooks.push(`${plugin.name}:${name}`);
|
|
4525
|
-
}
|
|
4526
|
-
if (scan.skillsDir) {
|
|
4527
|
-
const skillResult = await installSkillsFromSource({
|
|
4528
|
-
source: scan.skillsDir,
|
|
4529
|
-
sourceType: "local",
|
|
4530
|
-
scope: opts.scope,
|
|
4531
|
-
projectRoot: opts.projectRoot,
|
|
4532
|
-
homeDir: opts.homeDir,
|
|
4533
|
-
force: opts.force
|
|
4534
|
-
});
|
|
4535
|
-
installedSkills.push(...skillResult.installed.map((n) => `${plugin.name}:${n}`));
|
|
4536
|
-
skippedSkills.push(...skillResult.skipped.map((n) => `${plugin.name}:${n}`));
|
|
4537
|
-
}
|
|
4538
|
-
} finally {
|
|
4539
|
-
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}`) : ""}`);
|
|
4540
5650
|
}
|
|
4541
5651
|
}
|
|
4542
|
-
return
|
|
4543
|
-
installedCommands,
|
|
4544
|
-
installedHooks,
|
|
4545
|
-
installedSkills,
|
|
4546
|
-
skippedCommands,
|
|
4547
|
-
skippedHooks,
|
|
4548
|
-
skippedSkills
|
|
4549
|
-
};
|
|
4550
|
-
}
|
|
4551
|
-
|
|
4552
|
-
// src/tui/ui/HelpBar.tsx
|
|
4553
|
-
import { Box, Text } from "ink";
|
|
4554
|
-
import { jsxDEV } from "react/jsx-dev-runtime";
|
|
4555
|
-
function HelpBar({ text }) {
|
|
4556
|
-
return /* @__PURE__ */ jsxDEV(Box, {
|
|
4557
|
-
marginTop: 1,
|
|
4558
|
-
children: /* @__PURE__ */ jsxDEV(Text, {
|
|
4559
|
-
dimColor: true,
|
|
4560
|
-
children: text
|
|
4561
|
-
}, undefined, false, undefined, this)
|
|
4562
|
-
}, undefined, false, undefined, this);
|
|
5652
|
+
return lines;
|
|
4563
5653
|
}
|
|
4564
|
-
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
|
|
4570
|
-
|
|
4571
|
-
|
|
4572
|
-
const max = Math.max(0, a.h - s.height);
|
|
4573
|
-
const nextScrollTop = Math.min(s.scrollTop, max);
|
|
4574
|
-
if (s.innerHeight === a.h && nextScrollTop === s.scrollTop)
|
|
4575
|
-
return s;
|
|
4576
|
-
return { ...s, innerHeight: a.h, scrollTop: nextScrollTop };
|
|
4577
|
-
}
|
|
4578
|
-
case "SET_HEIGHT": {
|
|
4579
|
-
const max = Math.max(0, s.innerHeight - a.h);
|
|
4580
|
-
const nextScrollTop = Math.min(s.scrollTop, max);
|
|
4581
|
-
if (s.height === a.h && nextScrollTop === s.scrollTop)
|
|
4582
|
-
return s;
|
|
4583
|
-
return { ...s, height: a.h, scrollTop: nextScrollTop };
|
|
4584
|
-
}
|
|
4585
|
-
case "SCROLL": {
|
|
4586
|
-
const max = Math.max(0, s.innerHeight - s.height);
|
|
4587
|
-
const nextScrollTop = Math.max(0, Math.min(max, s.scrollTop + a.delta));
|
|
4588
|
-
if (nextScrollTop === s.scrollTop)
|
|
4589
|
-
return s;
|
|
4590
|
-
return { ...s, scrollTop: nextScrollTop };
|
|
4591
|
-
}
|
|
4592
|
-
case "TOP": {
|
|
4593
|
-
if (s.scrollTop === 0)
|
|
4594
|
-
return s;
|
|
4595
|
-
return { ...s, scrollTop: 0 };
|
|
4596
|
-
}
|
|
4597
|
-
case "BOTTOM": {
|
|
4598
|
-
const max = Math.max(0, s.innerHeight - s.height);
|
|
4599
|
-
if (s.scrollTop === max)
|
|
4600
|
-
return s;
|
|
4601
|
-
return { ...s, scrollTop: max };
|
|
4602
|
-
}
|
|
4603
|
-
default:
|
|
4604
|
-
return s;
|
|
4605
|
-
}
|
|
4606
|
-
};
|
|
4607
|
-
function ScrollArea({ height, children }) {
|
|
4608
|
-
const innerRef = useRef(null);
|
|
4609
|
-
const { stdout } = useStdout();
|
|
4610
|
-
const [state, dispatch] = useReducer(reducer, { innerHeight: 0, height, scrollTop: 0 });
|
|
4611
|
-
useEffect(() => {
|
|
4612
|
-
dispatch({ type: "SET_HEIGHT", h: height });
|
|
4613
|
-
}, [height]);
|
|
4614
|
-
useEffect(() => {
|
|
4615
|
-
if (!innerRef.current)
|
|
4616
|
-
return;
|
|
4617
|
-
const dim = measureElement(innerRef.current);
|
|
4618
|
-
dispatch({ type: "SET_INNER", h: dim.height });
|
|
4619
|
-
});
|
|
4620
|
-
useEffect(() => {
|
|
4621
|
-
const onResize = () => dispatch({ type: "SET_HEIGHT", h: stdout.rows });
|
|
4622
|
-
return () => void onResize();
|
|
4623
|
-
}, [stdout]);
|
|
4624
|
-
useInput((input, key) => {
|
|
4625
|
-
if (key.pageDown || key.downArrow && key.meta)
|
|
4626
|
-
dispatch({ type: "SCROLL", delta: Math.max(1, Math.floor(state.height * 0.8)) });
|
|
4627
|
-
if (key.pageUp || key.upArrow && key.meta)
|
|
4628
|
-
dispatch({ type: "SCROLL", delta: -Math.max(1, Math.floor(state.height * 0.8)) });
|
|
4629
|
-
if (input === "g")
|
|
4630
|
-
dispatch({ type: "TOP" });
|
|
4631
|
-
if (input === "G")
|
|
4632
|
-
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
|
+
]
|
|
4633
5662
|
});
|
|
4634
|
-
|
|
4635
|
-
|
|
4636
|
-
|
|
4637
|
-
|
|
4638
|
-
|
|
4639
|
-
|
|
4640
|
-
|
|
4641
|
-
flexDirection: "column",
|
|
4642
|
-
marginTop: -state.scrollTop,
|
|
4643
|
-
children
|
|
4644
|
-
}, undefined, false, undefined, this)
|
|
4645
|
-
}, 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;
|
|
4646
5670
|
}
|
|
4647
|
-
|
|
4648
|
-
|
|
4649
|
-
import { Box as Box3, useStdout as useStdout2 } from "ink";
|
|
4650
|
-
import { jsxDEV as jsxDEV3 } from "react/jsx-dev-runtime";
|
|
4651
|
-
function Screen({ children }) {
|
|
4652
|
-
const { stdout } = useStdout2();
|
|
4653
|
-
const height = stdout?.rows;
|
|
4654
|
-
return /* @__PURE__ */ jsxDEV3(Box3, {
|
|
4655
|
-
flexDirection: "column",
|
|
4656
|
-
height,
|
|
4657
|
-
children
|
|
4658
|
-
}, undefined, false, undefined, this);
|
|
5671
|
+
function scopeLabel(scope) {
|
|
5672
|
+
return scope === "global" ? "Global (~/.agents)" : "Project (.agents)";
|
|
4659
5673
|
}
|
|
4660
|
-
|
|
4661
|
-
|
|
4662
|
-
|
|
4663
|
-
|
|
4664
|
-
|
|
4665
|
-
|
|
4666
|
-
|
|
4667
|
-
const
|
|
4668
|
-
|
|
4669
|
-
|
|
4670
|
-
|
|
4671
|
-
|
|
4672
|
-
|
|
4673
|
-
|
|
4674
|
-
const
|
|
4675
|
-
|
|
4676
|
-
|
|
4677
|
-
|
|
4678
|
-
|
|
4679
|
-
const [forceBackupDir, setForceBackupDir] = useState(null);
|
|
4680
|
-
const [showDetails, setShowDetails] = useState(false);
|
|
4681
|
-
const [conflictsOnly, setConflictsOnly] = useState(false);
|
|
4682
|
-
const { stdout } = useStdout3();
|
|
4683
|
-
useInput2((input, key) => {
|
|
4684
|
-
if (input === "q")
|
|
4685
|
-
exit();
|
|
4686
|
-
if (step === "status" && input === "d")
|
|
4687
|
-
setShowDetails((prev) => !prev);
|
|
4688
|
-
if (step === "status" && input === "c")
|
|
4689
|
-
setConflictsOnly(true);
|
|
4690
|
-
if (step === "status" && input === "a")
|
|
4691
|
-
setConflictsOnly(false);
|
|
4692
|
-
if (key.escape) {
|
|
4693
|
-
if (step === "action")
|
|
4694
|
-
return setStep("scope");
|
|
4695
|
-
if (step === "status")
|
|
4696
|
-
return setStep("action");
|
|
4697
|
-
if (step === "force-confirm")
|
|
4698
|
-
return setStep("action");
|
|
4699
|
-
if (step === "migrate-choice") {
|
|
4700
|
-
setMigratePlan(null);
|
|
4701
|
-
setMigrateSelections(new Map);
|
|
4702
|
-
return setStep("action");
|
|
4703
|
-
}
|
|
4704
|
-
if (step === "skill-source-type")
|
|
4705
|
-
return setStep("action");
|
|
4706
|
-
if (step === "skill-input")
|
|
4707
|
-
return setStep("skill-source-type");
|
|
4708
|
-
if (step === "plugin-marketplace-input")
|
|
4709
|
-
return setStep("action");
|
|
4710
|
-
if (step === "plugin-select")
|
|
4711
|
-
return setStep("plugin-marketplace-input");
|
|
4712
|
-
if (step === "done")
|
|
4713
|
-
return setStep("action");
|
|
4714
|
-
}
|
|
4715
|
-
if (step === "done" && key.return)
|
|
4716
|
-
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
|
|
4717
5693
|
});
|
|
4718
|
-
|
|
4719
|
-
|
|
4720
|
-
|
|
4721
|
-
|
|
4722
|
-
|
|
4723
|
-
|
|
4724
|
-
|
|
4725
|
-
|
|
4726
|
-
|
|
4727
|
-
|
|
4728
|
-
|
|
4729
|
-
const conflicts = plan?.conflicts.length || 0;
|
|
4730
|
-
const changes = plan?.changes.length || 0;
|
|
4731
|
-
const actionItems = useMemo(() => {
|
|
4732
|
-
const items = [
|
|
4733
|
-
{ label: "Apply/repair links", value: "apply" }
|
|
4734
|
-
];
|
|
4735
|
-
if (conflicts > 0)
|
|
4736
|
-
items.push({ label: "Force apply (backup + overwrite conflicts)", value: "force-apply" });
|
|
4737
|
-
items.push({ label: "View status", value: "view-status" });
|
|
4738
|
-
items.push({ label: "Migrate existing content", value: "migrate" });
|
|
4739
|
-
items.push({ label: "Add skill", value: "add-skill" });
|
|
4740
|
-
items.push({ label: "Install plugin", value: "install-plugin" });
|
|
4741
|
-
items.push({ label: "Exit", value: "exit" });
|
|
4742
|
-
return items;
|
|
4743
|
-
}, [conflicts]);
|
|
4744
|
-
const displayName = (name) => {
|
|
4745
|
-
if (name === "agents-md")
|
|
4746
|
-
return "AGENTS.md";
|
|
4747
|
-
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"
|
|
4748
5705
|
};
|
|
4749
|
-
|
|
4750
|
-
|
|
4751
|
-
|
|
4752
|
-
|
|
4753
|
-
|
|
4754
|
-
|
|
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 }))
|
|
4755
5721
|
});
|
|
4756
|
-
|
|
4757
|
-
|
|
4758
|
-
|
|
4759
|
-
|
|
4760
|
-
|
|
4761
|
-
|
|
4762
|
-
|
|
4763
|
-
|
|
4764
|
-
|
|
4765
|
-
|
|
4766
|
-
|
|
4767
|
-
|
|
4768
|
-
|
|
4769
|
-
|
|
4770
|
-
|
|
4771
|
-
|
|
4772
|
-
|
|
4773
|
-
|
|
4774
|
-
|
|
4775
|
-
|
|
4776
|
-
|
|
4777
|
-
|
|
4778
|
-
|
|
4779
|
-
|
|
4780
|
-
|
|
4781
|
-
const
|
|
4782
|
-
|
|
4783
|
-
|
|
4784
|
-
|
|
4785
|
-
|
|
4786
|
-
|
|
4787
|
-
try {
|
|
4788
|
-
const stat = await fs10.promises.lstat(task.target);
|
|
4789
|
-
if (stat.isDirectory() && !stat.isSymbolicLink()) {
|
|
4790
|
-
const entries = await fs10.promises.readdir(task.target);
|
|
4791
|
-
const shown = entries.slice(0, 6);
|
|
4792
|
-
const more = entries.length > 6 ? `… +${entries.length - 6} more` : "";
|
|
4793
|
-
const contents = entries.length === 0 ? "(empty)" : `${shown.join(", ")}${more ? `, ${more}` : ""}`;
|
|
4794
|
-
map.set(task.target, { reason: task.reason, contents: `Contains: ${contents}` });
|
|
4795
|
-
}
|
|
4796
|
-
} catch {}
|
|
4797
|
-
}
|
|
4798
|
-
if (!cancelled)
|
|
4799
|
-
setConflictDetails(map);
|
|
4800
|
-
};
|
|
4801
|
-
load();
|
|
4802
|
-
return () => {
|
|
4803
|
-
cancelled = true;
|
|
4804
|
-
};
|
|
4805
|
-
}, [plan]);
|
|
4806
|
-
const renderStatusList = () => {
|
|
4807
|
-
const sections = status.map((s) => {
|
|
4808
|
-
const targets = conflictsOnly ? s.targets.filter((t) => t.status === "conflict") : s.targets;
|
|
4809
|
-
if (conflictsOnly && targets.length === 0)
|
|
4810
|
-
return null;
|
|
4811
|
-
return /* @__PURE__ */ jsxDEV4(Box4, {
|
|
4812
|
-
flexDirection: "column",
|
|
4813
|
-
marginTop: 1,
|
|
4814
|
-
children: [
|
|
4815
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
4816
|
-
color: "cyan",
|
|
4817
|
-
children: displayName(s.name)
|
|
4818
|
-
}, undefined, false, undefined, this),
|
|
4819
|
-
targets.map((t) => /* @__PURE__ */ jsxDEV4(Box4, {
|
|
4820
|
-
flexDirection: "column",
|
|
4821
|
-
children: [
|
|
4822
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
4823
|
-
children: [
|
|
4824
|
-
t.status === "linked" ? "✓" : t.status === "missing" ? "•" : "⚠",
|
|
4825
|
-
" ",
|
|
4826
|
-
t.path
|
|
4827
|
-
]
|
|
4828
|
-
}, undefined, true, undefined, this),
|
|
4829
|
-
showDetails && t.status === "conflict" && conflictDetails.has(t.path) ? /* @__PURE__ */ jsxDEV4(Fragment, {
|
|
4830
|
-
children: [
|
|
4831
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
4832
|
-
color: "red",
|
|
4833
|
-
children: [
|
|
4834
|
-
" ",
|
|
4835
|
-
conflictDetails.get(t.path)?.reason
|
|
4836
|
-
]
|
|
4837
|
-
}, undefined, true, undefined, this),
|
|
4838
|
-
conflictDetails.get(t.path)?.contents ? /* @__PURE__ */ jsxDEV4(Text2, {
|
|
4839
|
-
dimColor: true,
|
|
4840
|
-
children: [
|
|
4841
|
-
" ",
|
|
4842
|
-
conflictDetails.get(t.path)?.contents
|
|
4843
|
-
]
|
|
4844
|
-
}, undefined, true, undefined, this) : null
|
|
4845
|
-
]
|
|
4846
|
-
}, undefined, true, undefined, this) : null
|
|
4847
|
-
]
|
|
4848
|
-
}, t.path, true, undefined, this))
|
|
4849
|
-
]
|
|
4850
|
-
}, s.name, true, undefined, this);
|
|
4851
|
-
}).filter(Boolean);
|
|
4852
|
-
if (!sections.length) {
|
|
4853
|
-
return /* @__PURE__ */ jsxDEV4(Box4, {
|
|
4854
|
-
marginTop: 1,
|
|
4855
|
-
children: /* @__PURE__ */ jsxDEV4(Text2, {
|
|
4856
|
-
dimColor: true,
|
|
4857
|
-
children: "No conflicts found."
|
|
4858
|
-
}, undefined, false, undefined, this)
|
|
4859
|
-
}, undefined, false, undefined, this);
|
|
4860
|
-
}
|
|
4861
|
-
return /* @__PURE__ */ jsxDEV4(Box4, {
|
|
4862
|
-
flexDirection: "column",
|
|
4863
|
-
children: sections
|
|
4864
|
-
}, undefined, false, undefined, this);
|
|
4865
|
-
};
|
|
4866
|
-
if (step === "scope") {
|
|
4867
|
-
return /* @__PURE__ */ jsxDEV4(Screen, {
|
|
4868
|
-
children: [
|
|
4869
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
4870
|
-
color: "green",
|
|
4871
|
-
children: appTitle
|
|
4872
|
-
}, undefined, false, undefined, this),
|
|
4873
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
4874
|
-
children: "Choose a workspace:"
|
|
4875
|
-
}, undefined, false, undefined, this),
|
|
4876
|
-
/* @__PURE__ */ jsxDEV4(SelectInput, {
|
|
4877
|
-
items: [
|
|
4878
|
-
{ label: "Global home", value: "global" },
|
|
4879
|
-
{ label: "Project folder", value: "project" },
|
|
4880
|
-
{ label: "Exit", value: "exit" }
|
|
4881
|
-
],
|
|
4882
|
-
onSelect: (item) => {
|
|
4883
|
-
if (item.value === "exit")
|
|
4884
|
-
return exit();
|
|
4885
|
-
setScope(item.value);
|
|
4886
|
-
setStep("action");
|
|
4887
|
-
}
|
|
4888
|
-
}, undefined, false, undefined, this)
|
|
4889
|
-
]
|
|
4890
|
-
}, undefined, true, undefined, this);
|
|
4891
|
-
}
|
|
4892
|
-
if (step === "action") {
|
|
4893
|
-
return /* @__PURE__ */ jsxDEV4(Screen, {
|
|
4894
|
-
children: [
|
|
4895
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
4896
|
-
color: "green",
|
|
4897
|
-
children: appTitle
|
|
4898
|
-
}, undefined, false, undefined, this),
|
|
4899
|
-
/* @__PURE__ */ jsxDEV4(Box4, {
|
|
4900
|
-
flexDirection: "column",
|
|
4901
|
-
marginTop: 1,
|
|
4902
|
-
children: [
|
|
4903
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
4904
|
-
children: [
|
|
4905
|
-
"Scope: ",
|
|
4906
|
-
scopeLabel
|
|
4907
|
-
]
|
|
4908
|
-
}, undefined, true, undefined, this),
|
|
4909
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
4910
|
-
children: [
|
|
4911
|
-
"Pending changes: ",
|
|
4912
|
-
changes,
|
|
4913
|
-
" · Conflicts: ",
|
|
4914
|
-
conflicts
|
|
4915
|
-
]
|
|
4916
|
-
}, undefined, true, undefined, this),
|
|
4917
|
-
summaryTable.map((line) => /* @__PURE__ */ jsxDEV4(Text2, {
|
|
4918
|
-
children: line
|
|
4919
|
-
}, line, false, undefined, this))
|
|
4920
|
-
]
|
|
4921
|
-
}, undefined, true, undefined, this),
|
|
4922
|
-
/* @__PURE__ */ jsxDEV4(Box4, {
|
|
4923
|
-
marginTop: 1,
|
|
4924
|
-
flexDirection: "column",
|
|
4925
|
-
children: [
|
|
4926
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
4927
|
-
children: "Choose an action:"
|
|
4928
|
-
}, undefined, false, undefined, this),
|
|
4929
|
-
/* @__PURE__ */ jsxDEV4(SelectInput, {
|
|
4930
|
-
items: actionItems,
|
|
4931
|
-
onSelect: (item) => {
|
|
4932
|
-
if (item.value === "exit")
|
|
4933
|
-
return exit();
|
|
4934
|
-
if (item.value === "view-status") {
|
|
4935
|
-
setStep("status");
|
|
4936
|
-
return;
|
|
4937
|
-
}
|
|
4938
|
-
if (item.value === "migrate") {
|
|
4939
|
-
if (!scope)
|
|
4940
|
-
return;
|
|
4941
|
-
setBusy("Scanning existing content...");
|
|
4942
|
-
setStep("applying");
|
|
4943
|
-
(async () => {
|
|
4944
|
-
try {
|
|
4945
|
-
const plan2 = await scanMigration({ scope });
|
|
4946
|
-
setMigratePlan(plan2);
|
|
4947
|
-
setMigrateIndex(0);
|
|
4948
|
-
setMigrateSelections(new Map);
|
|
4949
|
-
if (plan2.conflicts.length > 0) {
|
|
4950
|
-
setBusy(null);
|
|
4951
|
-
setStep("migrate-choice");
|
|
4952
|
-
return;
|
|
4953
|
-
}
|
|
4954
|
-
setBusy("Migrating...");
|
|
4955
|
-
const result = await applyMigration(plan2, new Map, { scope });
|
|
4956
|
-
setMessage(`Migrated ${result.copied} items. Backup: ${result.backupDir}`);
|
|
4957
|
-
await refreshStatus(scope);
|
|
4958
|
-
setStep("done");
|
|
4959
|
-
} catch (err) {
|
|
4960
|
-
setMessage(err?.message || String(err));
|
|
4961
|
-
setStep("done");
|
|
4962
|
-
} finally {
|
|
4963
|
-
setBusy(null);
|
|
4964
|
-
}
|
|
4965
|
-
})();
|
|
4966
|
-
return;
|
|
4967
|
-
}
|
|
4968
|
-
if (item.value === "apply" || item.value === "force-apply") {
|
|
4969
|
-
if (item.value === "force-apply") {
|
|
4970
|
-
setBusy("Preparing force apply...");
|
|
4971
|
-
setStep("applying");
|
|
4972
|
-
(async () => {
|
|
4973
|
-
try {
|
|
4974
|
-
if (!scope)
|
|
4975
|
-
return;
|
|
4976
|
-
const roots = resolveRoots({ scope });
|
|
4977
|
-
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
4978
|
-
setForceBackupDir(path15.join(roots.canonicalRoot, "backup", timestamp));
|
|
4979
|
-
setStep("force-confirm");
|
|
4980
|
-
} catch (err) {
|
|
4981
|
-
setMessage(err?.message || String(err));
|
|
4982
|
-
setStep("done");
|
|
4983
|
-
} finally {
|
|
4984
|
-
setBusy(null);
|
|
4985
|
-
}
|
|
4986
|
-
})();
|
|
4987
|
-
return;
|
|
4988
|
-
}
|
|
4989
|
-
setBusy("Applying...");
|
|
4990
|
-
setStep("applying");
|
|
4991
|
-
(async () => {
|
|
4992
|
-
try {
|
|
4993
|
-
if (!plan || !scope)
|
|
4994
|
-
return;
|
|
4995
|
-
const result = await applyLinkPlan(plan);
|
|
4996
|
-
setMessage(`Applied: ${result.applied}, Skipped: ${result.skipped}, Conflicts: ${result.conflicts}`);
|
|
4997
|
-
await refreshStatus(scope);
|
|
4998
|
-
} catch (err) {
|
|
4999
|
-
setMessage(err?.message || String(err));
|
|
5000
|
-
} finally {
|
|
5001
|
-
setBusy(null);
|
|
5002
|
-
setStep("done");
|
|
5003
|
-
}
|
|
5004
|
-
})();
|
|
5005
|
-
return;
|
|
5006
|
-
}
|
|
5007
|
-
if (item.value === "add-skill") {
|
|
5008
|
-
setSkillInput("");
|
|
5009
|
-
setStep("skill-source-type");
|
|
5010
|
-
return;
|
|
5011
|
-
}
|
|
5012
|
-
if (item.value === "install-plugin") {
|
|
5013
|
-
setMarketplaceInput("");
|
|
5014
|
-
setStep("plugin-marketplace-input");
|
|
5015
|
-
return;
|
|
5016
|
-
}
|
|
5017
|
-
}
|
|
5018
|
-
}, undefined, false, undefined, this),
|
|
5019
|
-
/* @__PURE__ */ jsxDEV4(HelpBar, {
|
|
5020
|
-
text: "Use ↑↓ to navigate, Enter to select, Esc to go back, q to quit"
|
|
5021
|
-
}, undefined, false, undefined, this)
|
|
5022
|
-
]
|
|
5023
|
-
}, undefined, true, undefined, this)
|
|
5024
|
-
]
|
|
5025
|
-
}, undefined, true, undefined, this);
|
|
5026
|
-
}
|
|
5027
|
-
if (step === "status") {
|
|
5028
|
-
const listHeight = Math.max(6, (stdout?.rows ?? 24) - 8);
|
|
5029
|
-
return /* @__PURE__ */ jsxDEV4(Screen, {
|
|
5030
|
-
children: [
|
|
5031
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5032
|
-
color: "green",
|
|
5033
|
-
children: appTitle
|
|
5034
|
-
}, undefined, false, undefined, this),
|
|
5035
|
-
/* @__PURE__ */ jsxDEV4(Box4, {
|
|
5036
|
-
flexDirection: "column",
|
|
5037
|
-
marginTop: 1,
|
|
5038
|
-
children: [
|
|
5039
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5040
|
-
children: [
|
|
5041
|
-
"Scope: ",
|
|
5042
|
-
scopeLabel
|
|
5043
|
-
]
|
|
5044
|
-
}, undefined, true, undefined, this),
|
|
5045
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5046
|
-
children: [
|
|
5047
|
-
"Pending changes: ",
|
|
5048
|
-
changes,
|
|
5049
|
-
" · Conflicts: ",
|
|
5050
|
-
conflicts
|
|
5051
|
-
]
|
|
5052
|
-
}, undefined, true, undefined, this),
|
|
5053
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5054
|
-
dimColor: true,
|
|
5055
|
-
children: "Legend: ✓ linked • need link ⚠ conflict"
|
|
5056
|
-
}, undefined, false, undefined, this),
|
|
5057
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5058
|
-
dimColor: true,
|
|
5059
|
-
children: [
|
|
5060
|
-
"Mode: ",
|
|
5061
|
-
conflictsOnly ? "Conflicts only" : "All",
|
|
5062
|
-
" · Details: ",
|
|
5063
|
-
showDetails ? "On" : "Off"
|
|
5064
|
-
]
|
|
5065
|
-
}, undefined, true, undefined, this)
|
|
5066
|
-
]
|
|
5067
|
-
}, undefined, true, undefined, this),
|
|
5068
|
-
/* @__PURE__ */ jsxDEV4(ScrollArea, {
|
|
5069
|
-
height: listHeight,
|
|
5070
|
-
children: renderStatusList()
|
|
5071
|
-
}, undefined, false, undefined, this),
|
|
5072
|
-
/* @__PURE__ */ jsxDEV4(HelpBar, {
|
|
5073
|
-
text: "d: details · c: conflicts only · a: show all · Esc: back · q: quit"
|
|
5074
|
-
}, undefined, false, undefined, this)
|
|
5075
|
-
]
|
|
5076
|
-
}, undefined, true, undefined, this);
|
|
5077
|
-
}
|
|
5078
|
-
if (step === "force-confirm") {
|
|
5079
|
-
return /* @__PURE__ */ jsxDEV4(Screen, {
|
|
5080
|
-
children: [
|
|
5081
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5082
|
-
color: "yellow",
|
|
5083
|
-
children: "Force apply will overwrite existing real files/directories."
|
|
5084
|
-
}, undefined, false, undefined, this),
|
|
5085
|
-
/* @__PURE__ */ jsxDEV4(Box4, {
|
|
5086
|
-
flexDirection: "column",
|
|
5087
|
-
marginTop: 1,
|
|
5088
|
-
children: [
|
|
5089
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5090
|
-
children: "Backup will be created at:"
|
|
5091
|
-
}, undefined, false, undefined, this),
|
|
5092
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5093
|
-
dimColor: true,
|
|
5094
|
-
children: forceBackupDir || "(pending)"
|
|
5095
|
-
}, undefined, false, undefined, this)
|
|
5096
|
-
]
|
|
5097
|
-
}, undefined, true, undefined, this),
|
|
5098
|
-
/* @__PURE__ */ jsxDEV4(Box4, {
|
|
5099
|
-
marginTop: 1,
|
|
5100
|
-
flexDirection: "column",
|
|
5101
|
-
children: [
|
|
5102
|
-
/* @__PURE__ */ jsxDEV4(SelectInput, {
|
|
5103
|
-
items: [
|
|
5104
|
-
{ label: "Proceed (create backup + overwrite)", value: "proceed" },
|
|
5105
|
-
{ label: "Cancel", value: "cancel" }
|
|
5106
|
-
],
|
|
5107
|
-
onSelect: (item) => {
|
|
5108
|
-
if (item.value === "cancel") {
|
|
5109
|
-
setForceBackupDir(null);
|
|
5110
|
-
setStep("action");
|
|
5111
|
-
return;
|
|
5112
|
-
}
|
|
5113
|
-
setBusy("Applying (force)...");
|
|
5114
|
-
setStep("applying");
|
|
5115
|
-
(async () => {
|
|
5116
|
-
try {
|
|
5117
|
-
if (!plan || !scope)
|
|
5118
|
-
return;
|
|
5119
|
-
const backupDir = forceBackupDir || undefined;
|
|
5120
|
-
const result = await applyLinkPlan(plan, { force: true, backupDir });
|
|
5121
|
-
const backupNote = result.backedUp > 0 && result.backupDir ? `, Backed up: ${result.backedUp} (${result.backupDir})` : "";
|
|
5122
|
-
setMessage(`Applied: ${result.applied}, Skipped: ${result.skipped}, Conflicts: ${result.conflicts}${backupNote}`);
|
|
5123
|
-
await refreshStatus(scope);
|
|
5124
|
-
} catch (err) {
|
|
5125
|
-
setMessage(err?.message || String(err));
|
|
5126
|
-
} finally {
|
|
5127
|
-
setForceBackupDir(null);
|
|
5128
|
-
setBusy(null);
|
|
5129
|
-
setStep("done");
|
|
5130
|
-
}
|
|
5131
|
-
})();
|
|
5132
|
-
}
|
|
5133
|
-
}, undefined, false, undefined, this),
|
|
5134
|
-
/* @__PURE__ */ jsxDEV4(HelpBar, {
|
|
5135
|
-
text: "Enter to confirm · Esc to cancel · q to quit"
|
|
5136
|
-
}, undefined, false, undefined, this)
|
|
5137
|
-
]
|
|
5138
|
-
}, undefined, true, undefined, this)
|
|
5139
|
-
]
|
|
5140
|
-
}, undefined, true, undefined, this);
|
|
5141
|
-
}
|
|
5142
|
-
if (step === "migrate-choice" && migratePlan) {
|
|
5143
|
-
const conflict = migratePlan.conflicts[migrateIndex];
|
|
5144
|
-
if (!conflict) {
|
|
5145
|
-
return /* @__PURE__ */ jsxDEV4(Screen, {
|
|
5146
|
-
children: [
|
|
5147
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5148
|
-
color: "green",
|
|
5149
|
-
children: appTitle
|
|
5150
|
-
}, undefined, false, undefined, this),
|
|
5151
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5152
|
-
dimColor: true,
|
|
5153
|
-
children: "No conflicts to resolve."
|
|
5154
|
-
}, undefined, false, undefined, this),
|
|
5155
|
-
/* @__PURE__ */ jsxDEV4(HelpBar, {
|
|
5156
|
-
text: "Esc: back · q: quit"
|
|
5157
|
-
}, undefined, false, undefined, this)
|
|
5158
|
-
]
|
|
5159
|
-
}, undefined, true, undefined, this);
|
|
5160
|
-
}
|
|
5161
|
-
const items = conflict.candidates.map((c) => ({
|
|
5162
|
-
label: c.label,
|
|
5163
|
-
value: c
|
|
5164
|
-
}));
|
|
5165
|
-
return /* @__PURE__ */ jsxDEV4(Screen, {
|
|
5166
|
-
children: [
|
|
5167
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5168
|
-
color: "green",
|
|
5169
|
-
children: appTitle
|
|
5170
|
-
}, undefined, false, undefined, this),
|
|
5171
|
-
/* @__PURE__ */ jsxDEV4(Box4, {
|
|
5172
|
-
flexDirection: "column",
|
|
5173
|
-
marginTop: 1,
|
|
5174
|
-
children: [
|
|
5175
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5176
|
-
children: [
|
|
5177
|
-
"Resolve conflict ",
|
|
5178
|
-
migrateIndex + 1,
|
|
5179
|
-
" of ",
|
|
5180
|
-
migratePlan.conflicts.length
|
|
5181
|
-
]
|
|
5182
|
-
}, undefined, true, undefined, this),
|
|
5183
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5184
|
-
dimColor: true,
|
|
5185
|
-
children: conflict.label
|
|
5186
|
-
}, undefined, false, undefined, this)
|
|
5187
|
-
]
|
|
5188
|
-
}, undefined, true, undefined, this),
|
|
5189
|
-
/* @__PURE__ */ jsxDEV4(Box4, {
|
|
5190
|
-
marginTop: 1,
|
|
5191
|
-
flexDirection: "column",
|
|
5192
|
-
children: [
|
|
5193
|
-
/* @__PURE__ */ jsxDEV4(SelectInput, {
|
|
5194
|
-
items,
|
|
5195
|
-
onSelect: (item) => {
|
|
5196
|
-
if (!scope)
|
|
5197
|
-
return;
|
|
5198
|
-
const next = new Map(migrateSelections);
|
|
5199
|
-
next.set(conflict.targetPath, item.value);
|
|
5200
|
-
setMigrateSelections(next);
|
|
5201
|
-
if (migrateIndex + 1 < migratePlan.conflicts.length) {
|
|
5202
|
-
setMigrateIndex(migrateIndex + 1);
|
|
5203
|
-
return;
|
|
5204
|
-
}
|
|
5205
|
-
setBusy("Migrating...");
|
|
5206
|
-
setStep("applying");
|
|
5207
|
-
(async () => {
|
|
5208
|
-
try {
|
|
5209
|
-
const result = await applyMigration(migratePlan, next, { scope });
|
|
5210
|
-
setMessage(`Migrated ${result.copied} items. Backup: ${result.backupDir}`);
|
|
5211
|
-
await refreshStatus(scope);
|
|
5212
|
-
} catch (err) {
|
|
5213
|
-
setMessage(err?.message || String(err));
|
|
5214
|
-
} finally {
|
|
5215
|
-
setBusy(null);
|
|
5216
|
-
setMigratePlan(null);
|
|
5217
|
-
setMigrateIndex(0);
|
|
5218
|
-
setMigrateSelections(new Map);
|
|
5219
|
-
setStep("done");
|
|
5220
|
-
}
|
|
5221
|
-
})();
|
|
5222
|
-
}
|
|
5223
|
-
}, undefined, false, undefined, this),
|
|
5224
|
-
/* @__PURE__ */ jsxDEV4(HelpBar, {
|
|
5225
|
-
text: "Use ↑↓ to choose, Enter to select, Esc to cancel"
|
|
5226
|
-
}, undefined, false, undefined, this)
|
|
5227
|
-
]
|
|
5228
|
-
}, undefined, true, undefined, this)
|
|
5229
|
-
]
|
|
5230
|
-
}, undefined, true, undefined, this);
|
|
5231
|
-
}
|
|
5232
|
-
if (step === "applying") {
|
|
5233
|
-
return /* @__PURE__ */ jsxDEV4(Screen, {
|
|
5234
|
-
children: /* @__PURE__ */ jsxDEV4(Text2, {
|
|
5235
|
-
color: "yellow",
|
|
5236
|
-
children: [
|
|
5237
|
-
/* @__PURE__ */ jsxDEV4(Spinner, {
|
|
5238
|
-
type: "dots"
|
|
5239
|
-
}, undefined, false, undefined, this),
|
|
5240
|
-
" ",
|
|
5241
|
-
busy || "Working..."
|
|
5242
|
-
]
|
|
5243
|
-
}, undefined, true, undefined, this)
|
|
5244
|
-
}, undefined, false, undefined, this);
|
|
5245
|
-
}
|
|
5246
|
-
if (step === "skill-source-type") {
|
|
5247
|
-
return /* @__PURE__ */ jsxDEV4(Screen, {
|
|
5248
|
-
children: [
|
|
5249
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5250
|
-
children: "Select skill source type:"
|
|
5251
|
-
}, undefined, false, undefined, this),
|
|
5252
|
-
/* @__PURE__ */ jsxDEV4(SelectInput, {
|
|
5253
|
-
items: [
|
|
5254
|
-
{ label: "Local path", value: "local" },
|
|
5255
|
-
{ label: "URL", value: "url" },
|
|
5256
|
-
{ label: "Back", value: "back" }
|
|
5257
|
-
],
|
|
5258
|
-
onSelect: (item) => {
|
|
5259
|
-
if (item.value === "back") {
|
|
5260
|
-
setStep("action");
|
|
5261
|
-
return;
|
|
5262
|
-
}
|
|
5263
|
-
setSkillType(item.value);
|
|
5264
|
-
setStep("skill-input");
|
|
5265
|
-
}
|
|
5266
|
-
}, undefined, false, undefined, this),
|
|
5267
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5268
|
-
dimColor: true,
|
|
5269
|
-
children: "Press Esc to go back, or q to quit."
|
|
5270
|
-
}, undefined, false, undefined, this)
|
|
5271
|
-
]
|
|
5272
|
-
}, undefined, true, undefined, this);
|
|
5273
|
-
}
|
|
5274
|
-
if (step === "skill-input") {
|
|
5275
|
-
return /* @__PURE__ */ jsxDEV4(Screen, {
|
|
5276
|
-
children: [
|
|
5277
|
-
skillType === "local" ? /* @__PURE__ */ jsxDEV4(Fragment, {
|
|
5278
|
-
children: [
|
|
5279
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5280
|
-
children: "Paste a skills folder path and we’ll install all skills inside."
|
|
5281
|
-
}, undefined, false, undefined, this),
|
|
5282
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5283
|
-
children: "Or paste a SKILL.md file and we’ll install the full skill."
|
|
5284
|
-
}, undefined, false, undefined, this)
|
|
5285
|
-
]
|
|
5286
|
-
}, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV4(Fragment, {
|
|
5287
|
-
children: [
|
|
5288
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5289
|
-
children: "Paste a skills folder URL and we’ll fetch all skills inside."
|
|
5290
|
-
}, undefined, false, undefined, this),
|
|
5291
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5292
|
-
children: "Or paste a SKILL.md URL and we’ll install the full skill."
|
|
5293
|
-
}, undefined, false, undefined, this)
|
|
5294
|
-
]
|
|
5295
|
-
}, undefined, true, undefined, this),
|
|
5296
|
-
/* @__PURE__ */ jsxDEV4(TextInput, {
|
|
5297
|
-
value: skillInput,
|
|
5298
|
-
onChange: setSkillInput,
|
|
5299
|
-
onSubmit: () => {
|
|
5300
|
-
if (!scope)
|
|
5301
|
-
return;
|
|
5302
|
-
setBusy("Installing skill(s)...");
|
|
5303
|
-
setStep("applying");
|
|
5304
|
-
(async () => {
|
|
5305
|
-
try {
|
|
5306
|
-
const result = await installSkillsFromSource({
|
|
5307
|
-
source: skillInput,
|
|
5308
|
-
sourceType: skillType,
|
|
5309
|
-
scope
|
|
5310
|
-
});
|
|
5311
|
-
setMessage(`Installed: ${result.installed.join(", ") || "none"} · Skipped: ${result.skipped.join(", ") || "none"}`);
|
|
5312
|
-
await refreshStatus(scope);
|
|
5313
|
-
} catch (err) {
|
|
5314
|
-
setMessage(err?.message || String(err));
|
|
5315
|
-
} finally {
|
|
5316
|
-
setBusy(null);
|
|
5317
|
-
setStep("done");
|
|
5318
|
-
}
|
|
5319
|
-
})();
|
|
5320
|
-
}
|
|
5321
|
-
}, undefined, false, undefined, this),
|
|
5322
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5323
|
-
dimColor: true,
|
|
5324
|
-
children: "Press Enter to continue, Esc to go back, or q to quit."
|
|
5325
|
-
}, undefined, false, undefined, this)
|
|
5326
|
-
]
|
|
5327
|
-
}, undefined, true, undefined, this);
|
|
5328
|
-
}
|
|
5329
|
-
if (step === "plugin-marketplace-input") {
|
|
5330
|
-
return /* @__PURE__ */ jsxDEV4(Screen, {
|
|
5331
|
-
children: [
|
|
5332
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5333
|
-
children: "Enter marketplace path or URL:"
|
|
5334
|
-
}, undefined, false, undefined, this),
|
|
5335
|
-
/* @__PURE__ */ jsxDEV4(TextInput, {
|
|
5336
|
-
value: marketplaceInput,
|
|
5337
|
-
onChange: setMarketplaceInput,
|
|
5338
|
-
onSubmit: () => {
|
|
5339
|
-
if (!scope)
|
|
5340
|
-
return;
|
|
5341
|
-
setBusy("Loading marketplace...");
|
|
5342
|
-
setStep("applying");
|
|
5343
|
-
(async () => {
|
|
5344
|
-
try {
|
|
5345
|
-
const loaded = await loadMarketplace(marketplaceInput);
|
|
5346
|
-
const plugins = loaded.json.plugins.map((p) => p.name);
|
|
5347
|
-
setMarketplacePlugins(plugins);
|
|
5348
|
-
setBusy(null);
|
|
5349
|
-
setStep("plugin-select");
|
|
5350
|
-
} catch (err) {
|
|
5351
|
-
setMessage(err?.message || String(err));
|
|
5352
|
-
setBusy(null);
|
|
5353
|
-
setStep("done");
|
|
5354
|
-
}
|
|
5355
|
-
})();
|
|
5356
|
-
}
|
|
5357
|
-
}, undefined, false, undefined, this),
|
|
5358
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5359
|
-
dimColor: true,
|
|
5360
|
-
children: "Press Enter to continue, Esc to go back, or q to quit."
|
|
5361
|
-
}, undefined, false, undefined, this)
|
|
5362
|
-
]
|
|
5363
|
-
}, undefined, true, undefined, this);
|
|
5364
|
-
}
|
|
5365
|
-
if (step === "plugin-select") {
|
|
5366
|
-
return /* @__PURE__ */ jsxDEV4(Screen, {
|
|
5367
|
-
children: [
|
|
5368
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5369
|
-
children: "Select plugin to install:"
|
|
5370
|
-
}, undefined, false, undefined, this),
|
|
5371
|
-
/* @__PURE__ */ jsxDEV4(SelectInput, {
|
|
5372
|
-
items: [
|
|
5373
|
-
{ label: "All plugins", value: "all" },
|
|
5374
|
-
...marketplacePlugins.map((p) => ({ label: p, value: p })),
|
|
5375
|
-
{ label: "Back", value: "back" }
|
|
5376
|
-
],
|
|
5377
|
-
onSelect: (item) => {
|
|
5378
|
-
if (!scope)
|
|
5379
|
-
return;
|
|
5380
|
-
if (item.value === "back") {
|
|
5381
|
-
setStep("action");
|
|
5382
|
-
return;
|
|
5383
|
-
}
|
|
5384
|
-
setBusy("Installing plugin(s)...");
|
|
5385
|
-
setStep("applying");
|
|
5386
|
-
(async () => {
|
|
5387
|
-
try {
|
|
5388
|
-
const result = await installMarketplace({
|
|
5389
|
-
marketplace: marketplaceInput,
|
|
5390
|
-
plugins: item.value === "all" ? "all" : [String(item.value)],
|
|
5391
|
-
scope
|
|
5392
|
-
});
|
|
5393
|
-
setMessage(`Installed commands: ${result.installedCommands.length}, hooks: ${result.installedHooks.length}, skills: ${result.installedSkills.length}`);
|
|
5394
|
-
await refreshStatus(scope);
|
|
5395
|
-
} catch (err) {
|
|
5396
|
-
setMessage(err?.message || String(err));
|
|
5397
|
-
} finally {
|
|
5398
|
-
setBusy(null);
|
|
5399
|
-
setStep("done");
|
|
5400
|
-
}
|
|
5401
|
-
})();
|
|
5402
|
-
}
|
|
5403
|
-
}, undefined, false, undefined, this),
|
|
5404
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5405
|
-
dimColor: true,
|
|
5406
|
-
children: "Press Esc to go back, or q to quit."
|
|
5407
|
-
}, undefined, false, undefined, this)
|
|
5408
|
-
]
|
|
5409
|
-
}, undefined, true, undefined, this);
|
|
5410
|
-
}
|
|
5411
|
-
if (step === "done") {
|
|
5412
|
-
return /* @__PURE__ */ jsxDEV4(Screen, {
|
|
5413
|
-
children: [
|
|
5414
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5415
|
-
children: message || "Done."
|
|
5416
|
-
}, undefined, false, undefined, this),
|
|
5417
|
-
/* @__PURE__ */ jsxDEV4(Text2, {
|
|
5418
|
-
dimColor: true,
|
|
5419
|
-
children: "Press Enter to continue, Esc to go back, or q to quit."
|
|
5420
|
-
}, 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" }
|
|
5421
5753
|
]
|
|
5422
|
-
}
|
|
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;
|
|
5423
5764
|
}
|
|
5424
|
-
|
|
5425
|
-
|
|
5426
|
-
|
|
5427
|
-
|
|
5428
|
-
|
|
5429
|
-
|
|
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
|
+
});
|