@oh-my-pi/cli 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/icon.png +0 -0
- package/.github/logo.png +0 -0
- package/.github/workflows/publish.yml +1 -1
- package/LICENSE +21 -0
- package/README.md +131 -145
- package/biome.json +1 -1
- package/dist/cli.js +2032 -1136
- package/dist/commands/create.d.ts.map +1 -1
- package/dist/commands/doctor.d.ts +1 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/enable.d.ts +1 -0
- package/dist/commands/enable.d.ts.map +1 -1
- package/dist/commands/info.d.ts +1 -0
- package/dist/commands/info.d.ts.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/install.d.ts +1 -0
- package/dist/commands/install.d.ts.map +1 -1
- package/dist/commands/link.d.ts +2 -0
- package/dist/commands/link.d.ts.map +1 -1
- package/dist/commands/list.d.ts +1 -0
- package/dist/commands/list.d.ts.map +1 -1
- package/dist/commands/outdated.d.ts +1 -0
- package/dist/commands/outdated.d.ts.map +1 -1
- package/dist/commands/search.d.ts.map +1 -1
- package/dist/commands/uninstall.d.ts +1 -0
- package/dist/commands/uninstall.d.ts.map +1 -1
- package/dist/commands/update.d.ts +1 -0
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/why.d.ts +1 -0
- package/dist/commands/why.d.ts.map +1 -1
- package/dist/conflicts.d.ts +9 -1
- package/dist/conflicts.d.ts.map +1 -1
- package/dist/errors.d.ts +8 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/index.d.ts +19 -19
- package/dist/index.d.ts.map +1 -1
- package/dist/lock.d.ts +3 -0
- package/dist/lock.d.ts.map +1 -0
- package/dist/lockfile.d.ts +52 -0
- package/dist/lockfile.d.ts.map +1 -0
- package/dist/manifest.d.ts +5 -0
- package/dist/manifest.d.ts.map +1 -1
- package/dist/migrate.d.ts.map +1 -1
- package/dist/npm.d.ts +14 -2
- package/dist/npm.d.ts.map +1 -1
- package/dist/paths.d.ts +34 -2
- package/dist/paths.d.ts.map +1 -1
- package/dist/symlinks.d.ts +10 -4
- package/dist/symlinks.d.ts.map +1 -1
- package/package.json +7 -2
- package/plugins/metal-theme/package.json +6 -1
- package/plugins/subagents/package.json +6 -1
- package/src/cli.ts +69 -43
- package/src/commands/create.ts +51 -1
- package/src/commands/doctor.ts +95 -7
- package/src/commands/enable.ts +25 -8
- package/src/commands/info.ts +41 -5
- package/src/commands/init.ts +20 -2
- package/src/commands/install.ts +266 -52
- package/src/commands/link.ts +60 -9
- package/src/commands/list.ts +10 -5
- package/src/commands/outdated.ts +17 -6
- package/src/commands/search.ts +20 -3
- package/src/commands/uninstall.ts +57 -6
- package/src/commands/update.ts +67 -9
- package/src/commands/why.ts +47 -16
- package/src/conflicts.ts +33 -1
- package/src/errors.ts +22 -0
- package/src/index.ts +19 -25
- package/src/lock.ts +46 -0
- package/src/lockfile.ts +132 -0
- package/src/manifest.ts +143 -35
- package/src/migrate.ts +14 -3
- package/src/npm.ts +74 -18
- package/src/paths.ts +77 -9
- package/src/symlinks.ts +134 -17
- package/tsconfig.json +7 -3
- package/CHECK.md +0 -352
package/dist/cli.js
CHANGED
|
@@ -17,203 +17,826 @@ var __toESM = (mod, isNodeMode, target) => {
|
|
|
17
17
|
return to;
|
|
18
18
|
};
|
|
19
19
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
20
|
+
var __export = (target, all) => {
|
|
21
|
+
for (var name in all)
|
|
22
|
+
__defProp(target, name, {
|
|
23
|
+
get: all[name],
|
|
24
|
+
enumerable: true,
|
|
25
|
+
configurable: true,
|
|
26
|
+
set: (newValue) => all[name] = () => newValue
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
20
30
|
var __require = import.meta.require;
|
|
21
31
|
|
|
22
|
-
// node_modules/
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
+
// node_modules/chalk/source/vendor/ansi-styles/index.js
|
|
33
|
+
function assembleStyles() {
|
|
34
|
+
const codes = new Map;
|
|
35
|
+
for (const [groupName, group] of Object.entries(styles)) {
|
|
36
|
+
for (const [styleName, style] of Object.entries(group)) {
|
|
37
|
+
styles[styleName] = {
|
|
38
|
+
open: `\x1B[${style[0]}m`,
|
|
39
|
+
close: `\x1B[${style[1]}m`
|
|
40
|
+
};
|
|
41
|
+
group[styleName] = styles[styleName];
|
|
42
|
+
codes.set(style[0], style[1]);
|
|
32
43
|
}
|
|
44
|
+
Object.defineProperty(styles, groupName, {
|
|
45
|
+
value: group,
|
|
46
|
+
enumerable: false
|
|
47
|
+
});
|
|
33
48
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
49
|
+
Object.defineProperty(styles, "codes", {
|
|
50
|
+
value: codes,
|
|
51
|
+
enumerable: false
|
|
52
|
+
});
|
|
53
|
+
styles.color.close = "\x1B[39m";
|
|
54
|
+
styles.bgColor.close = "\x1B[49m";
|
|
55
|
+
styles.color.ansi = wrapAnsi16();
|
|
56
|
+
styles.color.ansi256 = wrapAnsi256();
|
|
57
|
+
styles.color.ansi16m = wrapAnsi16m();
|
|
58
|
+
styles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET);
|
|
59
|
+
styles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET);
|
|
60
|
+
styles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET);
|
|
61
|
+
Object.defineProperties(styles, {
|
|
62
|
+
rgbToAnsi256: {
|
|
63
|
+
value(red, green, blue) {
|
|
64
|
+
if (red === green && green === blue) {
|
|
65
|
+
if (red < 8) {
|
|
66
|
+
return 16;
|
|
67
|
+
}
|
|
68
|
+
if (red > 248) {
|
|
69
|
+
return 231;
|
|
70
|
+
}
|
|
71
|
+
return Math.round((red - 8) / 247 * 24) + 232;
|
|
72
|
+
}
|
|
73
|
+
return 16 + 36 * Math.round(red / 255 * 5) + 6 * Math.round(green / 255 * 5) + Math.round(blue / 255 * 5);
|
|
74
|
+
},
|
|
75
|
+
enumerable: false
|
|
76
|
+
},
|
|
77
|
+
hexToRgb: {
|
|
78
|
+
value(hex) {
|
|
79
|
+
const matches = /[a-f\d]{6}|[a-f\d]{3}/i.exec(hex.toString(16));
|
|
80
|
+
if (!matches) {
|
|
81
|
+
return [0, 0, 0];
|
|
82
|
+
}
|
|
83
|
+
let [colorString] = matches;
|
|
84
|
+
if (colorString.length === 3) {
|
|
85
|
+
colorString = [...colorString].map((character) => character + character).join("");
|
|
86
|
+
}
|
|
87
|
+
const integer = Number.parseInt(colorString, 16);
|
|
88
|
+
return [
|
|
89
|
+
integer >> 16 & 255,
|
|
90
|
+
integer >> 8 & 255,
|
|
91
|
+
integer & 255
|
|
92
|
+
];
|
|
93
|
+
},
|
|
94
|
+
enumerable: false
|
|
95
|
+
},
|
|
96
|
+
hexToAnsi256: {
|
|
97
|
+
value: (hex) => styles.rgbToAnsi256(...styles.hexToRgb(hex)),
|
|
98
|
+
enumerable: false
|
|
99
|
+
},
|
|
100
|
+
ansi256ToAnsi: {
|
|
101
|
+
value(code) {
|
|
102
|
+
if (code < 8) {
|
|
103
|
+
return 30 + code;
|
|
104
|
+
}
|
|
105
|
+
if (code < 16) {
|
|
106
|
+
return 90 + (code - 8);
|
|
107
|
+
}
|
|
108
|
+
let red;
|
|
109
|
+
let green;
|
|
110
|
+
let blue;
|
|
111
|
+
if (code >= 232) {
|
|
112
|
+
red = ((code - 232) * 10 + 8) / 255;
|
|
113
|
+
green = red;
|
|
114
|
+
blue = red;
|
|
115
|
+
} else {
|
|
116
|
+
code -= 16;
|
|
117
|
+
const remainder = code % 36;
|
|
118
|
+
red = Math.floor(code / 36) / 5;
|
|
119
|
+
green = Math.floor(remainder / 6) / 5;
|
|
120
|
+
blue = remainder % 6 / 5;
|
|
121
|
+
}
|
|
122
|
+
const value = Math.max(red, green, blue) * 2;
|
|
123
|
+
if (value === 0) {
|
|
124
|
+
return 30;
|
|
125
|
+
}
|
|
126
|
+
let result = 30 + (Math.round(blue) << 2 | Math.round(green) << 1 | Math.round(red));
|
|
127
|
+
if (value === 2) {
|
|
128
|
+
result += 60;
|
|
129
|
+
}
|
|
130
|
+
return result;
|
|
131
|
+
},
|
|
132
|
+
enumerable: false
|
|
133
|
+
},
|
|
134
|
+
rgbToAnsi: {
|
|
135
|
+
value: (red, green, blue) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)),
|
|
136
|
+
enumerable: false
|
|
137
|
+
},
|
|
138
|
+
hexToAnsi: {
|
|
139
|
+
value: (hex) => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)),
|
|
140
|
+
enumerable: false
|
|
40
141
|
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
|
|
142
|
+
});
|
|
143
|
+
return styles;
|
|
144
|
+
}
|
|
145
|
+
var ANSI_BACKGROUND_OFFSET = 10, wrapAnsi16 = (offset = 0) => (code) => `\x1B[${code + offset}m`, wrapAnsi256 = (offset = 0) => (code) => `\x1B[${38 + offset};5;${code}m`, wrapAnsi16m = (offset = 0) => (red, green, blue) => `\x1B[${38 + offset};2;${red};${green};${blue}m`, styles, modifierNames, foregroundColorNames, backgroundColorNames, colorNames, ansiStyles, ansi_styles_default;
|
|
146
|
+
var init_ansi_styles = __esm(() => {
|
|
147
|
+
styles = {
|
|
148
|
+
modifier: {
|
|
149
|
+
reset: [0, 0],
|
|
150
|
+
bold: [1, 22],
|
|
151
|
+
dim: [2, 22],
|
|
152
|
+
italic: [3, 23],
|
|
153
|
+
underline: [4, 24],
|
|
154
|
+
overline: [53, 55],
|
|
155
|
+
inverse: [7, 27],
|
|
156
|
+
hidden: [8, 28],
|
|
157
|
+
strikethrough: [9, 29]
|
|
158
|
+
},
|
|
159
|
+
color: {
|
|
160
|
+
black: [30, 39],
|
|
161
|
+
red: [31, 39],
|
|
162
|
+
green: [32, 39],
|
|
163
|
+
yellow: [33, 39],
|
|
164
|
+
blue: [34, 39],
|
|
165
|
+
magenta: [35, 39],
|
|
166
|
+
cyan: [36, 39],
|
|
167
|
+
white: [37, 39],
|
|
168
|
+
blackBright: [90, 39],
|
|
169
|
+
gray: [90, 39],
|
|
170
|
+
grey: [90, 39],
|
|
171
|
+
redBright: [91, 39],
|
|
172
|
+
greenBright: [92, 39],
|
|
173
|
+
yellowBright: [93, 39],
|
|
174
|
+
blueBright: [94, 39],
|
|
175
|
+
magentaBright: [95, 39],
|
|
176
|
+
cyanBright: [96, 39],
|
|
177
|
+
whiteBright: [97, 39]
|
|
178
|
+
},
|
|
179
|
+
bgColor: {
|
|
180
|
+
bgBlack: [40, 49],
|
|
181
|
+
bgRed: [41, 49],
|
|
182
|
+
bgGreen: [42, 49],
|
|
183
|
+
bgYellow: [43, 49],
|
|
184
|
+
bgBlue: [44, 49],
|
|
185
|
+
bgMagenta: [45, 49],
|
|
186
|
+
bgCyan: [46, 49],
|
|
187
|
+
bgWhite: [47, 49],
|
|
188
|
+
bgBlackBright: [100, 49],
|
|
189
|
+
bgGray: [100, 49],
|
|
190
|
+
bgGrey: [100, 49],
|
|
191
|
+
bgRedBright: [101, 49],
|
|
192
|
+
bgGreenBright: [102, 49],
|
|
193
|
+
bgYellowBright: [103, 49],
|
|
194
|
+
bgBlueBright: [104, 49],
|
|
195
|
+
bgMagentaBright: [105, 49],
|
|
196
|
+
bgCyanBright: [106, 49],
|
|
197
|
+
bgWhiteBright: [107, 49]
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
modifierNames = Object.keys(styles.modifier);
|
|
201
|
+
foregroundColorNames = Object.keys(styles.color);
|
|
202
|
+
backgroundColorNames = Object.keys(styles.bgColor);
|
|
203
|
+
colorNames = [...foregroundColorNames, ...backgroundColorNames];
|
|
204
|
+
ansiStyles = assembleStyles();
|
|
205
|
+
ansi_styles_default = ansiStyles;
|
|
44
206
|
});
|
|
45
207
|
|
|
46
|
-
// node_modules/
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
this.required = true;
|
|
61
|
-
this._name = name.slice(1, -1);
|
|
62
|
-
break;
|
|
63
|
-
case "[":
|
|
64
|
-
this.required = false;
|
|
65
|
-
this._name = name.slice(1, -1);
|
|
66
|
-
break;
|
|
67
|
-
default:
|
|
68
|
-
this.required = true;
|
|
69
|
-
this._name = name;
|
|
70
|
-
break;
|
|
71
|
-
}
|
|
72
|
-
if (this._name.length > 3 && this._name.slice(-3) === "...") {
|
|
73
|
-
this.variadic = true;
|
|
74
|
-
this._name = this._name.slice(0, -3);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
name() {
|
|
78
|
-
return this._name;
|
|
79
|
-
}
|
|
80
|
-
_concatValue(value, previous) {
|
|
81
|
-
if (previous === this.defaultValue || !Array.isArray(previous)) {
|
|
82
|
-
return [value];
|
|
83
|
-
}
|
|
84
|
-
return previous.concat(value);
|
|
85
|
-
}
|
|
86
|
-
default(value, description) {
|
|
87
|
-
this.defaultValue = value;
|
|
88
|
-
this.defaultValueDescription = description;
|
|
89
|
-
return this;
|
|
90
|
-
}
|
|
91
|
-
argParser(fn) {
|
|
92
|
-
this.parseArg = fn;
|
|
93
|
-
return this;
|
|
208
|
+
// node_modules/chalk/source/vendor/supports-color/index.js
|
|
209
|
+
import process2 from "process";
|
|
210
|
+
import os from "os";
|
|
211
|
+
import tty from "tty";
|
|
212
|
+
function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process2.argv) {
|
|
213
|
+
const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
|
|
214
|
+
const position = argv.indexOf(prefix + flag);
|
|
215
|
+
const terminatorPosition = argv.indexOf("--");
|
|
216
|
+
return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
|
|
217
|
+
}
|
|
218
|
+
function envForceColor() {
|
|
219
|
+
if ("FORCE_COLOR" in env) {
|
|
220
|
+
if (env.FORCE_COLOR === "true") {
|
|
221
|
+
return 1;
|
|
94
222
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
this.parseArg = (arg, previous) => {
|
|
98
|
-
if (!this.argChoices.includes(arg)) {
|
|
99
|
-
throw new InvalidArgumentError(`Allowed choices are ${this.argChoices.join(", ")}.`);
|
|
100
|
-
}
|
|
101
|
-
if (this.variadic) {
|
|
102
|
-
return this._concatValue(arg, previous);
|
|
103
|
-
}
|
|
104
|
-
return arg;
|
|
105
|
-
};
|
|
106
|
-
return this;
|
|
223
|
+
if (env.FORCE_COLOR === "false") {
|
|
224
|
+
return 0;
|
|
107
225
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
226
|
+
return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
function translateLevel(level) {
|
|
230
|
+
if (level === 0) {
|
|
231
|
+
return false;
|
|
232
|
+
}
|
|
233
|
+
return {
|
|
234
|
+
level,
|
|
235
|
+
hasBasic: true,
|
|
236
|
+
has256: level >= 2,
|
|
237
|
+
has16m: level >= 3
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
|
|
241
|
+
const noFlagForceColor = envForceColor();
|
|
242
|
+
if (noFlagForceColor !== undefined) {
|
|
243
|
+
flagForceColor = noFlagForceColor;
|
|
244
|
+
}
|
|
245
|
+
const forceColor = sniffFlags ? flagForceColor : noFlagForceColor;
|
|
246
|
+
if (forceColor === 0) {
|
|
247
|
+
return 0;
|
|
248
|
+
}
|
|
249
|
+
if (sniffFlags) {
|
|
250
|
+
if (hasFlag("color=16m") || hasFlag("color=full") || hasFlag("color=truecolor")) {
|
|
251
|
+
return 3;
|
|
111
252
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
return this;
|
|
253
|
+
if (hasFlag("color=256")) {
|
|
254
|
+
return 2;
|
|
115
255
|
}
|
|
116
256
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
return arg.required ? "<" + nameOutput + ">" : "[" + nameOutput + "]";
|
|
257
|
+
if ("TF_BUILD" in env && "AGENT_NAME" in env) {
|
|
258
|
+
return 1;
|
|
120
259
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
this.sortSubcommands = false;
|
|
133
|
-
this.sortOptions = false;
|
|
134
|
-
this.showGlobalOptions = false;
|
|
135
|
-
}
|
|
136
|
-
visibleCommands(cmd) {
|
|
137
|
-
const visibleCommands = cmd.commands.filter((cmd2) => !cmd2._hidden);
|
|
138
|
-
const helpCommand = cmd._getHelpCommand();
|
|
139
|
-
if (helpCommand && !helpCommand._hidden) {
|
|
140
|
-
visibleCommands.push(helpCommand);
|
|
141
|
-
}
|
|
142
|
-
if (this.sortSubcommands) {
|
|
143
|
-
visibleCommands.sort((a, b) => {
|
|
144
|
-
return a.name().localeCompare(b.name());
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
return visibleCommands;
|
|
260
|
+
if (haveStream && !streamIsTTY && forceColor === undefined) {
|
|
261
|
+
return 0;
|
|
262
|
+
}
|
|
263
|
+
const min = forceColor || 0;
|
|
264
|
+
if (env.TERM === "dumb") {
|
|
265
|
+
return min;
|
|
266
|
+
}
|
|
267
|
+
if (process2.platform === "win32") {
|
|
268
|
+
const osRelease = os.release().split(".");
|
|
269
|
+
if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
|
|
270
|
+
return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
148
271
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
return
|
|
272
|
+
return 1;
|
|
273
|
+
}
|
|
274
|
+
if ("CI" in env) {
|
|
275
|
+
if (["GITHUB_ACTIONS", "GITEA_ACTIONS", "CIRCLECI"].some((key) => (key in env))) {
|
|
276
|
+
return 3;
|
|
154
277
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
const helpOption = cmd._getHelpOption();
|
|
158
|
-
if (helpOption && !helpOption.hidden) {
|
|
159
|
-
const removeShort = helpOption.short && cmd._findOption(helpOption.short);
|
|
160
|
-
const removeLong = helpOption.long && cmd._findOption(helpOption.long);
|
|
161
|
-
if (!removeShort && !removeLong) {
|
|
162
|
-
visibleOptions.push(helpOption);
|
|
163
|
-
} else if (helpOption.long && !removeLong) {
|
|
164
|
-
visibleOptions.push(cmd.createOption(helpOption.long, helpOption.description));
|
|
165
|
-
} else if (helpOption.short && !removeShort) {
|
|
166
|
-
visibleOptions.push(cmd.createOption(helpOption.short, helpOption.description));
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
if (this.sortOptions) {
|
|
170
|
-
visibleOptions.sort(this.compareOptions);
|
|
171
|
-
}
|
|
172
|
-
return visibleOptions;
|
|
278
|
+
if (["TRAVIS", "APPVEYOR", "GITLAB_CI", "BUILDKITE", "DRONE"].some((sign) => (sign in env)) || env.CI_NAME === "codeship") {
|
|
279
|
+
return 1;
|
|
173
280
|
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
281
|
+
return min;
|
|
282
|
+
}
|
|
283
|
+
if ("TEAMCITY_VERSION" in env) {
|
|
284
|
+
return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
|
|
285
|
+
}
|
|
286
|
+
if (env.COLORTERM === "truecolor") {
|
|
287
|
+
return 3;
|
|
288
|
+
}
|
|
289
|
+
if (env.TERM === "xterm-kitty") {
|
|
290
|
+
return 3;
|
|
291
|
+
}
|
|
292
|
+
if (env.TERM === "xterm-ghostty") {
|
|
293
|
+
return 3;
|
|
294
|
+
}
|
|
295
|
+
if (env.TERM === "wezterm") {
|
|
296
|
+
return 3;
|
|
297
|
+
}
|
|
298
|
+
if ("TERM_PROGRAM" in env) {
|
|
299
|
+
const version = Number.parseInt((env.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
|
|
300
|
+
switch (env.TERM_PROGRAM) {
|
|
301
|
+
case "iTerm.app": {
|
|
302
|
+
return version >= 3 ? 3 : 2;
|
|
181
303
|
}
|
|
182
|
-
|
|
183
|
-
|
|
304
|
+
case "Apple_Terminal": {
|
|
305
|
+
return 2;
|
|
184
306
|
}
|
|
185
|
-
return globalOptions;
|
|
186
307
|
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
308
|
+
}
|
|
309
|
+
if (/-256(color)?$/i.test(env.TERM)) {
|
|
310
|
+
return 2;
|
|
311
|
+
}
|
|
312
|
+
if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
|
|
313
|
+
return 1;
|
|
314
|
+
}
|
|
315
|
+
if ("COLORTERM" in env) {
|
|
316
|
+
return 1;
|
|
317
|
+
}
|
|
318
|
+
return min;
|
|
319
|
+
}
|
|
320
|
+
function createSupportsColor(stream, options = {}) {
|
|
321
|
+
const level = _supportsColor(stream, {
|
|
322
|
+
streamIsTTY: stream && stream.isTTY,
|
|
323
|
+
...options
|
|
324
|
+
});
|
|
325
|
+
return translateLevel(level);
|
|
326
|
+
}
|
|
327
|
+
var env, flagForceColor, supportsColor, supports_color_default;
|
|
328
|
+
var init_supports_color = __esm(() => {
|
|
329
|
+
({ env } = process2);
|
|
330
|
+
if (hasFlag("no-color") || hasFlag("no-colors") || hasFlag("color=false") || hasFlag("color=never")) {
|
|
331
|
+
flagForceColor = 0;
|
|
332
|
+
} else if (hasFlag("color") || hasFlag("colors") || hasFlag("color=true") || hasFlag("color=always")) {
|
|
333
|
+
flagForceColor = 1;
|
|
334
|
+
}
|
|
335
|
+
supportsColor = {
|
|
336
|
+
stdout: createSupportsColor({ isTTY: tty.isatty(1) }),
|
|
337
|
+
stderr: createSupportsColor({ isTTY: tty.isatty(2) })
|
|
338
|
+
};
|
|
339
|
+
supports_color_default = supportsColor;
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
// node_modules/chalk/source/utilities.js
|
|
343
|
+
function stringReplaceAll(string, substring, replacer) {
|
|
344
|
+
let index = string.indexOf(substring);
|
|
345
|
+
if (index === -1) {
|
|
346
|
+
return string;
|
|
347
|
+
}
|
|
348
|
+
const substringLength = substring.length;
|
|
349
|
+
let endIndex = 0;
|
|
350
|
+
let returnValue = "";
|
|
351
|
+
do {
|
|
352
|
+
returnValue += string.slice(endIndex, index) + substring + replacer;
|
|
353
|
+
endIndex = index + substringLength;
|
|
354
|
+
index = string.indexOf(substring, endIndex);
|
|
355
|
+
} while (index !== -1);
|
|
356
|
+
returnValue += string.slice(endIndex);
|
|
357
|
+
return returnValue;
|
|
358
|
+
}
|
|
359
|
+
function stringEncaseCRLFWithFirstIndex(string, prefix, postfix, index) {
|
|
360
|
+
let endIndex = 0;
|
|
361
|
+
let returnValue = "";
|
|
362
|
+
do {
|
|
363
|
+
const gotCR = string[index - 1] === "\r";
|
|
364
|
+
returnValue += string.slice(endIndex, gotCR ? index - 1 : index) + prefix + (gotCR ? `\r
|
|
365
|
+
` : `
|
|
366
|
+
`) + postfix;
|
|
367
|
+
endIndex = index + 1;
|
|
368
|
+
index = string.indexOf(`
|
|
369
|
+
`, endIndex);
|
|
370
|
+
} while (index !== -1);
|
|
371
|
+
returnValue += string.slice(endIndex);
|
|
372
|
+
return returnValue;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// node_modules/chalk/source/index.js
|
|
376
|
+
function createChalk(options) {
|
|
377
|
+
return chalkFactory(options);
|
|
378
|
+
}
|
|
379
|
+
var stdoutColor, stderrColor, GENERATOR, STYLER, IS_EMPTY, levelMapping, styles2, applyOptions = (object, options = {}) => {
|
|
380
|
+
if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) {
|
|
381
|
+
throw new Error("The `level` option should be an integer from 0 to 3");
|
|
382
|
+
}
|
|
383
|
+
const colorLevel = stdoutColor ? stdoutColor.level : 0;
|
|
384
|
+
object.level = options.level === undefined ? colorLevel : options.level;
|
|
385
|
+
}, chalkFactory = (options) => {
|
|
386
|
+
const chalk = (...strings) => strings.join(" ");
|
|
387
|
+
applyOptions(chalk, options);
|
|
388
|
+
Object.setPrototypeOf(chalk, createChalk.prototype);
|
|
389
|
+
return chalk;
|
|
390
|
+
}, getModelAnsi = (model, level, type, ...arguments_) => {
|
|
391
|
+
if (model === "rgb") {
|
|
392
|
+
if (level === "ansi16m") {
|
|
393
|
+
return ansi_styles_default[type].ansi16m(...arguments_);
|
|
197
394
|
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
return cmd._name + (cmd._aliases[0] ? "|" + cmd._aliases[0] : "") + (cmd.options.length ? " [options]" : "") + (args ? " " + args : "");
|
|
395
|
+
if (level === "ansi256") {
|
|
396
|
+
return ansi_styles_default[type].ansi256(ansi_styles_default.rgbToAnsi256(...arguments_));
|
|
201
397
|
}
|
|
202
|
-
|
|
203
|
-
|
|
398
|
+
return ansi_styles_default[type].ansi(ansi_styles_default.rgbToAnsi(...arguments_));
|
|
399
|
+
}
|
|
400
|
+
if (model === "hex") {
|
|
401
|
+
return getModelAnsi("rgb", level, type, ...ansi_styles_default.hexToRgb(...arguments_));
|
|
402
|
+
}
|
|
403
|
+
return ansi_styles_default[type][model](...arguments_);
|
|
404
|
+
}, usedModels, proto, createStyler = (open, close, parent) => {
|
|
405
|
+
let openAll;
|
|
406
|
+
let closeAll;
|
|
407
|
+
if (parent === undefined) {
|
|
408
|
+
openAll = open;
|
|
409
|
+
closeAll = close;
|
|
410
|
+
} else {
|
|
411
|
+
openAll = parent.openAll + open;
|
|
412
|
+
closeAll = close + parent.closeAll;
|
|
413
|
+
}
|
|
414
|
+
return {
|
|
415
|
+
open,
|
|
416
|
+
close,
|
|
417
|
+
openAll,
|
|
418
|
+
closeAll,
|
|
419
|
+
parent
|
|
420
|
+
};
|
|
421
|
+
}, createBuilder = (self, _styler, _isEmpty) => {
|
|
422
|
+
const builder = (...arguments_) => applyStyle(builder, arguments_.length === 1 ? "" + arguments_[0] : arguments_.join(" "));
|
|
423
|
+
Object.setPrototypeOf(builder, proto);
|
|
424
|
+
builder[GENERATOR] = self;
|
|
425
|
+
builder[STYLER] = _styler;
|
|
426
|
+
builder[IS_EMPTY] = _isEmpty;
|
|
427
|
+
return builder;
|
|
428
|
+
}, applyStyle = (self, string) => {
|
|
429
|
+
if (self.level <= 0 || !string) {
|
|
430
|
+
return self[IS_EMPTY] ? "" : string;
|
|
431
|
+
}
|
|
432
|
+
let styler = self[STYLER];
|
|
433
|
+
if (styler === undefined) {
|
|
434
|
+
return string;
|
|
435
|
+
}
|
|
436
|
+
const { openAll, closeAll } = styler;
|
|
437
|
+
if (string.includes("\x1B")) {
|
|
438
|
+
while (styler !== undefined) {
|
|
439
|
+
string = stringReplaceAll(string, styler.close, styler.open);
|
|
440
|
+
styler = styler.parent;
|
|
204
441
|
}
|
|
205
|
-
|
|
206
|
-
|
|
442
|
+
}
|
|
443
|
+
const lfIndex = string.indexOf(`
|
|
444
|
+
`);
|
|
445
|
+
if (lfIndex !== -1) {
|
|
446
|
+
string = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex);
|
|
447
|
+
}
|
|
448
|
+
return openAll + string + closeAll;
|
|
449
|
+
}, chalk, chalkStderr, source_default;
|
|
450
|
+
var init_source = __esm(() => {
|
|
451
|
+
init_ansi_styles();
|
|
452
|
+
init_supports_color();
|
|
453
|
+
({ stdout: stdoutColor, stderr: stderrColor } = supports_color_default);
|
|
454
|
+
GENERATOR = Symbol("GENERATOR");
|
|
455
|
+
STYLER = Symbol("STYLER");
|
|
456
|
+
IS_EMPTY = Symbol("IS_EMPTY");
|
|
457
|
+
levelMapping = [
|
|
458
|
+
"ansi",
|
|
459
|
+
"ansi",
|
|
460
|
+
"ansi256",
|
|
461
|
+
"ansi16m"
|
|
462
|
+
];
|
|
463
|
+
styles2 = Object.create(null);
|
|
464
|
+
Object.setPrototypeOf(createChalk.prototype, Function.prototype);
|
|
465
|
+
for (const [styleName, style] of Object.entries(ansi_styles_default)) {
|
|
466
|
+
styles2[styleName] = {
|
|
467
|
+
get() {
|
|
468
|
+
const builder = createBuilder(this, createStyler(style.open, style.close, this[STYLER]), this[IS_EMPTY]);
|
|
469
|
+
Object.defineProperty(this, styleName, { value: builder });
|
|
470
|
+
return builder;
|
|
471
|
+
}
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
styles2.visible = {
|
|
475
|
+
get() {
|
|
476
|
+
const builder = createBuilder(this, this[STYLER], true);
|
|
477
|
+
Object.defineProperty(this, "visible", { value: builder });
|
|
478
|
+
return builder;
|
|
207
479
|
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
480
|
+
};
|
|
481
|
+
usedModels = ["rgb", "hex", "ansi256"];
|
|
482
|
+
for (const model of usedModels) {
|
|
483
|
+
styles2[model] = {
|
|
484
|
+
get() {
|
|
485
|
+
const { level } = this;
|
|
486
|
+
return function(...arguments_) {
|
|
487
|
+
const styler = createStyler(getModelAnsi(model, levelMapping[level], "color", ...arguments_), ansi_styles_default.color.close, this[STYLER]);
|
|
488
|
+
return createBuilder(this, styler, this[IS_EMPTY]);
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
};
|
|
492
|
+
const bgModel = "bg" + model[0].toUpperCase() + model.slice(1);
|
|
493
|
+
styles2[bgModel] = {
|
|
494
|
+
get() {
|
|
495
|
+
const { level } = this;
|
|
496
|
+
return function(...arguments_) {
|
|
497
|
+
const styler = createStyler(getModelAnsi(model, levelMapping[level], "bgColor", ...arguments_), ansi_styles_default.bgColor.close, this[STYLER]);
|
|
498
|
+
return createBuilder(this, styler, this[IS_EMPTY]);
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
proto = Object.defineProperties(() => {}, {
|
|
504
|
+
...styles2,
|
|
505
|
+
level: {
|
|
506
|
+
enumerable: true,
|
|
507
|
+
get() {
|
|
508
|
+
return this[GENERATOR].level;
|
|
509
|
+
},
|
|
510
|
+
set(level) {
|
|
511
|
+
this[GENERATOR].level = level;
|
|
512
|
+
}
|
|
212
513
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
514
|
+
});
|
|
515
|
+
Object.defineProperties(createChalk.prototype, styles2);
|
|
516
|
+
chalk = createChalk();
|
|
517
|
+
chalkStderr = createChalk({ level: stderrColor ? stderrColor.level : 0 });
|
|
518
|
+
source_default = chalk;
|
|
519
|
+
});
|
|
520
|
+
|
|
521
|
+
// src/paths.ts
|
|
522
|
+
import { existsSync as existsSync2 } from "fs";
|
|
523
|
+
import { homedir } from "os";
|
|
524
|
+
import { dirname, join as join2, resolve } from "path";
|
|
525
|
+
function findProjectRoot() {
|
|
526
|
+
let dir = process.cwd();
|
|
527
|
+
const root = resolve("/");
|
|
528
|
+
while (dir !== root) {
|
|
529
|
+
if (existsSync2(join2(dir, ".pi", "plugins.json"))) {
|
|
530
|
+
return dir;
|
|
531
|
+
}
|
|
532
|
+
const parent = dirname(dir);
|
|
533
|
+
if (parent === dir)
|
|
534
|
+
break;
|
|
535
|
+
dir = parent;
|
|
536
|
+
}
|
|
537
|
+
return null;
|
|
538
|
+
}
|
|
539
|
+
function hasProjectPlugins() {
|
|
540
|
+
return findProjectRoot() !== null;
|
|
541
|
+
}
|
|
542
|
+
function resolveScope(options) {
|
|
543
|
+
if (options.global) {
|
|
544
|
+
return true;
|
|
545
|
+
}
|
|
546
|
+
if (options.local) {
|
|
547
|
+
return false;
|
|
548
|
+
}
|
|
549
|
+
return !hasProjectPlugins();
|
|
550
|
+
}
|
|
551
|
+
var PI_CONFIG_DIR, PLUGINS_DIR, NODE_MODULES_DIR, GLOBAL_PACKAGE_JSON, GLOBAL_LOCK_FILE, LEGACY_MANIFEST_PATH, PROJECT_PI_DIR = ".pi", PROJECT_PLUGINS_JSON, PROJECT_PACKAGE_JSON, PROJECT_PLUGINS_LOCK, PROJECT_NODE_MODULES;
|
|
552
|
+
var init_paths = __esm(() => {
|
|
553
|
+
PI_CONFIG_DIR = join2(homedir(), ".pi");
|
|
554
|
+
PLUGINS_DIR = join2(PI_CONFIG_DIR, "plugins");
|
|
555
|
+
NODE_MODULES_DIR = join2(PLUGINS_DIR, "node_modules");
|
|
556
|
+
GLOBAL_PACKAGE_JSON = join2(PLUGINS_DIR, "package.json");
|
|
557
|
+
GLOBAL_LOCK_FILE = join2(PLUGINS_DIR, "package-lock.json");
|
|
558
|
+
LEGACY_MANIFEST_PATH = join2(PLUGINS_DIR, "manifest.json");
|
|
559
|
+
PROJECT_PLUGINS_JSON = join2(PROJECT_PI_DIR, "plugins.json");
|
|
560
|
+
PROJECT_PACKAGE_JSON = join2(PROJECT_PI_DIR, "package.json");
|
|
561
|
+
PROJECT_PLUGINS_LOCK = join2(PROJECT_PI_DIR, "plugins-lock.json");
|
|
562
|
+
PROJECT_NODE_MODULES = join2(PROJECT_PI_DIR, "node_modules");
|
|
563
|
+
});
|
|
564
|
+
|
|
565
|
+
// src/lockfile.ts
|
|
566
|
+
var exports_lockfile = {};
|
|
567
|
+
__export(exports_lockfile, {
|
|
568
|
+
validateOrRegenerateLockFile: () => validateOrRegenerateLockFile,
|
|
569
|
+
updateLockFile: () => updateLockFile,
|
|
570
|
+
saveLockFile: () => saveLockFile,
|
|
571
|
+
loadLockFile: () => loadLockFile,
|
|
572
|
+
getLockedVersion: () => getLockedVersion,
|
|
573
|
+
createLockFile: () => createLockFile,
|
|
574
|
+
LOCKFILE_VERSION: () => LOCKFILE_VERSION
|
|
575
|
+
});
|
|
576
|
+
import { existsSync as existsSync7 } from "fs";
|
|
577
|
+
import { readFile as readFile2, writeFile as writeFile4 } from "fs/promises";
|
|
578
|
+
async function loadLockFile(global = true) {
|
|
579
|
+
const path = global ? GLOBAL_LOCK_FILE : PROJECT_PLUGINS_LOCK;
|
|
580
|
+
try {
|
|
581
|
+
if (!existsSync7(path))
|
|
582
|
+
return null;
|
|
583
|
+
const data = await readFile2(path, "utf-8");
|
|
584
|
+
const parsed = JSON.parse(data);
|
|
585
|
+
if (typeof parsed.lockfileVersion !== "number" || typeof parsed.packages !== "object") {
|
|
586
|
+
console.log(source_default.yellow(`Warning: ${path} has invalid schema, ignoring`));
|
|
587
|
+
return null;
|
|
588
|
+
}
|
|
589
|
+
if (parsed.lockfileVersion > LOCKFILE_VERSION) {
|
|
590
|
+
console.log(source_default.yellow(`Warning: ${path} was created by a newer version of omp (lockfile v${parsed.lockfileVersion}), ignoring`));
|
|
591
|
+
return null;
|
|
592
|
+
}
|
|
593
|
+
return parsed;
|
|
594
|
+
} catch (err) {
|
|
595
|
+
if (err.name === "SyntaxError") {
|
|
596
|
+
console.log(source_default.yellow(`Warning: ${path} is corrupted (invalid JSON), ignoring`));
|
|
597
|
+
}
|
|
598
|
+
return null;
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
async function saveLockFile(lockFile, global = true) {
|
|
602
|
+
const path = global ? GLOBAL_LOCK_FILE : PROJECT_PLUGINS_LOCK;
|
|
603
|
+
await writeFile4(path, JSON.stringify(lockFile, null, 2));
|
|
604
|
+
}
|
|
605
|
+
function createLockFile() {
|
|
606
|
+
return {
|
|
607
|
+
lockfileVersion: LOCKFILE_VERSION,
|
|
608
|
+
packages: {}
|
|
609
|
+
};
|
|
610
|
+
}
|
|
611
|
+
async function validateOrRegenerateLockFile(global = true) {
|
|
612
|
+
const existing = await loadLockFile(global);
|
|
613
|
+
if (existing) {
|
|
614
|
+
return existing;
|
|
615
|
+
}
|
|
616
|
+
const path = global ? GLOBAL_LOCK_FILE : PROJECT_PLUGINS_LOCK;
|
|
617
|
+
if (existsSync7(path)) {
|
|
618
|
+
console.log(source_default.yellow(`Regenerating corrupted lock file: ${path}`));
|
|
619
|
+
}
|
|
620
|
+
return createLockFile();
|
|
621
|
+
}
|
|
622
|
+
async function getLockedVersion(packageName, global = true) {
|
|
623
|
+
const lockFile = await loadLockFile(global);
|
|
624
|
+
if (!lockFile)
|
|
625
|
+
return null;
|
|
626
|
+
const entry = lockFile.packages[packageName];
|
|
627
|
+
return entry?.version ?? null;
|
|
628
|
+
}
|
|
629
|
+
async function updateLockFile(packageName, version, global = true) {
|
|
630
|
+
let lockFile = await loadLockFile(global);
|
|
631
|
+
if (!lockFile) {
|
|
632
|
+
lockFile = createLockFile();
|
|
633
|
+
}
|
|
634
|
+
lockFile.packages[packageName] = {
|
|
635
|
+
version
|
|
636
|
+
};
|
|
637
|
+
await saveLockFile(lockFile, global);
|
|
638
|
+
}
|
|
639
|
+
var LOCKFILE_VERSION = 1;
|
|
640
|
+
var init_lockfile = __esm(() => {
|
|
641
|
+
init_paths();
|
|
642
|
+
init_source();
|
|
643
|
+
});
|
|
644
|
+
|
|
645
|
+
// node_modules/commander/lib/error.js
|
|
646
|
+
var require_error = __commonJS((exports) => {
|
|
647
|
+
class CommanderError extends Error {
|
|
648
|
+
constructor(exitCode, code, message) {
|
|
649
|
+
super(message);
|
|
650
|
+
Error.captureStackTrace(this, this.constructor);
|
|
651
|
+
this.name = this.constructor.name;
|
|
652
|
+
this.code = code;
|
|
653
|
+
this.exitCode = exitCode;
|
|
654
|
+
this.nestedError = undefined;
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
class InvalidArgumentError extends CommanderError {
|
|
659
|
+
constructor(message) {
|
|
660
|
+
super(1, "commander.invalidArgument", message);
|
|
661
|
+
Error.captureStackTrace(this, this.constructor);
|
|
662
|
+
this.name = this.constructor.name;
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
exports.CommanderError = CommanderError;
|
|
666
|
+
exports.InvalidArgumentError = InvalidArgumentError;
|
|
667
|
+
});
|
|
668
|
+
|
|
669
|
+
// node_modules/commander/lib/argument.js
|
|
670
|
+
var require_argument = __commonJS((exports) => {
|
|
671
|
+
var { InvalidArgumentError } = require_error();
|
|
672
|
+
|
|
673
|
+
class Argument {
|
|
674
|
+
constructor(name, description) {
|
|
675
|
+
this.description = description || "";
|
|
676
|
+
this.variadic = false;
|
|
677
|
+
this.parseArg = undefined;
|
|
678
|
+
this.defaultValue = undefined;
|
|
679
|
+
this.defaultValueDescription = undefined;
|
|
680
|
+
this.argChoices = undefined;
|
|
681
|
+
switch (name[0]) {
|
|
682
|
+
case "<":
|
|
683
|
+
this.required = true;
|
|
684
|
+
this._name = name.slice(1, -1);
|
|
685
|
+
break;
|
|
686
|
+
case "[":
|
|
687
|
+
this.required = false;
|
|
688
|
+
this._name = name.slice(1, -1);
|
|
689
|
+
break;
|
|
690
|
+
default:
|
|
691
|
+
this.required = true;
|
|
692
|
+
this._name = name;
|
|
693
|
+
break;
|
|
694
|
+
}
|
|
695
|
+
if (this._name.length > 3 && this._name.slice(-3) === "...") {
|
|
696
|
+
this.variadic = true;
|
|
697
|
+
this._name = this._name.slice(0, -3);
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
name() {
|
|
701
|
+
return this._name;
|
|
702
|
+
}
|
|
703
|
+
_concatValue(value, previous) {
|
|
704
|
+
if (previous === this.defaultValue || !Array.isArray(previous)) {
|
|
705
|
+
return [value];
|
|
706
|
+
}
|
|
707
|
+
return previous.concat(value);
|
|
708
|
+
}
|
|
709
|
+
default(value, description) {
|
|
710
|
+
this.defaultValue = value;
|
|
711
|
+
this.defaultValueDescription = description;
|
|
712
|
+
return this;
|
|
713
|
+
}
|
|
714
|
+
argParser(fn) {
|
|
715
|
+
this.parseArg = fn;
|
|
716
|
+
return this;
|
|
717
|
+
}
|
|
718
|
+
choices(values) {
|
|
719
|
+
this.argChoices = values.slice();
|
|
720
|
+
this.parseArg = (arg, previous) => {
|
|
721
|
+
if (!this.argChoices.includes(arg)) {
|
|
722
|
+
throw new InvalidArgumentError(`Allowed choices are ${this.argChoices.join(", ")}.`);
|
|
723
|
+
}
|
|
724
|
+
if (this.variadic) {
|
|
725
|
+
return this._concatValue(arg, previous);
|
|
726
|
+
}
|
|
727
|
+
return arg;
|
|
728
|
+
};
|
|
729
|
+
return this;
|
|
730
|
+
}
|
|
731
|
+
argRequired() {
|
|
732
|
+
this.required = true;
|
|
733
|
+
return this;
|
|
734
|
+
}
|
|
735
|
+
argOptional() {
|
|
736
|
+
this.required = false;
|
|
737
|
+
return this;
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
function humanReadableArgName(arg) {
|
|
741
|
+
const nameOutput = arg.name() + (arg.variadic === true ? "..." : "");
|
|
742
|
+
return arg.required ? "<" + nameOutput + ">" : "[" + nameOutput + "]";
|
|
743
|
+
}
|
|
744
|
+
exports.Argument = Argument;
|
|
745
|
+
exports.humanReadableArgName = humanReadableArgName;
|
|
746
|
+
});
|
|
747
|
+
|
|
748
|
+
// node_modules/commander/lib/help.js
|
|
749
|
+
var require_help = __commonJS((exports) => {
|
|
750
|
+
var { humanReadableArgName } = require_argument();
|
|
751
|
+
|
|
752
|
+
class Help {
|
|
753
|
+
constructor() {
|
|
754
|
+
this.helpWidth = undefined;
|
|
755
|
+
this.sortSubcommands = false;
|
|
756
|
+
this.sortOptions = false;
|
|
757
|
+
this.showGlobalOptions = false;
|
|
758
|
+
}
|
|
759
|
+
visibleCommands(cmd) {
|
|
760
|
+
const visibleCommands = cmd.commands.filter((cmd2) => !cmd2._hidden);
|
|
761
|
+
const helpCommand = cmd._getHelpCommand();
|
|
762
|
+
if (helpCommand && !helpCommand._hidden) {
|
|
763
|
+
visibleCommands.push(helpCommand);
|
|
764
|
+
}
|
|
765
|
+
if (this.sortSubcommands) {
|
|
766
|
+
visibleCommands.sort((a, b) => {
|
|
767
|
+
return a.name().localeCompare(b.name());
|
|
768
|
+
});
|
|
769
|
+
}
|
|
770
|
+
return visibleCommands;
|
|
771
|
+
}
|
|
772
|
+
compareOptions(a, b) {
|
|
773
|
+
const getSortKey = (option) => {
|
|
774
|
+
return option.short ? option.short.replace(/^-/, "") : option.long.replace(/^--/, "");
|
|
775
|
+
};
|
|
776
|
+
return getSortKey(a).localeCompare(getSortKey(b));
|
|
777
|
+
}
|
|
778
|
+
visibleOptions(cmd) {
|
|
779
|
+
const visibleOptions = cmd.options.filter((option) => !option.hidden);
|
|
780
|
+
const helpOption = cmd._getHelpOption();
|
|
781
|
+
if (helpOption && !helpOption.hidden) {
|
|
782
|
+
const removeShort = helpOption.short && cmd._findOption(helpOption.short);
|
|
783
|
+
const removeLong = helpOption.long && cmd._findOption(helpOption.long);
|
|
784
|
+
if (!removeShort && !removeLong) {
|
|
785
|
+
visibleOptions.push(helpOption);
|
|
786
|
+
} else if (helpOption.long && !removeLong) {
|
|
787
|
+
visibleOptions.push(cmd.createOption(helpOption.long, helpOption.description));
|
|
788
|
+
} else if (helpOption.short && !removeShort) {
|
|
789
|
+
visibleOptions.push(cmd.createOption(helpOption.short, helpOption.description));
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
if (this.sortOptions) {
|
|
793
|
+
visibleOptions.sort(this.compareOptions);
|
|
794
|
+
}
|
|
795
|
+
return visibleOptions;
|
|
796
|
+
}
|
|
797
|
+
visibleGlobalOptions(cmd) {
|
|
798
|
+
if (!this.showGlobalOptions)
|
|
799
|
+
return [];
|
|
800
|
+
const globalOptions = [];
|
|
801
|
+
for (let ancestorCmd = cmd.parent;ancestorCmd; ancestorCmd = ancestorCmd.parent) {
|
|
802
|
+
const visibleOptions = ancestorCmd.options.filter((option) => !option.hidden);
|
|
803
|
+
globalOptions.push(...visibleOptions);
|
|
804
|
+
}
|
|
805
|
+
if (this.sortOptions) {
|
|
806
|
+
globalOptions.sort(this.compareOptions);
|
|
807
|
+
}
|
|
808
|
+
return globalOptions;
|
|
809
|
+
}
|
|
810
|
+
visibleArguments(cmd) {
|
|
811
|
+
if (cmd._argsDescription) {
|
|
812
|
+
cmd.registeredArguments.forEach((argument) => {
|
|
813
|
+
argument.description = argument.description || cmd._argsDescription[argument.name()] || "";
|
|
814
|
+
});
|
|
815
|
+
}
|
|
816
|
+
if (cmd.registeredArguments.find((argument) => argument.description)) {
|
|
817
|
+
return cmd.registeredArguments;
|
|
818
|
+
}
|
|
819
|
+
return [];
|
|
820
|
+
}
|
|
821
|
+
subcommandTerm(cmd) {
|
|
822
|
+
const args = cmd.registeredArguments.map((arg) => humanReadableArgName(arg)).join(" ");
|
|
823
|
+
return cmd._name + (cmd._aliases[0] ? "|" + cmd._aliases[0] : "") + (cmd.options.length ? " [options]" : "") + (args ? " " + args : "");
|
|
824
|
+
}
|
|
825
|
+
optionTerm(option) {
|
|
826
|
+
return option.flags;
|
|
827
|
+
}
|
|
828
|
+
argumentTerm(argument) {
|
|
829
|
+
return argument.name();
|
|
830
|
+
}
|
|
831
|
+
longestSubcommandTermLength(cmd, helper) {
|
|
832
|
+
return helper.visibleCommands(cmd).reduce((max, command) => {
|
|
833
|
+
return Math.max(max, helper.subcommandTerm(command).length);
|
|
834
|
+
}, 0);
|
|
835
|
+
}
|
|
836
|
+
longestOptionTermLength(cmd, helper) {
|
|
837
|
+
return helper.visibleOptions(cmd).reduce((max, option) => {
|
|
838
|
+
return Math.max(max, helper.optionTerm(option).length);
|
|
839
|
+
}, 0);
|
|
217
840
|
}
|
|
218
841
|
longestGlobalOptionTermLength(cmd, helper) {
|
|
219
842
|
return helper.visibleGlobalOptions(cmd).reduce((max, option) => {
|
|
@@ -601,7 +1224,7 @@ var require_command = __commonJS((exports) => {
|
|
|
601
1224
|
var childProcess = __require("child_process");
|
|
602
1225
|
var path = __require("path");
|
|
603
1226
|
var fs = __require("fs");
|
|
604
|
-
var
|
|
1227
|
+
var process3 = __require("process");
|
|
605
1228
|
var { Argument, humanReadableArgName } = require_argument();
|
|
606
1229
|
var { CommanderError } = require_error();
|
|
607
1230
|
var { Help } = require_help();
|
|
@@ -643,10 +1266,10 @@ var require_command = __commonJS((exports) => {
|
|
|
643
1266
|
this._showHelpAfterError = false;
|
|
644
1267
|
this._showSuggestionAfterError = true;
|
|
645
1268
|
this._outputConfiguration = {
|
|
646
|
-
writeOut: (str) =>
|
|
647
|
-
writeErr: (str) =>
|
|
648
|
-
getOutHelpWidth: () =>
|
|
649
|
-
getErrHelpWidth: () =>
|
|
1269
|
+
writeOut: (str) => process3.stdout.write(str),
|
|
1270
|
+
writeErr: (str) => process3.stderr.write(str),
|
|
1271
|
+
getOutHelpWidth: () => process3.stdout.isTTY ? process3.stdout.columns : undefined,
|
|
1272
|
+
getErrHelpWidth: () => process3.stderr.isTTY ? process3.stderr.columns : undefined,
|
|
650
1273
|
outputError: (str, write) => write(str)
|
|
651
1274
|
};
|
|
652
1275
|
this._hidden = false;
|
|
@@ -842,7 +1465,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
842
1465
|
if (this._exitCallback) {
|
|
843
1466
|
this._exitCallback(new CommanderError(exitCode, code, message));
|
|
844
1467
|
}
|
|
845
|
-
|
|
1468
|
+
process3.exit(exitCode);
|
|
846
1469
|
}
|
|
847
1470
|
action(fn) {
|
|
848
1471
|
const listener = (args) => {
|
|
@@ -1037,16 +1660,16 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1037
1660
|
}
|
|
1038
1661
|
parseOptions = parseOptions || {};
|
|
1039
1662
|
if (argv === undefined && parseOptions.from === undefined) {
|
|
1040
|
-
if (
|
|
1663
|
+
if (process3.versions?.electron) {
|
|
1041
1664
|
parseOptions.from = "electron";
|
|
1042
1665
|
}
|
|
1043
|
-
const execArgv =
|
|
1666
|
+
const execArgv = process3.execArgv ?? [];
|
|
1044
1667
|
if (execArgv.includes("-e") || execArgv.includes("--eval") || execArgv.includes("-p") || execArgv.includes("--print")) {
|
|
1045
1668
|
parseOptions.from = "eval";
|
|
1046
1669
|
}
|
|
1047
1670
|
}
|
|
1048
1671
|
if (argv === undefined) {
|
|
1049
|
-
argv =
|
|
1672
|
+
argv = process3.argv;
|
|
1050
1673
|
}
|
|
1051
1674
|
this.rawArgs = argv.slice();
|
|
1052
1675
|
let userArgs;
|
|
@@ -1057,7 +1680,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1057
1680
|
userArgs = argv.slice(2);
|
|
1058
1681
|
break;
|
|
1059
1682
|
case "electron":
|
|
1060
|
-
if (
|
|
1683
|
+
if (process3.defaultApp) {
|
|
1061
1684
|
this._scriptPath = argv[1];
|
|
1062
1685
|
userArgs = argv.slice(2);
|
|
1063
1686
|
} else {
|
|
@@ -1128,23 +1751,23 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1128
1751
|
}
|
|
1129
1752
|
launchWithNode = sourceExt.includes(path.extname(executableFile));
|
|
1130
1753
|
let proc;
|
|
1131
|
-
if (
|
|
1754
|
+
if (process3.platform !== "win32") {
|
|
1132
1755
|
if (launchWithNode) {
|
|
1133
1756
|
args.unshift(executableFile);
|
|
1134
|
-
args = incrementNodeInspectorPort(
|
|
1135
|
-
proc = childProcess.spawn(
|
|
1757
|
+
args = incrementNodeInspectorPort(process3.execArgv).concat(args);
|
|
1758
|
+
proc = childProcess.spawn(process3.argv[0], args, { stdio: "inherit" });
|
|
1136
1759
|
} else {
|
|
1137
1760
|
proc = childProcess.spawn(executableFile, args, { stdio: "inherit" });
|
|
1138
1761
|
}
|
|
1139
1762
|
} else {
|
|
1140
1763
|
args.unshift(executableFile);
|
|
1141
|
-
args = incrementNodeInspectorPort(
|
|
1142
|
-
proc = childProcess.spawn(
|
|
1764
|
+
args = incrementNodeInspectorPort(process3.execArgv).concat(args);
|
|
1765
|
+
proc = childProcess.spawn(process3.execPath, args, { stdio: "inherit" });
|
|
1143
1766
|
}
|
|
1144
1767
|
if (!proc.killed) {
|
|
1145
1768
|
const signals = ["SIGUSR1", "SIGUSR2", "SIGTERM", "SIGINT", "SIGHUP"];
|
|
1146
1769
|
signals.forEach((signal) => {
|
|
1147
|
-
|
|
1770
|
+
process3.on(signal, () => {
|
|
1148
1771
|
if (proc.killed === false && proc.exitCode === null) {
|
|
1149
1772
|
proc.kill(signal);
|
|
1150
1773
|
}
|
|
@@ -1155,7 +1778,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1155
1778
|
proc.on("close", (code) => {
|
|
1156
1779
|
code = code ?? 1;
|
|
1157
1780
|
if (!exitCallback) {
|
|
1158
|
-
|
|
1781
|
+
process3.exit(code);
|
|
1159
1782
|
} else {
|
|
1160
1783
|
exitCallback(new CommanderError(code, "commander.executeSubCommandAsync", "(close)"));
|
|
1161
1784
|
}
|
|
@@ -1172,7 +1795,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1172
1795
|
throw new Error(`'${executableFile}' not executable`);
|
|
1173
1796
|
}
|
|
1174
1797
|
if (!exitCallback) {
|
|
1175
|
-
|
|
1798
|
+
process3.exit(1);
|
|
1176
1799
|
} else {
|
|
1177
1800
|
const wrappedError = new CommanderError(1, "commander.executeSubCommandAsync", "(error)");
|
|
1178
1801
|
wrappedError.nestedError = err;
|
|
@@ -1520,11 +2143,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1520
2143
|
}
|
|
1521
2144
|
_parseOptionsEnv() {
|
|
1522
2145
|
this.options.forEach((option) => {
|
|
1523
|
-
if (option.envVar && option.envVar in
|
|
2146
|
+
if (option.envVar && option.envVar in process3.env) {
|
|
1524
2147
|
const optionKey = option.attributeName();
|
|
1525
2148
|
if (this.getOptionValue(optionKey) === undefined || ["default", "config", "env"].includes(this.getOptionValueSource(optionKey))) {
|
|
1526
2149
|
if (option.required || option.optional) {
|
|
1527
|
-
this.emit(`optionEnv:${option.name()}`,
|
|
2150
|
+
this.emit(`optionEnv:${option.name()}`, process3.env[option.envVar]);
|
|
1528
2151
|
} else {
|
|
1529
2152
|
this.emit(`optionEnv:${option.name()}`);
|
|
1530
2153
|
}
|
|
@@ -1637,743 +2260,271 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1637
2260
|
}
|
|
1638
2261
|
description(str, argsDescription) {
|
|
1639
2262
|
if (str === undefined && argsDescription === undefined)
|
|
1640
|
-
return this._description;
|
|
1641
|
-
this._description = str;
|
|
1642
|
-
if (argsDescription) {
|
|
1643
|
-
this._argsDescription = argsDescription;
|
|
1644
|
-
}
|
|
1645
|
-
return this;
|
|
1646
|
-
}
|
|
1647
|
-
summary(str) {
|
|
1648
|
-
if (str === undefined)
|
|
1649
|
-
return this._summary;
|
|
1650
|
-
this._summary = str;
|
|
1651
|
-
return this;
|
|
1652
|
-
}
|
|
1653
|
-
alias(alias) {
|
|
1654
|
-
if (alias === undefined)
|
|
1655
|
-
return this._aliases[0];
|
|
1656
|
-
let command = this;
|
|
1657
|
-
if (this.commands.length !== 0 && this.commands[this.commands.length - 1]._executableHandler) {
|
|
1658
|
-
command = this.commands[this.commands.length - 1];
|
|
1659
|
-
}
|
|
1660
|
-
if (alias === command._name)
|
|
1661
|
-
throw new Error("Command alias can't be the same as its name");
|
|
1662
|
-
const matchingCommand = this.parent?._findCommand(alias);
|
|
1663
|
-
if (matchingCommand) {
|
|
1664
|
-
const existingCmd = [matchingCommand.name()].concat(matchingCommand.aliases()).join("|");
|
|
1665
|
-
throw new Error(`cannot add alias '${alias}' to command '${this.name()}' as already have command '${existingCmd}'`);
|
|
1666
|
-
}
|
|
1667
|
-
command._aliases.push(alias);
|
|
1668
|
-
return this;
|
|
1669
|
-
}
|
|
1670
|
-
aliases(aliases) {
|
|
1671
|
-
if (aliases === undefined)
|
|
1672
|
-
return this._aliases;
|
|
1673
|
-
aliases.forEach((alias) => this.alias(alias));
|
|
1674
|
-
return this;
|
|
1675
|
-
}
|
|
1676
|
-
usage(str) {
|
|
1677
|
-
if (str === undefined) {
|
|
1678
|
-
if (this._usage)
|
|
1679
|
-
return this._usage;
|
|
1680
|
-
const args = this.registeredArguments.map((arg) => {
|
|
1681
|
-
return humanReadableArgName(arg);
|
|
1682
|
-
});
|
|
1683
|
-
return [].concat(this.options.length || this._helpOption !== null ? "[options]" : [], this.commands.length ? "[command]" : [], this.registeredArguments.length ? args : []).join(" ");
|
|
1684
|
-
}
|
|
1685
|
-
this._usage = str;
|
|
1686
|
-
return this;
|
|
1687
|
-
}
|
|
1688
|
-
name(str) {
|
|
1689
|
-
if (str === undefined)
|
|
1690
|
-
return this._name;
|
|
1691
|
-
this._name = str;
|
|
1692
|
-
return this;
|
|
1693
|
-
}
|
|
1694
|
-
nameFromFilename(filename) {
|
|
1695
|
-
this._name = path.basename(filename, path.extname(filename));
|
|
1696
|
-
return this;
|
|
1697
|
-
}
|
|
1698
|
-
executableDir(path2) {
|
|
1699
|
-
if (path2 === undefined)
|
|
1700
|
-
return this._executableDir;
|
|
1701
|
-
this._executableDir = path2;
|
|
1702
|
-
return this;
|
|
1703
|
-
}
|
|
1704
|
-
helpInformation(contextOptions) {
|
|
1705
|
-
const helper = this.createHelp();
|
|
1706
|
-
if (helper.helpWidth === undefined) {
|
|
1707
|
-
helper.helpWidth = contextOptions && contextOptions.error ? this._outputConfiguration.getErrHelpWidth() : this._outputConfiguration.getOutHelpWidth();
|
|
1708
|
-
}
|
|
1709
|
-
return helper.formatHelp(this, helper);
|
|
1710
|
-
}
|
|
1711
|
-
_getHelpContext(contextOptions) {
|
|
1712
|
-
contextOptions = contextOptions || {};
|
|
1713
|
-
const context = { error: !!contextOptions.error };
|
|
1714
|
-
let write;
|
|
1715
|
-
if (context.error) {
|
|
1716
|
-
write = (arg) => this._outputConfiguration.writeErr(arg);
|
|
1717
|
-
} else {
|
|
1718
|
-
write = (arg) => this._outputConfiguration.writeOut(arg);
|
|
1719
|
-
}
|
|
1720
|
-
context.write = contextOptions.write || write;
|
|
1721
|
-
context.command = this;
|
|
1722
|
-
return context;
|
|
1723
|
-
}
|
|
1724
|
-
outputHelp(contextOptions) {
|
|
1725
|
-
let deprecatedCallback;
|
|
1726
|
-
if (typeof contextOptions === "function") {
|
|
1727
|
-
deprecatedCallback = contextOptions;
|
|
1728
|
-
contextOptions = undefined;
|
|
1729
|
-
}
|
|
1730
|
-
const context = this._getHelpContext(contextOptions);
|
|
1731
|
-
this._getCommandAndAncestors().reverse().forEach((command) => command.emit("beforeAllHelp", context));
|
|
1732
|
-
this.emit("beforeHelp", context);
|
|
1733
|
-
let helpInformation = this.helpInformation(context);
|
|
1734
|
-
if (deprecatedCallback) {
|
|
1735
|
-
helpInformation = deprecatedCallback(helpInformation);
|
|
1736
|
-
if (typeof helpInformation !== "string" && !Buffer.isBuffer(helpInformation)) {
|
|
1737
|
-
throw new Error("outputHelp callback must return a string or a Buffer");
|
|
1738
|
-
}
|
|
1739
|
-
}
|
|
1740
|
-
context.write(helpInformation);
|
|
1741
|
-
if (this._getHelpOption()?.long) {
|
|
1742
|
-
this.emit(this._getHelpOption().long);
|
|
1743
|
-
}
|
|
1744
|
-
this.emit("afterHelp", context);
|
|
1745
|
-
this._getCommandAndAncestors().forEach((command) => command.emit("afterAllHelp", context));
|
|
1746
|
-
}
|
|
1747
|
-
helpOption(flags, description) {
|
|
1748
|
-
if (typeof flags === "boolean") {
|
|
1749
|
-
if (flags) {
|
|
1750
|
-
this._helpOption = this._helpOption ?? undefined;
|
|
1751
|
-
} else {
|
|
1752
|
-
this._helpOption = null;
|
|
1753
|
-
}
|
|
1754
|
-
return this;
|
|
1755
|
-
}
|
|
1756
|
-
flags = flags ?? "-h, --help";
|
|
1757
|
-
description = description ?? "display help for command";
|
|
1758
|
-
this._helpOption = this.createOption(flags, description);
|
|
1759
|
-
return this;
|
|
1760
|
-
}
|
|
1761
|
-
_getHelpOption() {
|
|
1762
|
-
if (this._helpOption === undefined) {
|
|
1763
|
-
this.helpOption(undefined, undefined);
|
|
1764
|
-
}
|
|
1765
|
-
return this._helpOption;
|
|
1766
|
-
}
|
|
1767
|
-
addHelpOption(option) {
|
|
1768
|
-
this._helpOption = option;
|
|
1769
|
-
return this;
|
|
1770
|
-
}
|
|
1771
|
-
help(contextOptions) {
|
|
1772
|
-
this.outputHelp(contextOptions);
|
|
1773
|
-
let exitCode = process2.exitCode || 0;
|
|
1774
|
-
if (exitCode === 0 && contextOptions && typeof contextOptions !== "function" && contextOptions.error) {
|
|
1775
|
-
exitCode = 1;
|
|
1776
|
-
}
|
|
1777
|
-
this._exit(exitCode, "commander.help", "(outputHelp)");
|
|
1778
|
-
}
|
|
1779
|
-
addHelpText(position, text) {
|
|
1780
|
-
const allowedValues = ["beforeAll", "before", "after", "afterAll"];
|
|
1781
|
-
if (!allowedValues.includes(position)) {
|
|
1782
|
-
throw new Error(`Unexpected value for position to addHelpText.
|
|
1783
|
-
Expecting one of '${allowedValues.join("', '")}'`);
|
|
1784
|
-
}
|
|
1785
|
-
const helpEvent = `${position}Help`;
|
|
1786
|
-
this.on(helpEvent, (context) => {
|
|
1787
|
-
let helpStr;
|
|
1788
|
-
if (typeof text === "function") {
|
|
1789
|
-
helpStr = text({ error: context.error, command: context.command });
|
|
1790
|
-
} else {
|
|
1791
|
-
helpStr = text;
|
|
1792
|
-
}
|
|
1793
|
-
if (helpStr) {
|
|
1794
|
-
context.write(`${helpStr}
|
|
1795
|
-
`);
|
|
1796
|
-
}
|
|
1797
|
-
});
|
|
1798
|
-
return this;
|
|
1799
|
-
}
|
|
1800
|
-
_outputHelpIfRequested(args) {
|
|
1801
|
-
const helpOption = this._getHelpOption();
|
|
1802
|
-
const helpRequested = helpOption && args.find((arg) => helpOption.is(arg));
|
|
1803
|
-
if (helpRequested) {
|
|
1804
|
-
this.outputHelp();
|
|
1805
|
-
this._exit(0, "commander.helpDisplayed", "(outputHelp)");
|
|
1806
|
-
}
|
|
1807
|
-
}
|
|
1808
|
-
}
|
|
1809
|
-
function incrementNodeInspectorPort(args) {
|
|
1810
|
-
return args.map((arg) => {
|
|
1811
|
-
if (!arg.startsWith("--inspect")) {
|
|
1812
|
-
return arg;
|
|
1813
|
-
}
|
|
1814
|
-
let debugOption;
|
|
1815
|
-
let debugHost = "127.0.0.1";
|
|
1816
|
-
let debugPort = "9229";
|
|
1817
|
-
let match;
|
|
1818
|
-
if ((match = arg.match(/^(--inspect(-brk)?)$/)) !== null) {
|
|
1819
|
-
debugOption = match[1];
|
|
1820
|
-
} else if ((match = arg.match(/^(--inspect(-brk|-port)?)=([^:]+)$/)) !== null) {
|
|
1821
|
-
debugOption = match[1];
|
|
1822
|
-
if (/^\d+$/.test(match[3])) {
|
|
1823
|
-
debugPort = match[3];
|
|
1824
|
-
} else {
|
|
1825
|
-
debugHost = match[3];
|
|
1826
|
-
}
|
|
1827
|
-
} else if ((match = arg.match(/^(--inspect(-brk|-port)?)=([^:]+):(\d+)$/)) !== null) {
|
|
1828
|
-
debugOption = match[1];
|
|
1829
|
-
debugHost = match[3];
|
|
1830
|
-
debugPort = match[4];
|
|
1831
|
-
}
|
|
1832
|
-
if (debugOption && debugPort !== "0") {
|
|
1833
|
-
return `${debugOption}=${debugHost}:${parseInt(debugPort) + 1}`;
|
|
1834
|
-
}
|
|
1835
|
-
return arg;
|
|
1836
|
-
});
|
|
1837
|
-
}
|
|
1838
|
-
exports.Command = Command;
|
|
1839
|
-
});
|
|
1840
|
-
|
|
1841
|
-
// node_modules/commander/index.js
|
|
1842
|
-
var require_commander = __commonJS((exports) => {
|
|
1843
|
-
var { Argument } = require_argument();
|
|
1844
|
-
var { Command } = require_command();
|
|
1845
|
-
var { CommanderError, InvalidArgumentError } = require_error();
|
|
1846
|
-
var { Help } = require_help();
|
|
1847
|
-
var { Option } = require_option();
|
|
1848
|
-
exports.program = new Command;
|
|
1849
|
-
exports.createCommand = (name) => new Command(name);
|
|
1850
|
-
exports.createOption = (flags, description) => new Option(flags, description);
|
|
1851
|
-
exports.createArgument = (name, description) => new Argument(name, description);
|
|
1852
|
-
exports.Command = Command;
|
|
1853
|
-
exports.Option = Option;
|
|
1854
|
-
exports.Argument = Argument;
|
|
1855
|
-
exports.Help = Help;
|
|
1856
|
-
exports.CommanderError = CommanderError;
|
|
1857
|
-
exports.InvalidArgumentError = InvalidArgumentError;
|
|
1858
|
-
exports.InvalidOptionArgumentError = InvalidArgumentError;
|
|
1859
|
-
});
|
|
1860
|
-
|
|
1861
|
-
// node_modules/commander/esm.mjs
|
|
1862
|
-
var import__ = __toESM(require_commander(), 1);
|
|
1863
|
-
var {
|
|
1864
|
-
program,
|
|
1865
|
-
createCommand,
|
|
1866
|
-
createArgument,
|
|
1867
|
-
createOption,
|
|
1868
|
-
CommanderError,
|
|
1869
|
-
InvalidArgumentError,
|
|
1870
|
-
InvalidOptionArgumentError,
|
|
1871
|
-
Command,
|
|
1872
|
-
Argument,
|
|
1873
|
-
Option,
|
|
1874
|
-
Help
|
|
1875
|
-
} = import__.default;
|
|
1876
|
-
|
|
1877
|
-
// src/commands/create.ts
|
|
1878
|
-
import { existsSync } from "fs";
|
|
1879
|
-
import { mkdir, writeFile } from "fs/promises";
|
|
1880
|
-
import { join } from "path";
|
|
1881
|
-
|
|
1882
|
-
// node_modules/chalk/source/vendor/ansi-styles/index.js
|
|
1883
|
-
var ANSI_BACKGROUND_OFFSET = 10;
|
|
1884
|
-
var wrapAnsi16 = (offset = 0) => (code) => `\x1B[${code + offset}m`;
|
|
1885
|
-
var wrapAnsi256 = (offset = 0) => (code) => `\x1B[${38 + offset};5;${code}m`;
|
|
1886
|
-
var wrapAnsi16m = (offset = 0) => (red, green, blue) => `\x1B[${38 + offset};2;${red};${green};${blue}m`;
|
|
1887
|
-
var styles = {
|
|
1888
|
-
modifier: {
|
|
1889
|
-
reset: [0, 0],
|
|
1890
|
-
bold: [1, 22],
|
|
1891
|
-
dim: [2, 22],
|
|
1892
|
-
italic: [3, 23],
|
|
1893
|
-
underline: [4, 24],
|
|
1894
|
-
overline: [53, 55],
|
|
1895
|
-
inverse: [7, 27],
|
|
1896
|
-
hidden: [8, 28],
|
|
1897
|
-
strikethrough: [9, 29]
|
|
1898
|
-
},
|
|
1899
|
-
color: {
|
|
1900
|
-
black: [30, 39],
|
|
1901
|
-
red: [31, 39],
|
|
1902
|
-
green: [32, 39],
|
|
1903
|
-
yellow: [33, 39],
|
|
1904
|
-
blue: [34, 39],
|
|
1905
|
-
magenta: [35, 39],
|
|
1906
|
-
cyan: [36, 39],
|
|
1907
|
-
white: [37, 39],
|
|
1908
|
-
blackBright: [90, 39],
|
|
1909
|
-
gray: [90, 39],
|
|
1910
|
-
grey: [90, 39],
|
|
1911
|
-
redBright: [91, 39],
|
|
1912
|
-
greenBright: [92, 39],
|
|
1913
|
-
yellowBright: [93, 39],
|
|
1914
|
-
blueBright: [94, 39],
|
|
1915
|
-
magentaBright: [95, 39],
|
|
1916
|
-
cyanBright: [96, 39],
|
|
1917
|
-
whiteBright: [97, 39]
|
|
1918
|
-
},
|
|
1919
|
-
bgColor: {
|
|
1920
|
-
bgBlack: [40, 49],
|
|
1921
|
-
bgRed: [41, 49],
|
|
1922
|
-
bgGreen: [42, 49],
|
|
1923
|
-
bgYellow: [43, 49],
|
|
1924
|
-
bgBlue: [44, 49],
|
|
1925
|
-
bgMagenta: [45, 49],
|
|
1926
|
-
bgCyan: [46, 49],
|
|
1927
|
-
bgWhite: [47, 49],
|
|
1928
|
-
bgBlackBright: [100, 49],
|
|
1929
|
-
bgGray: [100, 49],
|
|
1930
|
-
bgGrey: [100, 49],
|
|
1931
|
-
bgRedBright: [101, 49],
|
|
1932
|
-
bgGreenBright: [102, 49],
|
|
1933
|
-
bgYellowBright: [103, 49],
|
|
1934
|
-
bgBlueBright: [104, 49],
|
|
1935
|
-
bgMagentaBright: [105, 49],
|
|
1936
|
-
bgCyanBright: [106, 49],
|
|
1937
|
-
bgWhiteBright: [107, 49]
|
|
1938
|
-
}
|
|
1939
|
-
};
|
|
1940
|
-
var modifierNames = Object.keys(styles.modifier);
|
|
1941
|
-
var foregroundColorNames = Object.keys(styles.color);
|
|
1942
|
-
var backgroundColorNames = Object.keys(styles.bgColor);
|
|
1943
|
-
var colorNames = [...foregroundColorNames, ...backgroundColorNames];
|
|
1944
|
-
function assembleStyles() {
|
|
1945
|
-
const codes = new Map;
|
|
1946
|
-
for (const [groupName, group] of Object.entries(styles)) {
|
|
1947
|
-
for (const [styleName, style] of Object.entries(group)) {
|
|
1948
|
-
styles[styleName] = {
|
|
1949
|
-
open: `\x1B[${style[0]}m`,
|
|
1950
|
-
close: `\x1B[${style[1]}m`
|
|
1951
|
-
};
|
|
1952
|
-
group[styleName] = styles[styleName];
|
|
1953
|
-
codes.set(style[0], style[1]);
|
|
1954
|
-
}
|
|
1955
|
-
Object.defineProperty(styles, groupName, {
|
|
1956
|
-
value: group,
|
|
1957
|
-
enumerable: false
|
|
1958
|
-
});
|
|
1959
|
-
}
|
|
1960
|
-
Object.defineProperty(styles, "codes", {
|
|
1961
|
-
value: codes,
|
|
1962
|
-
enumerable: false
|
|
1963
|
-
});
|
|
1964
|
-
styles.color.close = "\x1B[39m";
|
|
1965
|
-
styles.bgColor.close = "\x1B[49m";
|
|
1966
|
-
styles.color.ansi = wrapAnsi16();
|
|
1967
|
-
styles.color.ansi256 = wrapAnsi256();
|
|
1968
|
-
styles.color.ansi16m = wrapAnsi16m();
|
|
1969
|
-
styles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET);
|
|
1970
|
-
styles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET);
|
|
1971
|
-
styles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET);
|
|
1972
|
-
Object.defineProperties(styles, {
|
|
1973
|
-
rgbToAnsi256: {
|
|
1974
|
-
value(red, green, blue) {
|
|
1975
|
-
if (red === green && green === blue) {
|
|
1976
|
-
if (red < 8) {
|
|
1977
|
-
return 16;
|
|
1978
|
-
}
|
|
1979
|
-
if (red > 248) {
|
|
1980
|
-
return 231;
|
|
1981
|
-
}
|
|
1982
|
-
return Math.round((red - 8) / 247 * 24) + 232;
|
|
1983
|
-
}
|
|
1984
|
-
return 16 + 36 * Math.round(red / 255 * 5) + 6 * Math.round(green / 255 * 5) + Math.round(blue / 255 * 5);
|
|
1985
|
-
},
|
|
1986
|
-
enumerable: false
|
|
1987
|
-
},
|
|
1988
|
-
hexToRgb: {
|
|
1989
|
-
value(hex) {
|
|
1990
|
-
const matches = /[a-f\d]{6}|[a-f\d]{3}/i.exec(hex.toString(16));
|
|
1991
|
-
if (!matches) {
|
|
1992
|
-
return [0, 0, 0];
|
|
1993
|
-
}
|
|
1994
|
-
let [colorString] = matches;
|
|
1995
|
-
if (colorString.length === 3) {
|
|
1996
|
-
colorString = [...colorString].map((character) => character + character).join("");
|
|
1997
|
-
}
|
|
1998
|
-
const integer = Number.parseInt(colorString, 16);
|
|
1999
|
-
return [
|
|
2000
|
-
integer >> 16 & 255,
|
|
2001
|
-
integer >> 8 & 255,
|
|
2002
|
-
integer & 255
|
|
2003
|
-
];
|
|
2004
|
-
},
|
|
2005
|
-
enumerable: false
|
|
2006
|
-
},
|
|
2007
|
-
hexToAnsi256: {
|
|
2008
|
-
value: (hex) => styles.rgbToAnsi256(...styles.hexToRgb(hex)),
|
|
2009
|
-
enumerable: false
|
|
2010
|
-
},
|
|
2011
|
-
ansi256ToAnsi: {
|
|
2012
|
-
value(code) {
|
|
2013
|
-
if (code < 8) {
|
|
2014
|
-
return 30 + code;
|
|
2015
|
-
}
|
|
2016
|
-
if (code < 16) {
|
|
2017
|
-
return 90 + (code - 8);
|
|
2018
|
-
}
|
|
2019
|
-
let red;
|
|
2020
|
-
let green;
|
|
2021
|
-
let blue;
|
|
2022
|
-
if (code >= 232) {
|
|
2023
|
-
red = ((code - 232) * 10 + 8) / 255;
|
|
2024
|
-
green = red;
|
|
2025
|
-
blue = red;
|
|
2026
|
-
} else {
|
|
2027
|
-
code -= 16;
|
|
2028
|
-
const remainder = code % 36;
|
|
2029
|
-
red = Math.floor(code / 36) / 5;
|
|
2030
|
-
green = Math.floor(remainder / 6) / 5;
|
|
2031
|
-
blue = remainder % 6 / 5;
|
|
2032
|
-
}
|
|
2033
|
-
const value = Math.max(red, green, blue) * 2;
|
|
2034
|
-
if (value === 0) {
|
|
2035
|
-
return 30;
|
|
2036
|
-
}
|
|
2037
|
-
let result = 30 + (Math.round(blue) << 2 | Math.round(green) << 1 | Math.round(red));
|
|
2038
|
-
if (value === 2) {
|
|
2039
|
-
result += 60;
|
|
2040
|
-
}
|
|
2041
|
-
return result;
|
|
2042
|
-
},
|
|
2043
|
-
enumerable: false
|
|
2044
|
-
},
|
|
2045
|
-
rgbToAnsi: {
|
|
2046
|
-
value: (red, green, blue) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)),
|
|
2047
|
-
enumerable: false
|
|
2048
|
-
},
|
|
2049
|
-
hexToAnsi: {
|
|
2050
|
-
value: (hex) => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)),
|
|
2051
|
-
enumerable: false
|
|
2263
|
+
return this._description;
|
|
2264
|
+
this._description = str;
|
|
2265
|
+
if (argsDescription) {
|
|
2266
|
+
this._argsDescription = argsDescription;
|
|
2267
|
+
}
|
|
2268
|
+
return this;
|
|
2052
2269
|
}
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
// node_modules/chalk/source/vendor/supports-color/index.js
|
|
2060
|
-
import process2 from "process";
|
|
2061
|
-
import os from "os";
|
|
2062
|
-
import tty from "tty";
|
|
2063
|
-
function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process2.argv) {
|
|
2064
|
-
const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
|
|
2065
|
-
const position = argv.indexOf(prefix + flag);
|
|
2066
|
-
const terminatorPosition = argv.indexOf("--");
|
|
2067
|
-
return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
|
|
2068
|
-
}
|
|
2069
|
-
var { env } = process2;
|
|
2070
|
-
var flagForceColor;
|
|
2071
|
-
if (hasFlag("no-color") || hasFlag("no-colors") || hasFlag("color=false") || hasFlag("color=never")) {
|
|
2072
|
-
flagForceColor = 0;
|
|
2073
|
-
} else if (hasFlag("color") || hasFlag("colors") || hasFlag("color=true") || hasFlag("color=always")) {
|
|
2074
|
-
flagForceColor = 1;
|
|
2075
|
-
}
|
|
2076
|
-
function envForceColor() {
|
|
2077
|
-
if ("FORCE_COLOR" in env) {
|
|
2078
|
-
if (env.FORCE_COLOR === "true") {
|
|
2079
|
-
return 1;
|
|
2270
|
+
summary(str) {
|
|
2271
|
+
if (str === undefined)
|
|
2272
|
+
return this._summary;
|
|
2273
|
+
this._summary = str;
|
|
2274
|
+
return this;
|
|
2080
2275
|
}
|
|
2081
|
-
|
|
2082
|
-
|
|
2276
|
+
alias(alias) {
|
|
2277
|
+
if (alias === undefined)
|
|
2278
|
+
return this._aliases[0];
|
|
2279
|
+
let command = this;
|
|
2280
|
+
if (this.commands.length !== 0 && this.commands[this.commands.length - 1]._executableHandler) {
|
|
2281
|
+
command = this.commands[this.commands.length - 1];
|
|
2282
|
+
}
|
|
2283
|
+
if (alias === command._name)
|
|
2284
|
+
throw new Error("Command alias can't be the same as its name");
|
|
2285
|
+
const matchingCommand = this.parent?._findCommand(alias);
|
|
2286
|
+
if (matchingCommand) {
|
|
2287
|
+
const existingCmd = [matchingCommand.name()].concat(matchingCommand.aliases()).join("|");
|
|
2288
|
+
throw new Error(`cannot add alias '${alias}' to command '${this.name()}' as already have command '${existingCmd}'`);
|
|
2289
|
+
}
|
|
2290
|
+
command._aliases.push(alias);
|
|
2291
|
+
return this;
|
|
2083
2292
|
}
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
return false;
|
|
2090
|
-
}
|
|
2091
|
-
return {
|
|
2092
|
-
level,
|
|
2093
|
-
hasBasic: true,
|
|
2094
|
-
has256: level >= 2,
|
|
2095
|
-
has16m: level >= 3
|
|
2096
|
-
};
|
|
2097
|
-
}
|
|
2098
|
-
function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
|
|
2099
|
-
const noFlagForceColor = envForceColor();
|
|
2100
|
-
if (noFlagForceColor !== undefined) {
|
|
2101
|
-
flagForceColor = noFlagForceColor;
|
|
2102
|
-
}
|
|
2103
|
-
const forceColor = sniffFlags ? flagForceColor : noFlagForceColor;
|
|
2104
|
-
if (forceColor === 0) {
|
|
2105
|
-
return 0;
|
|
2106
|
-
}
|
|
2107
|
-
if (sniffFlags) {
|
|
2108
|
-
if (hasFlag("color=16m") || hasFlag("color=full") || hasFlag("color=truecolor")) {
|
|
2109
|
-
return 3;
|
|
2293
|
+
aliases(aliases) {
|
|
2294
|
+
if (aliases === undefined)
|
|
2295
|
+
return this._aliases;
|
|
2296
|
+
aliases.forEach((alias) => this.alias(alias));
|
|
2297
|
+
return this;
|
|
2110
2298
|
}
|
|
2111
|
-
|
|
2112
|
-
|
|
2299
|
+
usage(str) {
|
|
2300
|
+
if (str === undefined) {
|
|
2301
|
+
if (this._usage)
|
|
2302
|
+
return this._usage;
|
|
2303
|
+
const args = this.registeredArguments.map((arg) => {
|
|
2304
|
+
return humanReadableArgName(arg);
|
|
2305
|
+
});
|
|
2306
|
+
return [].concat(this.options.length || this._helpOption !== null ? "[options]" : [], this.commands.length ? "[command]" : [], this.registeredArguments.length ? args : []).join(" ");
|
|
2307
|
+
}
|
|
2308
|
+
this._usage = str;
|
|
2309
|
+
return this;
|
|
2113
2310
|
}
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
return 0;
|
|
2120
|
-
}
|
|
2121
|
-
const min = forceColor || 0;
|
|
2122
|
-
if (env.TERM === "dumb") {
|
|
2123
|
-
return min;
|
|
2124
|
-
}
|
|
2125
|
-
if (process2.platform === "win32") {
|
|
2126
|
-
const osRelease = os.release().split(".");
|
|
2127
|
-
if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
|
|
2128
|
-
return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
2311
|
+
name(str) {
|
|
2312
|
+
if (str === undefined)
|
|
2313
|
+
return this._name;
|
|
2314
|
+
this._name = str;
|
|
2315
|
+
return this;
|
|
2129
2316
|
}
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
if (["GITHUB_ACTIONS", "GITEA_ACTIONS", "CIRCLECI"].some((key) => (key in env))) {
|
|
2134
|
-
return 3;
|
|
2317
|
+
nameFromFilename(filename) {
|
|
2318
|
+
this._name = path.basename(filename, path.extname(filename));
|
|
2319
|
+
return this;
|
|
2135
2320
|
}
|
|
2136
|
-
|
|
2137
|
-
|
|
2321
|
+
executableDir(path2) {
|
|
2322
|
+
if (path2 === undefined)
|
|
2323
|
+
return this._executableDir;
|
|
2324
|
+
this._executableDir = path2;
|
|
2325
|
+
return this;
|
|
2138
2326
|
}
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
}
|
|
2144
|
-
if (env.COLORTERM === "truecolor") {
|
|
2145
|
-
return 3;
|
|
2146
|
-
}
|
|
2147
|
-
if (env.TERM === "xterm-kitty") {
|
|
2148
|
-
return 3;
|
|
2149
|
-
}
|
|
2150
|
-
if (env.TERM === "xterm-ghostty") {
|
|
2151
|
-
return 3;
|
|
2152
|
-
}
|
|
2153
|
-
if (env.TERM === "wezterm") {
|
|
2154
|
-
return 3;
|
|
2155
|
-
}
|
|
2156
|
-
if ("TERM_PROGRAM" in env) {
|
|
2157
|
-
const version = Number.parseInt((env.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
|
|
2158
|
-
switch (env.TERM_PROGRAM) {
|
|
2159
|
-
case "iTerm.app": {
|
|
2160
|
-
return version >= 3 ? 3 : 2;
|
|
2327
|
+
helpInformation(contextOptions) {
|
|
2328
|
+
const helper = this.createHelp();
|
|
2329
|
+
if (helper.helpWidth === undefined) {
|
|
2330
|
+
helper.helpWidth = contextOptions && contextOptions.error ? this._outputConfiguration.getErrHelpWidth() : this._outputConfiguration.getOutHelpWidth();
|
|
2161
2331
|
}
|
|
2162
|
-
|
|
2163
|
-
|
|
2332
|
+
return helper.formatHelp(this, helper);
|
|
2333
|
+
}
|
|
2334
|
+
_getHelpContext(contextOptions) {
|
|
2335
|
+
contextOptions = contextOptions || {};
|
|
2336
|
+
const context = { error: !!contextOptions.error };
|
|
2337
|
+
let write;
|
|
2338
|
+
if (context.error) {
|
|
2339
|
+
write = (arg) => this._outputConfiguration.writeErr(arg);
|
|
2340
|
+
} else {
|
|
2341
|
+
write = (arg) => this._outputConfiguration.writeOut(arg);
|
|
2164
2342
|
}
|
|
2343
|
+
context.write = contextOptions.write || write;
|
|
2344
|
+
context.command = this;
|
|
2345
|
+
return context;
|
|
2165
2346
|
}
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
};
|
|
2189
|
-
var supports_color_default = supportsColor;
|
|
2190
|
-
|
|
2191
|
-
// node_modules/chalk/source/utilities.js
|
|
2192
|
-
function stringReplaceAll(string, substring, replacer) {
|
|
2193
|
-
let index = string.indexOf(substring);
|
|
2194
|
-
if (index === -1) {
|
|
2195
|
-
return string;
|
|
2196
|
-
}
|
|
2197
|
-
const substringLength = substring.length;
|
|
2198
|
-
let endIndex = 0;
|
|
2199
|
-
let returnValue = "";
|
|
2200
|
-
do {
|
|
2201
|
-
returnValue += string.slice(endIndex, index) + substring + replacer;
|
|
2202
|
-
endIndex = index + substringLength;
|
|
2203
|
-
index = string.indexOf(substring, endIndex);
|
|
2204
|
-
} while (index !== -1);
|
|
2205
|
-
returnValue += string.slice(endIndex);
|
|
2206
|
-
return returnValue;
|
|
2207
|
-
}
|
|
2208
|
-
function stringEncaseCRLFWithFirstIndex(string, prefix, postfix, index) {
|
|
2209
|
-
let endIndex = 0;
|
|
2210
|
-
let returnValue = "";
|
|
2211
|
-
do {
|
|
2212
|
-
const gotCR = string[index - 1] === "\r";
|
|
2213
|
-
returnValue += string.slice(endIndex, gotCR ? index - 1 : index) + prefix + (gotCR ? `\r
|
|
2214
|
-
` : `
|
|
2215
|
-
`) + postfix;
|
|
2216
|
-
endIndex = index + 1;
|
|
2217
|
-
index = string.indexOf(`
|
|
2218
|
-
`, endIndex);
|
|
2219
|
-
} while (index !== -1);
|
|
2220
|
-
returnValue += string.slice(endIndex);
|
|
2221
|
-
return returnValue;
|
|
2222
|
-
}
|
|
2223
|
-
|
|
2224
|
-
// node_modules/chalk/source/index.js
|
|
2225
|
-
var { stdout: stdoutColor, stderr: stderrColor } = supports_color_default;
|
|
2226
|
-
var GENERATOR = Symbol("GENERATOR");
|
|
2227
|
-
var STYLER = Symbol("STYLER");
|
|
2228
|
-
var IS_EMPTY = Symbol("IS_EMPTY");
|
|
2229
|
-
var levelMapping = [
|
|
2230
|
-
"ansi",
|
|
2231
|
-
"ansi",
|
|
2232
|
-
"ansi256",
|
|
2233
|
-
"ansi16m"
|
|
2234
|
-
];
|
|
2235
|
-
var styles2 = Object.create(null);
|
|
2236
|
-
var applyOptions = (object, options = {}) => {
|
|
2237
|
-
if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) {
|
|
2238
|
-
throw new Error("The `level` option should be an integer from 0 to 3");
|
|
2239
|
-
}
|
|
2240
|
-
const colorLevel = stdoutColor ? stdoutColor.level : 0;
|
|
2241
|
-
object.level = options.level === undefined ? colorLevel : options.level;
|
|
2242
|
-
};
|
|
2243
|
-
var chalkFactory = (options) => {
|
|
2244
|
-
const chalk = (...strings) => strings.join(" ");
|
|
2245
|
-
applyOptions(chalk, options);
|
|
2246
|
-
Object.setPrototypeOf(chalk, createChalk.prototype);
|
|
2247
|
-
return chalk;
|
|
2248
|
-
};
|
|
2249
|
-
function createChalk(options) {
|
|
2250
|
-
return chalkFactory(options);
|
|
2251
|
-
}
|
|
2252
|
-
Object.setPrototypeOf(createChalk.prototype, Function.prototype);
|
|
2253
|
-
for (const [styleName, style] of Object.entries(ansi_styles_default)) {
|
|
2254
|
-
styles2[styleName] = {
|
|
2255
|
-
get() {
|
|
2256
|
-
const builder = createBuilder(this, createStyler(style.open, style.close, this[STYLER]), this[IS_EMPTY]);
|
|
2257
|
-
Object.defineProperty(this, styleName, { value: builder });
|
|
2258
|
-
return builder;
|
|
2347
|
+
outputHelp(contextOptions) {
|
|
2348
|
+
let deprecatedCallback;
|
|
2349
|
+
if (typeof contextOptions === "function") {
|
|
2350
|
+
deprecatedCallback = contextOptions;
|
|
2351
|
+
contextOptions = undefined;
|
|
2352
|
+
}
|
|
2353
|
+
const context = this._getHelpContext(contextOptions);
|
|
2354
|
+
this._getCommandAndAncestors().reverse().forEach((command) => command.emit("beforeAllHelp", context));
|
|
2355
|
+
this.emit("beforeHelp", context);
|
|
2356
|
+
let helpInformation = this.helpInformation(context);
|
|
2357
|
+
if (deprecatedCallback) {
|
|
2358
|
+
helpInformation = deprecatedCallback(helpInformation);
|
|
2359
|
+
if (typeof helpInformation !== "string" && !Buffer.isBuffer(helpInformation)) {
|
|
2360
|
+
throw new Error("outputHelp callback must return a string or a Buffer");
|
|
2361
|
+
}
|
|
2362
|
+
}
|
|
2363
|
+
context.write(helpInformation);
|
|
2364
|
+
if (this._getHelpOption()?.long) {
|
|
2365
|
+
this.emit(this._getHelpOption().long);
|
|
2366
|
+
}
|
|
2367
|
+
this.emit("afterHelp", context);
|
|
2368
|
+
this._getCommandAndAncestors().forEach((command) => command.emit("afterAllHelp", context));
|
|
2259
2369
|
}
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
}
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
return
|
|
2370
|
+
helpOption(flags, description) {
|
|
2371
|
+
if (typeof flags === "boolean") {
|
|
2372
|
+
if (flags) {
|
|
2373
|
+
this._helpOption = this._helpOption ?? undefined;
|
|
2374
|
+
} else {
|
|
2375
|
+
this._helpOption = null;
|
|
2376
|
+
}
|
|
2377
|
+
return this;
|
|
2378
|
+
}
|
|
2379
|
+
flags = flags ?? "-h, --help";
|
|
2380
|
+
description = description ?? "display help for command";
|
|
2381
|
+
this._helpOption = this.createOption(flags, description);
|
|
2382
|
+
return this;
|
|
2273
2383
|
}
|
|
2274
|
-
|
|
2275
|
-
|
|
2384
|
+
_getHelpOption() {
|
|
2385
|
+
if (this._helpOption === undefined) {
|
|
2386
|
+
this.helpOption(undefined, undefined);
|
|
2387
|
+
}
|
|
2388
|
+
return this._helpOption;
|
|
2276
2389
|
}
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
return getModelAnsi("rgb", level, type, ...ansi_styles_default.hexToRgb(...arguments_));
|
|
2281
|
-
}
|
|
2282
|
-
return ansi_styles_default[type][model](...arguments_);
|
|
2283
|
-
};
|
|
2284
|
-
var usedModels = ["rgb", "hex", "ansi256"];
|
|
2285
|
-
for (const model of usedModels) {
|
|
2286
|
-
styles2[model] = {
|
|
2287
|
-
get() {
|
|
2288
|
-
const { level } = this;
|
|
2289
|
-
return function(...arguments_) {
|
|
2290
|
-
const styler = createStyler(getModelAnsi(model, levelMapping[level], "color", ...arguments_), ansi_styles_default.color.close, this[STYLER]);
|
|
2291
|
-
return createBuilder(this, styler, this[IS_EMPTY]);
|
|
2292
|
-
};
|
|
2390
|
+
addHelpOption(option) {
|
|
2391
|
+
this._helpOption = option;
|
|
2392
|
+
return this;
|
|
2293
2393
|
}
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
return createBuilder(this, styler, this[IS_EMPTY]);
|
|
2302
|
-
};
|
|
2394
|
+
help(contextOptions) {
|
|
2395
|
+
this.outputHelp(contextOptions);
|
|
2396
|
+
let exitCode = process3.exitCode || 0;
|
|
2397
|
+
if (exitCode === 0 && contextOptions && typeof contextOptions !== "function" && contextOptions.error) {
|
|
2398
|
+
exitCode = 1;
|
|
2399
|
+
}
|
|
2400
|
+
this._exit(exitCode, "commander.help", "(outputHelp)");
|
|
2303
2401
|
}
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2402
|
+
addHelpText(position, text) {
|
|
2403
|
+
const allowedValues = ["beforeAll", "before", "after", "afterAll"];
|
|
2404
|
+
if (!allowedValues.includes(position)) {
|
|
2405
|
+
throw new Error(`Unexpected value for position to addHelpText.
|
|
2406
|
+
Expecting one of '${allowedValues.join("', '")}'`);
|
|
2407
|
+
}
|
|
2408
|
+
const helpEvent = `${position}Help`;
|
|
2409
|
+
this.on(helpEvent, (context) => {
|
|
2410
|
+
let helpStr;
|
|
2411
|
+
if (typeof text === "function") {
|
|
2412
|
+
helpStr = text({ error: context.error, command: context.command });
|
|
2413
|
+
} else {
|
|
2414
|
+
helpStr = text;
|
|
2415
|
+
}
|
|
2416
|
+
if (helpStr) {
|
|
2417
|
+
context.write(`${helpStr}
|
|
2418
|
+
`);
|
|
2419
|
+
}
|
|
2420
|
+
});
|
|
2421
|
+
return this;
|
|
2315
2422
|
}
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
closeAll = close;
|
|
2324
|
-
} else {
|
|
2325
|
-
openAll = parent.openAll + open;
|
|
2326
|
-
closeAll = close + parent.closeAll;
|
|
2327
|
-
}
|
|
2328
|
-
return {
|
|
2329
|
-
open,
|
|
2330
|
-
close,
|
|
2331
|
-
openAll,
|
|
2332
|
-
closeAll,
|
|
2333
|
-
parent
|
|
2334
|
-
};
|
|
2335
|
-
};
|
|
2336
|
-
var createBuilder = (self, _styler, _isEmpty) => {
|
|
2337
|
-
const builder = (...arguments_) => applyStyle(builder, arguments_.length === 1 ? "" + arguments_[0] : arguments_.join(" "));
|
|
2338
|
-
Object.setPrototypeOf(builder, proto);
|
|
2339
|
-
builder[GENERATOR] = self;
|
|
2340
|
-
builder[STYLER] = _styler;
|
|
2341
|
-
builder[IS_EMPTY] = _isEmpty;
|
|
2342
|
-
return builder;
|
|
2343
|
-
};
|
|
2344
|
-
var applyStyle = (self, string) => {
|
|
2345
|
-
if (self.level <= 0 || !string) {
|
|
2346
|
-
return self[IS_EMPTY] ? "" : string;
|
|
2347
|
-
}
|
|
2348
|
-
let styler = self[STYLER];
|
|
2349
|
-
if (styler === undefined) {
|
|
2350
|
-
return string;
|
|
2351
|
-
}
|
|
2352
|
-
const { openAll, closeAll } = styler;
|
|
2353
|
-
if (string.includes("\x1B")) {
|
|
2354
|
-
while (styler !== undefined) {
|
|
2355
|
-
string = stringReplaceAll(string, styler.close, styler.open);
|
|
2356
|
-
styler = styler.parent;
|
|
2423
|
+
_outputHelpIfRequested(args) {
|
|
2424
|
+
const helpOption = this._getHelpOption();
|
|
2425
|
+
const helpRequested = helpOption && args.find((arg) => helpOption.is(arg));
|
|
2426
|
+
if (helpRequested) {
|
|
2427
|
+
this.outputHelp();
|
|
2428
|
+
this._exit(0, "commander.helpDisplayed", "(outputHelp)");
|
|
2429
|
+
}
|
|
2357
2430
|
}
|
|
2358
2431
|
}
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2432
|
+
function incrementNodeInspectorPort(args) {
|
|
2433
|
+
return args.map((arg) => {
|
|
2434
|
+
if (!arg.startsWith("--inspect")) {
|
|
2435
|
+
return arg;
|
|
2436
|
+
}
|
|
2437
|
+
let debugOption;
|
|
2438
|
+
let debugHost = "127.0.0.1";
|
|
2439
|
+
let debugPort = "9229";
|
|
2440
|
+
let match;
|
|
2441
|
+
if ((match = arg.match(/^(--inspect(-brk)?)$/)) !== null) {
|
|
2442
|
+
debugOption = match[1];
|
|
2443
|
+
} else if ((match = arg.match(/^(--inspect(-brk|-port)?)=([^:]+)$/)) !== null) {
|
|
2444
|
+
debugOption = match[1];
|
|
2445
|
+
if (/^\d+$/.test(match[3])) {
|
|
2446
|
+
debugPort = match[3];
|
|
2447
|
+
} else {
|
|
2448
|
+
debugHost = match[3];
|
|
2449
|
+
}
|
|
2450
|
+
} else if ((match = arg.match(/^(--inspect(-brk|-port)?)=([^:]+):(\d+)$/)) !== null) {
|
|
2451
|
+
debugOption = match[1];
|
|
2452
|
+
debugHost = match[3];
|
|
2453
|
+
debugPort = match[4];
|
|
2454
|
+
}
|
|
2455
|
+
if (debugOption && debugPort !== "0") {
|
|
2456
|
+
return `${debugOption}=${debugHost}:${parseInt(debugPort) + 1}`;
|
|
2457
|
+
}
|
|
2458
|
+
return arg;
|
|
2459
|
+
});
|
|
2363
2460
|
}
|
|
2364
|
-
|
|
2365
|
-
};
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
var
|
|
2369
|
-
var
|
|
2461
|
+
exports.Command = Command;
|
|
2462
|
+
});
|
|
2463
|
+
|
|
2464
|
+
// node_modules/commander/index.js
|
|
2465
|
+
var require_commander = __commonJS((exports) => {
|
|
2466
|
+
var { Argument } = require_argument();
|
|
2467
|
+
var { Command } = require_command();
|
|
2468
|
+
var { CommanderError, InvalidArgumentError } = require_error();
|
|
2469
|
+
var { Help } = require_help();
|
|
2470
|
+
var { Option } = require_option();
|
|
2471
|
+
exports.program = new Command;
|
|
2472
|
+
exports.createCommand = (name) => new Command(name);
|
|
2473
|
+
exports.createOption = (flags, description) => new Option(flags, description);
|
|
2474
|
+
exports.createArgument = (name, description) => new Argument(name, description);
|
|
2475
|
+
exports.Command = Command;
|
|
2476
|
+
exports.Option = Option;
|
|
2477
|
+
exports.Argument = Argument;
|
|
2478
|
+
exports.Help = Help;
|
|
2479
|
+
exports.CommanderError = CommanderError;
|
|
2480
|
+
exports.InvalidArgumentError = InvalidArgumentError;
|
|
2481
|
+
exports.InvalidOptionArgumentError = InvalidArgumentError;
|
|
2482
|
+
});
|
|
2370
2483
|
|
|
2371
2484
|
// src/commands/create.ts
|
|
2485
|
+
init_source();
|
|
2486
|
+
import { existsSync } from "fs";
|
|
2487
|
+
import { mkdir, writeFile } from "fs/promises";
|
|
2488
|
+
import { join } from "path";
|
|
2489
|
+
var VALID_NPM_CHARS = new Set("abcdefghijklmnopqrstuvwxyz0123456789-_.");
|
|
2490
|
+
function isValidNpmName(name) {
|
|
2491
|
+
if (!name || name.length === 0)
|
|
2492
|
+
return false;
|
|
2493
|
+
if (name.startsWith(".") || name.startsWith("_"))
|
|
2494
|
+
return false;
|
|
2495
|
+
if (name.includes(" "))
|
|
2496
|
+
return false;
|
|
2497
|
+
for (const char of name) {
|
|
2498
|
+
if (!VALID_NPM_CHARS.has(char))
|
|
2499
|
+
return false;
|
|
2500
|
+
}
|
|
2501
|
+
return true;
|
|
2502
|
+
}
|
|
2503
|
+
function normalizePluginName(name) {
|
|
2504
|
+
let normalized = name.toLowerCase().split(" ").join("-");
|
|
2505
|
+
normalized = Array.from(normalized).filter((char) => VALID_NPM_CHARS.has(char)).join("");
|
|
2506
|
+
while (normalized.startsWith(".") || normalized.startsWith("_") || normalized.startsWith("-")) {
|
|
2507
|
+
normalized = normalized.slice(1);
|
|
2508
|
+
}
|
|
2509
|
+
return normalized;
|
|
2510
|
+
}
|
|
2372
2511
|
async function createPlugin(name, options = {}) {
|
|
2373
|
-
|
|
2512
|
+
let pluginName = name.startsWith("omp-") ? name : `omp-${name}`;
|
|
2513
|
+
if (!isValidNpmName(pluginName)) {
|
|
2514
|
+
const normalized = normalizePluginName(pluginName);
|
|
2515
|
+
if (!normalized || normalized === "omp-" || normalized === "omp") {
|
|
2516
|
+
console.log(source_default.red(`Error: Invalid plugin name "${name}" cannot be normalized to a valid npm name`));
|
|
2517
|
+
process.exitCode = 1;
|
|
2518
|
+
return;
|
|
2519
|
+
}
|
|
2520
|
+
const finalName = normalized.startsWith("omp-") ? normalized : `omp-${normalized}`;
|
|
2521
|
+
console.log(source_default.yellow(`Invalid plugin name. Normalized to: ${finalName}`));
|
|
2522
|
+
pluginName = finalName;
|
|
2523
|
+
}
|
|
2374
2524
|
const pluginDir = pluginName;
|
|
2375
2525
|
if (existsSync(pluginDir)) {
|
|
2376
2526
|
console.log(source_default.red(`Error: Directory ${pluginDir} already exists`));
|
|
2527
|
+
process.exitCode = 1;
|
|
2377
2528
|
return;
|
|
2378
2529
|
}
|
|
2379
2530
|
console.log(source_default.blue(`Creating plugin: ${pluginName}...`));
|
|
@@ -2491,13 +2642,32 @@ Provide instructions for the agent here.
|
|
|
2491
2642
|
console.log(source_default.dim(" 5. Publish: npm publish"));
|
|
2492
2643
|
} catch (err) {
|
|
2493
2644
|
console.log(source_default.red(`Error creating plugin: ${err.message}`));
|
|
2645
|
+
process.exitCode = 1;
|
|
2494
2646
|
}
|
|
2495
2647
|
}
|
|
2496
2648
|
|
|
2497
2649
|
// src/commands/doctor.ts
|
|
2498
|
-
import { existsSync as
|
|
2650
|
+
import { existsSync as existsSync5 } from "fs";
|
|
2499
2651
|
|
|
2500
2652
|
// src/conflicts.ts
|
|
2653
|
+
function detectIntraPluginDuplicates(pkgJson) {
|
|
2654
|
+
const duplicates = [];
|
|
2655
|
+
if (!pkgJson.omp?.install?.length) {
|
|
2656
|
+
return duplicates;
|
|
2657
|
+
}
|
|
2658
|
+
const destMap = new Map;
|
|
2659
|
+
for (const entry of pkgJson.omp.install) {
|
|
2660
|
+
const sources = destMap.get(entry.dest) || [];
|
|
2661
|
+
sources.push(entry.src);
|
|
2662
|
+
destMap.set(entry.dest, sources);
|
|
2663
|
+
}
|
|
2664
|
+
for (const [dest, sources] of destMap) {
|
|
2665
|
+
if (sources.length > 1) {
|
|
2666
|
+
duplicates.push({ dest, sources });
|
|
2667
|
+
}
|
|
2668
|
+
}
|
|
2669
|
+
return duplicates;
|
|
2670
|
+
}
|
|
2501
2671
|
function detectConflicts(newPluginName, newPkgJson, existingPlugins) {
|
|
2502
2672
|
const conflicts = [];
|
|
2503
2673
|
if (!newPkgJson.omp?.install?.length) {
|
|
@@ -2551,36 +2721,63 @@ function formatConflicts(conflicts) {
|
|
|
2551
2721
|
}
|
|
2552
2722
|
|
|
2553
2723
|
// src/manifest.ts
|
|
2554
|
-
|
|
2724
|
+
init_paths();
|
|
2725
|
+
import { existsSync as existsSync3 } from "fs";
|
|
2555
2726
|
import { mkdir as mkdir2, readFile, writeFile as writeFile2 } from "fs/promises";
|
|
2556
|
-
import { dirname, join as join3 } from "path";
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
var NODE_MODULES_DIR = join2(PLUGINS_DIR, "node_modules");
|
|
2564
|
-
var GLOBAL_PACKAGE_JSON = join2(PLUGINS_DIR, "package.json");
|
|
2565
|
-
var GLOBAL_LOCK_FILE = join2(PLUGINS_DIR, "package-lock.json");
|
|
2566
|
-
var LEGACY_MANIFEST_PATH = join2(PLUGINS_DIR, "manifest.json");
|
|
2567
|
-
var PROJECT_PI_DIR = ".pi";
|
|
2568
|
-
var PROJECT_PLUGINS_JSON = join2(PROJECT_PI_DIR, "plugins.json");
|
|
2569
|
-
var PROJECT_PLUGINS_LOCK = join2(PROJECT_PI_DIR, "plugins-lock.json");
|
|
2570
|
-
var PROJECT_NODE_MODULES = join2(PROJECT_PI_DIR, "node_modules");
|
|
2571
|
-
|
|
2572
|
-
// src/manifest.ts
|
|
2727
|
+
import { dirname as dirname2, join as join3 } from "path";
|
|
2728
|
+
function formatPermissionError(err, path) {
|
|
2729
|
+
if (err.code === "EACCES" || err.code === "EPERM") {
|
|
2730
|
+
return `Permission denied: Cannot write to ${path}. Check directory permissions or run with appropriate privileges.`;
|
|
2731
|
+
}
|
|
2732
|
+
return err.message;
|
|
2733
|
+
}
|
|
2573
2734
|
async function initGlobalPlugins() {
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2735
|
+
try {
|
|
2736
|
+
await mkdir2(PLUGINS_DIR, { recursive: true });
|
|
2737
|
+
if (!existsSync3(GLOBAL_PACKAGE_JSON)) {
|
|
2738
|
+
const packageJson = {
|
|
2739
|
+
name: "pi-plugins",
|
|
2740
|
+
version: "1.0.0",
|
|
2741
|
+
private: true,
|
|
2742
|
+
description: "Global pi plugins managed by omp",
|
|
2743
|
+
dependencies: {}
|
|
2744
|
+
};
|
|
2745
|
+
await writeFile2(GLOBAL_PACKAGE_JSON, JSON.stringify(packageJson, null, 2));
|
|
2746
|
+
}
|
|
2747
|
+
} catch (err) {
|
|
2748
|
+
const error = err;
|
|
2749
|
+
if (error.code === "EACCES" || error.code === "EPERM") {
|
|
2750
|
+
throw new Error(formatPermissionError(error, PLUGINS_DIR));
|
|
2751
|
+
}
|
|
2752
|
+
throw err;
|
|
2753
|
+
}
|
|
2754
|
+
}
|
|
2755
|
+
async function initProjectPlugins() {
|
|
2756
|
+
const PROJECT_PI_DIR2 = dirname2(PROJECT_PLUGINS_JSON);
|
|
2757
|
+
try {
|
|
2758
|
+
await mkdir2(PROJECT_PI_DIR2, { recursive: true });
|
|
2759
|
+
if (!existsSync3(PROJECT_PLUGINS_JSON)) {
|
|
2760
|
+
const pluginsJson = {
|
|
2761
|
+
plugins: {}
|
|
2762
|
+
};
|
|
2763
|
+
await writeFile2(PROJECT_PLUGINS_JSON, JSON.stringify(pluginsJson, null, 2));
|
|
2764
|
+
}
|
|
2765
|
+
if (!existsSync3(PROJECT_PACKAGE_JSON)) {
|
|
2766
|
+
const packageJson = {
|
|
2767
|
+
name: "pi-project-plugins",
|
|
2768
|
+
version: "1.0.0",
|
|
2769
|
+
private: true,
|
|
2770
|
+
description: "Project-local pi plugins managed by omp",
|
|
2771
|
+
dependencies: {}
|
|
2772
|
+
};
|
|
2773
|
+
await writeFile2(PROJECT_PACKAGE_JSON, JSON.stringify(packageJson, null, 2));
|
|
2774
|
+
}
|
|
2775
|
+
} catch (err) {
|
|
2776
|
+
const error = err;
|
|
2777
|
+
if (error.code === "EACCES" || error.code === "EPERM") {
|
|
2778
|
+
throw new Error(formatPermissionError(error, PROJECT_PI_DIR2));
|
|
2779
|
+
}
|
|
2780
|
+
throw err;
|
|
2584
2781
|
}
|
|
2585
2782
|
}
|
|
2586
2783
|
async function loadPluginsJson(global = true) {
|
|
@@ -2591,42 +2788,85 @@ async function loadPluginsJson(global = true) {
|
|
|
2591
2788
|
if (global) {
|
|
2592
2789
|
return {
|
|
2593
2790
|
plugins: parsed.dependencies || {},
|
|
2791
|
+
devDependencies: parsed.devDependencies || {},
|
|
2594
2792
|
disabled: parsed.omp?.disabled || []
|
|
2595
2793
|
};
|
|
2596
2794
|
}
|
|
2597
2795
|
return {
|
|
2598
2796
|
plugins: parsed.plugins || {},
|
|
2797
|
+
devDependencies: parsed.devDependencies || {},
|
|
2599
2798
|
disabled: parsed.disabled || []
|
|
2600
2799
|
};
|
|
2601
2800
|
} catch (err) {
|
|
2602
2801
|
if (err.code === "ENOENT") {
|
|
2603
|
-
return { plugins: {}, disabled: [] };
|
|
2802
|
+
return { plugins: {}, devDependencies: {}, disabled: [] };
|
|
2604
2803
|
}
|
|
2605
2804
|
throw err;
|
|
2606
2805
|
}
|
|
2607
2806
|
}
|
|
2807
|
+
async function syncProjectPackageJson(data) {
|
|
2808
|
+
let existing = {};
|
|
2809
|
+
try {
|
|
2810
|
+
existing = JSON.parse(await readFile(PROJECT_PACKAGE_JSON, "utf-8"));
|
|
2811
|
+
} catch {
|
|
2812
|
+
existing = {
|
|
2813
|
+
name: "pi-project-plugins",
|
|
2814
|
+
version: "1.0.0",
|
|
2815
|
+
private: true,
|
|
2816
|
+
description: "Project-local pi plugins managed by omp"
|
|
2817
|
+
};
|
|
2818
|
+
}
|
|
2819
|
+
existing.dependencies = data.plugins;
|
|
2820
|
+
if (data.devDependencies && Object.keys(data.devDependencies).length > 0) {
|
|
2821
|
+
existing.devDependencies = data.devDependencies;
|
|
2822
|
+
} else {
|
|
2823
|
+
delete existing.devDependencies;
|
|
2824
|
+
}
|
|
2825
|
+
await writeFile2(PROJECT_PACKAGE_JSON, JSON.stringify(existing, null, 2));
|
|
2826
|
+
}
|
|
2608
2827
|
async function savePluginsJson(data, global = true) {
|
|
2609
2828
|
const path = global ? GLOBAL_PACKAGE_JSON : PROJECT_PLUGINS_JSON;
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2829
|
+
try {
|
|
2830
|
+
await mkdir2(dirname2(path), { recursive: true });
|
|
2831
|
+
if (global) {
|
|
2832
|
+
let existing = {};
|
|
2833
|
+
try {
|
|
2834
|
+
existing = JSON.parse(await readFile(path, "utf-8"));
|
|
2835
|
+
} catch {
|
|
2836
|
+
existing = {
|
|
2837
|
+
name: "pi-plugins",
|
|
2838
|
+
version: "1.0.0",
|
|
2839
|
+
private: true,
|
|
2840
|
+
description: "Global pi plugins managed by omp"
|
|
2841
|
+
};
|
|
2842
|
+
}
|
|
2843
|
+
existing.dependencies = data.plugins;
|
|
2844
|
+
if (data.devDependencies && Object.keys(data.devDependencies).length > 0) {
|
|
2845
|
+
existing.devDependencies = data.devDependencies;
|
|
2846
|
+
} else {
|
|
2847
|
+
delete existing.devDependencies;
|
|
2848
|
+
}
|
|
2849
|
+
if (data.disabled?.length) {
|
|
2850
|
+
existing.omp = { ...existing.omp || {}, disabled: data.disabled };
|
|
2851
|
+
}
|
|
2852
|
+
await writeFile2(path, JSON.stringify(existing, null, 2));
|
|
2853
|
+
} else {
|
|
2854
|
+
const output = { plugins: data.plugins };
|
|
2855
|
+
if (data.devDependencies && Object.keys(data.devDependencies).length > 0) {
|
|
2856
|
+
output.devDependencies = data.devDependencies;
|
|
2857
|
+
}
|
|
2858
|
+
if (data.disabled?.length) {
|
|
2859
|
+
output.disabled = data.disabled;
|
|
2860
|
+
}
|
|
2861
|
+
await writeFile2(path, JSON.stringify(output, null, 2));
|
|
2862
|
+
await syncProjectPackageJson(data);
|
|
2622
2863
|
}
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2864
|
+
} catch (err) {
|
|
2865
|
+
const error = err;
|
|
2866
|
+
if (error.code === "EACCES" || error.code === "EPERM") {
|
|
2867
|
+
throw new Error(formatPermissionError(error, path));
|
|
2626
2868
|
}
|
|
2627
|
-
|
|
2628
|
-
} else {
|
|
2629
|
-
await writeFile2(path, JSON.stringify(data, null, 2));
|
|
2869
|
+
throw err;
|
|
2630
2870
|
}
|
|
2631
2871
|
}
|
|
2632
2872
|
async function readPluginPackageJson(pluginName, global = true) {
|
|
@@ -2649,7 +2889,7 @@ function getPluginSourceDir(pluginName, global = true) {
|
|
|
2649
2889
|
return join3(nodeModules, pluginName);
|
|
2650
2890
|
}
|
|
2651
2891
|
function hasLegacyManifest() {
|
|
2652
|
-
return
|
|
2892
|
+
return existsSync3(LEGACY_MANIFEST_PATH);
|
|
2653
2893
|
}
|
|
2654
2894
|
async function loadLegacyManifest() {
|
|
2655
2895
|
try {
|
|
@@ -2671,11 +2911,32 @@ async function getInstalledPlugins(global = true) {
|
|
|
2671
2911
|
return plugins;
|
|
2672
2912
|
}
|
|
2673
2913
|
|
|
2914
|
+
// src/commands/doctor.ts
|
|
2915
|
+
init_paths();
|
|
2916
|
+
|
|
2674
2917
|
// src/symlinks.ts
|
|
2675
|
-
import { existsSync as
|
|
2918
|
+
import { existsSync as existsSync4, lstatSync } from "fs";
|
|
2676
2919
|
import { mkdir as mkdir3, readlink, rm, symlink } from "fs/promises";
|
|
2677
|
-
import {
|
|
2678
|
-
|
|
2920
|
+
import { platform } from "os";
|
|
2921
|
+
import { dirname as dirname3, join as join4, resolve as resolve2 } from "path";
|
|
2922
|
+
init_paths();
|
|
2923
|
+
init_source();
|
|
2924
|
+
var isWindows = platform() === "win32";
|
|
2925
|
+
function formatPermissionError2(err, path) {
|
|
2926
|
+
if (err.code === "EACCES" || err.code === "EPERM") {
|
|
2927
|
+
return `Permission denied: Cannot write to ${path}. Check directory permissions or run with appropriate privileges.`;
|
|
2928
|
+
}
|
|
2929
|
+
return err.message;
|
|
2930
|
+
}
|
|
2931
|
+
function isPathWithinBase(basePath, targetPath) {
|
|
2932
|
+
const normalizedBase = resolve2(basePath);
|
|
2933
|
+
const resolvedTarget = resolve2(basePath, targetPath);
|
|
2934
|
+
return resolvedTarget === normalizedBase || resolvedTarget.startsWith(`${normalizedBase}/`);
|
|
2935
|
+
}
|
|
2936
|
+
function getBaseDir(global) {
|
|
2937
|
+
return global ? PI_CONFIG_DIR : PROJECT_PI_DIR;
|
|
2938
|
+
}
|
|
2939
|
+
async function createPluginSymlinks(pluginName, pkgJson, global = true, verbose = true, skipDestinations) {
|
|
2679
2940
|
const result = { created: [], errors: [] };
|
|
2680
2941
|
const sourceDir = getPluginSourceDir(pluginName, global);
|
|
2681
2942
|
if (!pkgJson.omp?.install?.length) {
|
|
@@ -2684,56 +2945,115 @@ async function createPluginSymlinks(pluginName, pkgJson, global = true, verbose
|
|
|
2684
2945
|
}
|
|
2685
2946
|
return result;
|
|
2686
2947
|
}
|
|
2948
|
+
const baseDir = getBaseDir(global);
|
|
2687
2949
|
for (const entry of pkgJson.omp.install) {
|
|
2950
|
+
if (skipDestinations?.has(entry.dest)) {
|
|
2951
|
+
if (verbose) {
|
|
2952
|
+
console.log(source_default.dim(` Skipped: ${entry.dest} (conflict resolved to existing plugin)`));
|
|
2953
|
+
}
|
|
2954
|
+
continue;
|
|
2955
|
+
}
|
|
2956
|
+
if (!isPathWithinBase(baseDir, entry.dest)) {
|
|
2957
|
+
const msg = `Path traversal blocked: ${entry.dest} escapes base directory`;
|
|
2958
|
+
result.errors.push(msg);
|
|
2959
|
+
if (verbose) {
|
|
2960
|
+
console.log(source_default.red(` \u2717 ${msg}`));
|
|
2961
|
+
}
|
|
2962
|
+
continue;
|
|
2963
|
+
}
|
|
2688
2964
|
try {
|
|
2689
2965
|
const src = join4(sourceDir, entry.src);
|
|
2690
|
-
const dest = join4(
|
|
2691
|
-
if (!
|
|
2966
|
+
const dest = join4(baseDir, entry.dest);
|
|
2967
|
+
if (!existsSync4(src)) {
|
|
2692
2968
|
result.errors.push(`Source not found: ${entry.src}`);
|
|
2693
2969
|
if (verbose) {
|
|
2694
2970
|
console.log(source_default.yellow(` \u26A0 Source not found: ${entry.src}`));
|
|
2695
2971
|
}
|
|
2696
2972
|
continue;
|
|
2697
2973
|
}
|
|
2698
|
-
await mkdir3(
|
|
2974
|
+
await mkdir3(dirname3(dest), { recursive: true });
|
|
2699
2975
|
try {
|
|
2700
2976
|
await rm(dest, { force: true, recursive: true });
|
|
2701
2977
|
} catch {}
|
|
2702
|
-
|
|
2978
|
+
try {
|
|
2979
|
+
if (isWindows) {
|
|
2980
|
+
const stats = lstatSync(src);
|
|
2981
|
+
if (stats.isDirectory()) {
|
|
2982
|
+
await symlink(src, dest, "junction");
|
|
2983
|
+
} else {
|
|
2984
|
+
await symlink(src, dest, "file");
|
|
2985
|
+
}
|
|
2986
|
+
} else {
|
|
2987
|
+
await symlink(src, dest);
|
|
2988
|
+
}
|
|
2989
|
+
} catch (symlinkErr) {
|
|
2990
|
+
const error = symlinkErr;
|
|
2991
|
+
if (isWindows && error.code === "EPERM") {
|
|
2992
|
+
console.log(source_default.red(` Permission denied creating symlink.`));
|
|
2993
|
+
console.log(source_default.dim(" On Windows, enable Developer Mode or run as Administrator."));
|
|
2994
|
+
console.log(source_default.dim(" Settings > Update & Security > For developers > Developer Mode"));
|
|
2995
|
+
}
|
|
2996
|
+
throw symlinkErr;
|
|
2997
|
+
}
|
|
2703
2998
|
result.created.push(entry.dest);
|
|
2704
2999
|
if (verbose) {
|
|
2705
3000
|
console.log(source_default.dim(` Linked: ${entry.dest} \u2192 ${entry.src}`));
|
|
2706
3001
|
}
|
|
2707
3002
|
} catch (err) {
|
|
2708
|
-
const
|
|
3003
|
+
const error = err;
|
|
3004
|
+
const msg = `Failed to link ${entry.dest}: ${formatPermissionError2(error, join4(baseDir, entry.dest))}`;
|
|
2709
3005
|
result.errors.push(msg);
|
|
2710
3006
|
if (verbose) {
|
|
2711
3007
|
console.log(source_default.red(` \u2717 ${msg}`));
|
|
3008
|
+
if (error.code === "EACCES" || error.code === "EPERM") {
|
|
3009
|
+
console.log(source_default.dim(" Check directory permissions or run with appropriate privileges."));
|
|
3010
|
+
}
|
|
2712
3011
|
}
|
|
2713
3012
|
}
|
|
2714
3013
|
}
|
|
2715
3014
|
return result;
|
|
2716
3015
|
}
|
|
2717
|
-
async function removePluginSymlinks(_pluginName, pkgJson, verbose = true) {
|
|
2718
|
-
const result = {
|
|
3016
|
+
async function removePluginSymlinks(_pluginName, pkgJson, global = true, verbose = true) {
|
|
3017
|
+
const result = { removed: [], errors: [], skippedNonSymlinks: [] };
|
|
2719
3018
|
if (!pkgJson.omp?.install?.length) {
|
|
2720
3019
|
return result;
|
|
2721
3020
|
}
|
|
3021
|
+
const baseDir = getBaseDir(global);
|
|
2722
3022
|
for (const entry of pkgJson.omp.install) {
|
|
2723
|
-
|
|
3023
|
+
if (!isPathWithinBase(baseDir, entry.dest)) {
|
|
3024
|
+
const msg = `Path traversal blocked: ${entry.dest} escapes base directory`;
|
|
3025
|
+
result.errors.push(msg);
|
|
3026
|
+
if (verbose) {
|
|
3027
|
+
console.log(source_default.red(` \u2717 ${msg}`));
|
|
3028
|
+
}
|
|
3029
|
+
continue;
|
|
3030
|
+
}
|
|
3031
|
+
const dest = join4(baseDir, entry.dest);
|
|
2724
3032
|
try {
|
|
2725
|
-
if (
|
|
3033
|
+
if (existsSync4(dest)) {
|
|
3034
|
+
const stats = lstatSync(dest);
|
|
3035
|
+
if (!stats.isSymbolicLink()) {
|
|
3036
|
+
result.skippedNonSymlinks.push(dest);
|
|
3037
|
+
if (verbose) {
|
|
3038
|
+
console.log(source_default.yellow(` \u26A0 Skipping ${entry.dest}: not a symlink (may contain user data)`));
|
|
3039
|
+
}
|
|
3040
|
+
continue;
|
|
3041
|
+
}
|
|
2726
3042
|
await rm(dest, { force: true, recursive: true });
|
|
2727
|
-
result.
|
|
3043
|
+
result.removed.push(entry.dest);
|
|
2728
3044
|
if (verbose) {
|
|
2729
3045
|
console.log(source_default.dim(` Removed: ${entry.dest}`));
|
|
2730
3046
|
}
|
|
2731
3047
|
}
|
|
2732
3048
|
} catch (err) {
|
|
2733
|
-
const
|
|
3049
|
+
const error = err;
|
|
3050
|
+
const msg = `Failed to remove ${entry.dest}: ${formatPermissionError2(error, dest)}`;
|
|
2734
3051
|
result.errors.push(msg);
|
|
2735
3052
|
if (verbose) {
|
|
2736
3053
|
console.log(source_default.yellow(` \u26A0 ${msg}`));
|
|
3054
|
+
if (error.code === "EACCES" || error.code === "EPERM") {
|
|
3055
|
+
console.log(source_default.dim(" Check directory permissions or run with appropriate privileges."));
|
|
3056
|
+
}
|
|
2737
3057
|
}
|
|
2738
3058
|
}
|
|
2739
3059
|
}
|
|
@@ -2742,13 +3062,18 @@ async function removePluginSymlinks(_pluginName, pkgJson, verbose = true) {
|
|
|
2742
3062
|
async function checkPluginSymlinks(pluginName, pkgJson, global = true) {
|
|
2743
3063
|
const result = { valid: [], broken: [], missing: [] };
|
|
2744
3064
|
const sourceDir = getPluginSourceDir(pluginName, global);
|
|
3065
|
+
const baseDir = getBaseDir(global);
|
|
2745
3066
|
if (!pkgJson.omp?.install?.length) {
|
|
2746
3067
|
return result;
|
|
2747
3068
|
}
|
|
2748
3069
|
for (const entry of pkgJson.omp.install) {
|
|
3070
|
+
if (!isPathWithinBase(baseDir, entry.dest)) {
|
|
3071
|
+
result.broken.push(entry.dest);
|
|
3072
|
+
continue;
|
|
3073
|
+
}
|
|
2749
3074
|
const src = join4(sourceDir, entry.src);
|
|
2750
|
-
const dest = join4(
|
|
2751
|
-
if (!
|
|
3075
|
+
const dest = join4(baseDir, entry.dest);
|
|
3076
|
+
if (!existsSync4(dest)) {
|
|
2752
3077
|
result.missing.push(entry.dest);
|
|
2753
3078
|
continue;
|
|
2754
3079
|
}
|
|
@@ -2756,7 +3081,7 @@ async function checkPluginSymlinks(pluginName, pkgJson, global = true) {
|
|
|
2756
3081
|
const stats = lstatSync(dest);
|
|
2757
3082
|
if (stats.isSymbolicLink()) {
|
|
2758
3083
|
const _target = await readlink(dest);
|
|
2759
|
-
if (
|
|
3084
|
+
if (existsSync4(src)) {
|
|
2760
3085
|
result.valid.push(entry.dest);
|
|
2761
3086
|
} else {
|
|
2762
3087
|
result.broken.push(entry.dest);
|
|
@@ -2770,10 +3095,11 @@ async function checkPluginSymlinks(pluginName, pkgJson, global = true) {
|
|
|
2770
3095
|
}
|
|
2771
3096
|
return result;
|
|
2772
3097
|
}
|
|
2773
|
-
async function traceInstalledFile(filePath, installedPlugins) {
|
|
3098
|
+
async function traceInstalledFile(filePath, installedPlugins, global = true) {
|
|
3099
|
+
const baseDir = getBaseDir(global);
|
|
2774
3100
|
let relativePath = filePath;
|
|
2775
|
-
if (filePath.startsWith(
|
|
2776
|
-
relativePath = filePath.slice(
|
|
3101
|
+
if (filePath.startsWith(baseDir)) {
|
|
3102
|
+
relativePath = filePath.slice(baseDir.length + 1);
|
|
2777
3103
|
}
|
|
2778
3104
|
for (const [name, pkgJson] of installedPlugins) {
|
|
2779
3105
|
if (pkgJson.omp?.install) {
|
|
@@ -2788,13 +3114,14 @@ async function traceInstalledFile(filePath, installedPlugins) {
|
|
|
2788
3114
|
}
|
|
2789
3115
|
|
|
2790
3116
|
// src/commands/doctor.ts
|
|
3117
|
+
init_source();
|
|
2791
3118
|
async function runDoctor(options = {}) {
|
|
2792
|
-
const isGlobal = options
|
|
3119
|
+
const isGlobal = resolveScope(options);
|
|
2793
3120
|
const results = [];
|
|
2794
3121
|
console.log(source_default.blue(`Running health checks...
|
|
2795
3122
|
`));
|
|
2796
3123
|
const pluginsDir = isGlobal ? PLUGINS_DIR : ".pi";
|
|
2797
|
-
if (!
|
|
3124
|
+
if (!existsSync5(pluginsDir)) {
|
|
2798
3125
|
results.push({
|
|
2799
3126
|
check: "Plugins directory",
|
|
2800
3127
|
status: "warning",
|
|
@@ -2808,8 +3135,8 @@ async function runDoctor(options = {}) {
|
|
|
2808
3135
|
message: pluginsDir
|
|
2809
3136
|
});
|
|
2810
3137
|
}
|
|
2811
|
-
const packageJsonPath = isGlobal ? GLOBAL_PACKAGE_JSON :
|
|
2812
|
-
if (!
|
|
3138
|
+
const packageJsonPath = isGlobal ? GLOBAL_PACKAGE_JSON : PROJECT_PLUGINS_JSON;
|
|
3139
|
+
if (!existsSync5(packageJsonPath)) {
|
|
2813
3140
|
results.push({
|
|
2814
3141
|
check: "Package manifest",
|
|
2815
3142
|
status: "warning",
|
|
@@ -2823,8 +3150,8 @@ async function runDoctor(options = {}) {
|
|
|
2823
3150
|
message: packageJsonPath
|
|
2824
3151
|
});
|
|
2825
3152
|
}
|
|
2826
|
-
const nodeModules = isGlobal ? NODE_MODULES_DIR :
|
|
2827
|
-
if (!
|
|
3153
|
+
const nodeModules = isGlobal ? NODE_MODULES_DIR : PROJECT_NODE_MODULES;
|
|
3154
|
+
if (!existsSync5(nodeModules)) {
|
|
2828
3155
|
results.push({
|
|
2829
3156
|
check: "Node modules",
|
|
2830
3157
|
status: "warning",
|
|
@@ -2901,6 +3228,31 @@ async function runDoctor(options = {}) {
|
|
|
2901
3228
|
fix: "Run: omp install (to reinstall) or remove from manifest"
|
|
2902
3229
|
});
|
|
2903
3230
|
}
|
|
3231
|
+
const missingDeps = [];
|
|
3232
|
+
for (const [name, pkgJson] of installedPlugins) {
|
|
3233
|
+
if (pkgJson.dependencies) {
|
|
3234
|
+
for (const depName of Object.keys(pkgJson.dependencies)) {
|
|
3235
|
+
const depPkgJson = await readPluginPackageJson(depName, isGlobal);
|
|
3236
|
+
if (!depPkgJson) {
|
|
3237
|
+
if (pluginsJson.plugins[depName]) {
|
|
3238
|
+
missingDeps.push(`${name} requires ${depName} (not in node_modules)`);
|
|
3239
|
+
}
|
|
3240
|
+
} else if (depPkgJson.omp?.install && depPkgJson.omp.install.length > 0) {
|
|
3241
|
+
if (!pluginsJson.plugins[depName]) {
|
|
3242
|
+
missingDeps.push(`${name} requires omp plugin ${depName} (installed but not in manifest)`);
|
|
3243
|
+
}
|
|
3244
|
+
}
|
|
3245
|
+
}
|
|
3246
|
+
}
|
|
3247
|
+
}
|
|
3248
|
+
if (missingDeps.length > 0) {
|
|
3249
|
+
results.push({
|
|
3250
|
+
check: "Missing omp dependencies",
|
|
3251
|
+
status: "warning",
|
|
3252
|
+
message: missingDeps.join("; "),
|
|
3253
|
+
fix: isGlobal ? "Run: npm install in ~/.pi/plugins" : "Run: npm install in .pi"
|
|
3254
|
+
});
|
|
3255
|
+
}
|
|
2904
3256
|
if (options.json) {
|
|
2905
3257
|
console.log(JSON.stringify({ results }, null, 2));
|
|
2906
3258
|
return;
|
|
@@ -2935,6 +3287,7 @@ async function runDoctor(options = {}) {
|
|
|
2935
3287
|
} else {
|
|
2936
3288
|
if (errors.length > 0) {
|
|
2937
3289
|
console.log(source_default.red(`${errors.length} error(s) found`));
|
|
3290
|
+
process.exitCode = 1;
|
|
2938
3291
|
}
|
|
2939
3292
|
if (warnings.length > 0) {
|
|
2940
3293
|
console.log(source_default.yellow(`${warnings.length} warning(s) found`));
|
|
@@ -2954,28 +3307,81 @@ Missing symlinks:`));
|
|
|
2954
3307
|
console.log(source_default.dim(` - ${s}`));
|
|
2955
3308
|
}
|
|
2956
3309
|
}
|
|
3310
|
+
if (options.fix) {
|
|
3311
|
+
let fixedAnything = false;
|
|
3312
|
+
if (brokenSymlinks.length > 0 || missingSymlinks.length > 0) {
|
|
3313
|
+
console.log(source_default.blue(`
|
|
3314
|
+
Attempting to fix broken/missing symlinks...`));
|
|
3315
|
+
for (const [name, pkgJson] of installedPlugins) {
|
|
3316
|
+
const symlinkResult = await createPluginSymlinks(name, pkgJson, isGlobal, false);
|
|
3317
|
+
if (symlinkResult.created.length > 0) {
|
|
3318
|
+
fixedAnything = true;
|
|
3319
|
+
console.log(source_default.green(` \u2713 Re-created symlinks for ${name}`));
|
|
3320
|
+
}
|
|
3321
|
+
if (symlinkResult.errors.length > 0) {
|
|
3322
|
+
for (const err of symlinkResult.errors) {
|
|
3323
|
+
console.log(source_default.red(` \u2717 ${name}: ${err}`));
|
|
3324
|
+
}
|
|
3325
|
+
}
|
|
3326
|
+
}
|
|
3327
|
+
}
|
|
3328
|
+
if (orphaned.length > 0) {
|
|
3329
|
+
console.log(source_default.blue(`
|
|
3330
|
+
Removing orphaned entries from manifest...`));
|
|
3331
|
+
for (const name of orphaned) {
|
|
3332
|
+
delete pluginsJson.plugins[name];
|
|
3333
|
+
console.log(source_default.green(` \u2713 Removed ${name}`));
|
|
3334
|
+
}
|
|
3335
|
+
await savePluginsJson(pluginsJson, isGlobal);
|
|
3336
|
+
fixedAnything = true;
|
|
3337
|
+
}
|
|
3338
|
+
if (conflicts.length > 0) {
|
|
3339
|
+
console.log(source_default.yellow(`
|
|
3340
|
+
Conflicts cannot be auto-fixed. Please resolve manually:`));
|
|
3341
|
+
for (const conflict of formatConflicts(conflicts)) {
|
|
3342
|
+
console.log(source_default.dim(` - ${conflict}`));
|
|
3343
|
+
}
|
|
3344
|
+
}
|
|
3345
|
+
if (fixedAnything) {
|
|
3346
|
+
console.log(source_default.green(`
|
|
3347
|
+
\u2713 Fixes applied. Run 'omp doctor' again to verify.`));
|
|
3348
|
+
} else if (conflicts.length === 0) {
|
|
3349
|
+
console.log(source_default.dim(`
|
|
3350
|
+
No fixable issues found.`));
|
|
3351
|
+
}
|
|
3352
|
+
}
|
|
2957
3353
|
}
|
|
2958
3354
|
|
|
2959
3355
|
// src/commands/enable.ts
|
|
3356
|
+
init_paths();
|
|
3357
|
+
init_source();
|
|
2960
3358
|
async function enablePlugin(name, options = {}) {
|
|
2961
|
-
const isGlobal = options
|
|
3359
|
+
const isGlobal = resolveScope(options);
|
|
2962
3360
|
const pluginsJson = await loadPluginsJson(isGlobal);
|
|
2963
3361
|
if (!pluginsJson.plugins[name]) {
|
|
2964
3362
|
console.log(source_default.yellow(`Plugin "${name}" is not installed.`));
|
|
3363
|
+
process.exitCode = 1;
|
|
2965
3364
|
return;
|
|
2966
3365
|
}
|
|
2967
3366
|
if (!pluginsJson.disabled?.includes(name)) {
|
|
2968
3367
|
console.log(source_default.yellow(`Plugin "${name}" is already enabled.`));
|
|
3368
|
+
process.exitCode = 1;
|
|
2969
3369
|
return;
|
|
2970
3370
|
}
|
|
2971
3371
|
try {
|
|
2972
3372
|
const pkgJson = await readPluginPackageJson(name, isGlobal);
|
|
2973
3373
|
if (!pkgJson) {
|
|
2974
3374
|
console.log(source_default.red(`Could not read package.json for ${name}`));
|
|
3375
|
+
process.exitCode = 1;
|
|
2975
3376
|
return;
|
|
2976
3377
|
}
|
|
2977
|
-
|
|
2978
|
-
|
|
3378
|
+
const symlinkStatus = await checkPluginSymlinks(name, pkgJson, isGlobal);
|
|
3379
|
+
if (symlinkStatus.valid.length > 0 && symlinkStatus.broken.length === 0 && symlinkStatus.missing.length === 0) {
|
|
3380
|
+
console.log(source_default.yellow(`Plugin "${name}" symlinks are already in place.`));
|
|
3381
|
+
} else {
|
|
3382
|
+
console.log(source_default.blue(`Enabling ${name}...`));
|
|
3383
|
+
await createPluginSymlinks(name, pkgJson, isGlobal);
|
|
3384
|
+
}
|
|
2979
3385
|
pluginsJson.disabled = pluginsJson.disabled.filter((n) => n !== name);
|
|
2980
3386
|
await savePluginsJson(pluginsJson, isGlobal);
|
|
2981
3387
|
console.log(source_default.green(`\u2713 Enabled "${name}"`));
|
|
@@ -2984,27 +3390,31 @@ async function enablePlugin(name, options = {}) {
|
|
|
2984
3390
|
}
|
|
2985
3391
|
} catch (err) {
|
|
2986
3392
|
console.log(source_default.red(`Error enabling plugin: ${err.message}`));
|
|
3393
|
+
process.exitCode = 1;
|
|
2987
3394
|
}
|
|
2988
3395
|
}
|
|
2989
3396
|
async function disablePlugin(name, options = {}) {
|
|
2990
|
-
const isGlobal = options
|
|
3397
|
+
const isGlobal = resolveScope(options);
|
|
2991
3398
|
const pluginsJson = await loadPluginsJson(isGlobal);
|
|
2992
3399
|
if (!pluginsJson.plugins[name]) {
|
|
2993
3400
|
console.log(source_default.yellow(`Plugin "${name}" is not installed.`));
|
|
3401
|
+
process.exitCode = 1;
|
|
2994
3402
|
return;
|
|
2995
3403
|
}
|
|
2996
3404
|
if (pluginsJson.disabled?.includes(name)) {
|
|
2997
3405
|
console.log(source_default.yellow(`Plugin "${name}" is already disabled.`));
|
|
3406
|
+
process.exitCode = 1;
|
|
2998
3407
|
return;
|
|
2999
3408
|
}
|
|
3000
3409
|
try {
|
|
3001
3410
|
const pkgJson = await readPluginPackageJson(name, isGlobal);
|
|
3002
3411
|
if (!pkgJson) {
|
|
3003
3412
|
console.log(source_default.red(`Could not read package.json for ${name}`));
|
|
3413
|
+
process.exitCode = 1;
|
|
3004
3414
|
return;
|
|
3005
3415
|
}
|
|
3006
3416
|
console.log(source_default.blue(`Disabling ${name}...`));
|
|
3007
|
-
await removePluginSymlinks(name, pkgJson);
|
|
3417
|
+
await removePluginSymlinks(name, pkgJson, isGlobal);
|
|
3008
3418
|
if (!pluginsJson.disabled) {
|
|
3009
3419
|
pluginsJson.disabled = [];
|
|
3010
3420
|
}
|
|
@@ -3018,21 +3428,65 @@ async function disablePlugin(name, options = {}) {
|
|
|
3018
3428
|
}
|
|
3019
3429
|
} catch (err) {
|
|
3020
3430
|
console.log(source_default.red(`Error disabling plugin: ${err.message}`));
|
|
3431
|
+
process.exitCode = 1;
|
|
3021
3432
|
}
|
|
3022
3433
|
}
|
|
3023
3434
|
|
|
3024
3435
|
// src/npm.ts
|
|
3025
|
-
import {
|
|
3026
|
-
function
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3436
|
+
import { execFileSync } from "child_process";
|
|
3437
|
+
function checkNpmAvailable() {
|
|
3438
|
+
try {
|
|
3439
|
+
const version = execFileSync("npm", ["--version"], {
|
|
3440
|
+
encoding: "utf-8",
|
|
3441
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
3442
|
+
}).trim();
|
|
3443
|
+
const major = parseInt(version.split(".")[0], 10);
|
|
3444
|
+
if (major < 7) {
|
|
3445
|
+
return {
|
|
3446
|
+
available: false,
|
|
3447
|
+
version,
|
|
3448
|
+
error: `npm version ${version} is too old. Please upgrade to npm 7 or later.`
|
|
3449
|
+
};
|
|
3450
|
+
}
|
|
3451
|
+
return { available: true, version };
|
|
3452
|
+
} catch {
|
|
3453
|
+
return {
|
|
3454
|
+
available: false,
|
|
3455
|
+
error: "npm is not installed or not in PATH. Please install Node.js/npm."
|
|
3456
|
+
};
|
|
3457
|
+
}
|
|
3458
|
+
}
|
|
3459
|
+
var DEFAULT_TIMEOUT_MS = 60000;
|
|
3460
|
+
function npmExec(args, cwd, timeout = DEFAULT_TIMEOUT_MS) {
|
|
3461
|
+
try {
|
|
3462
|
+
return execFileSync("npm", args, {
|
|
3463
|
+
cwd,
|
|
3464
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
3465
|
+
encoding: "utf-8",
|
|
3466
|
+
timeout
|
|
3467
|
+
});
|
|
3468
|
+
} catch (err) {
|
|
3469
|
+
const error = err;
|
|
3470
|
+
if (error.killed || error.code === "ETIMEDOUT") {
|
|
3471
|
+
throw new Error(`npm operation timed out after ${timeout / 1000} seconds`);
|
|
3472
|
+
}
|
|
3473
|
+
throw err;
|
|
3474
|
+
}
|
|
3033
3475
|
}
|
|
3034
|
-
function npmExecWithPrefix(args, prefix) {
|
|
3035
|
-
|
|
3476
|
+
function npmExecWithPrefix(args, prefix, timeout = DEFAULT_TIMEOUT_MS) {
|
|
3477
|
+
try {
|
|
3478
|
+
return execFileSync("npm", ["--prefix", prefix, ...args], {
|
|
3479
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
3480
|
+
encoding: "utf-8",
|
|
3481
|
+
timeout
|
|
3482
|
+
});
|
|
3483
|
+
} catch (err) {
|
|
3484
|
+
const error = err;
|
|
3485
|
+
if (error.killed || error.code === "ETIMEDOUT") {
|
|
3486
|
+
throw new Error(`npm operation timed out after ${timeout / 1000} seconds`);
|
|
3487
|
+
}
|
|
3488
|
+
throw err;
|
|
3489
|
+
}
|
|
3036
3490
|
}
|
|
3037
3491
|
async function npmInstall(packages, prefix, options = {}) {
|
|
3038
3492
|
const args = ["install"];
|
|
@@ -3056,13 +3510,9 @@ async function npmInfo(packageName) {
|
|
|
3056
3510
|
}
|
|
3057
3511
|
}
|
|
3058
3512
|
async function npmSearch(query, keyword = "omp-plugin") {
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
return JSON.parse(output);
|
|
3063
|
-
} catch {
|
|
3064
|
-
return [];
|
|
3065
|
-
}
|
|
3513
|
+
const searchTerm = keyword ? `keywords:${keyword} ${query}` : query;
|
|
3514
|
+
const output = npmExec(["search", searchTerm, "--json"]);
|
|
3515
|
+
return JSON.parse(output);
|
|
3066
3516
|
}
|
|
3067
3517
|
async function npmOutdated(prefix) {
|
|
3068
3518
|
try {
|
|
@@ -3089,12 +3539,14 @@ async function npmUpdate(packages, prefix) {
|
|
|
3089
3539
|
}
|
|
3090
3540
|
|
|
3091
3541
|
// src/commands/info.ts
|
|
3542
|
+
init_source();
|
|
3092
3543
|
async function showInfo(packageName, options = {}) {
|
|
3093
3544
|
console.log(source_default.blue(`Fetching info for ${packageName}...`));
|
|
3094
3545
|
try {
|
|
3095
3546
|
const info = await npmInfo(packageName);
|
|
3096
3547
|
if (!info) {
|
|
3097
3548
|
console.log(source_default.red(`Package not found: ${packageName}`));
|
|
3549
|
+
process.exitCode = 1;
|
|
3098
3550
|
return;
|
|
3099
3551
|
}
|
|
3100
3552
|
if (options.json) {
|
|
@@ -3122,6 +3574,13 @@ async function showInfo(packageName, options = {}) {
|
|
|
3122
3574
|
if (info.keywords?.length) {
|
|
3123
3575
|
console.log(source_default.dim("keywords: ") + info.keywords.join(", "));
|
|
3124
3576
|
}
|
|
3577
|
+
if (info.dependencies && Object.keys(info.dependencies).length > 0) {
|
|
3578
|
+
console.log(source_default.dim(`
|
|
3579
|
+
dependencies:`));
|
|
3580
|
+
for (const [depName, depVersion] of Object.entries(info.dependencies)) {
|
|
3581
|
+
console.log(source_default.dim(` ${depName}: ${depVersion}`));
|
|
3582
|
+
}
|
|
3583
|
+
}
|
|
3125
3584
|
const isOmpPlugin = info.keywords?.includes("omp-plugin");
|
|
3126
3585
|
if (isOmpPlugin) {
|
|
3127
3586
|
console.log(source_default.green(`
|
|
@@ -3131,27 +3590,59 @@ async function showInfo(packageName, options = {}) {
|
|
|
3131
3590
|
\u26A0 This package does not have the omp-plugin keyword`));
|
|
3132
3591
|
console.log(source_default.dim(" It may work, but might not have omp.install configuration"));
|
|
3133
3592
|
}
|
|
3134
|
-
if (
|
|
3593
|
+
if (info.omp?.install?.length) {
|
|
3135
3594
|
console.log(source_default.dim(`
|
|
3595
|
+
Files to install:`));
|
|
3596
|
+
for (const entry of info.omp.install) {
|
|
3597
|
+
console.log(source_default.dim(` ${entry.src} \u2192 ${entry.dest}`));
|
|
3598
|
+
}
|
|
3599
|
+
}
|
|
3600
|
+
if (options.versions || options.allVersions) {
|
|
3601
|
+
if (info["dist-tags"]) {
|
|
3602
|
+
console.log(source_default.dim(`
|
|
3136
3603
|
dist-tags:`));
|
|
3137
|
-
|
|
3138
|
-
|
|
3604
|
+
for (const [tag, version] of Object.entries(info["dist-tags"])) {
|
|
3605
|
+
console.log(source_default.dim(` ${tag}: `) + version);
|
|
3606
|
+
}
|
|
3607
|
+
}
|
|
3608
|
+
if (info.versions?.length) {
|
|
3609
|
+
console.log(source_default.dim(`
|
|
3610
|
+
all versions:`));
|
|
3611
|
+
if (options.allVersions) {
|
|
3612
|
+
console.log(source_default.dim(` ${info.versions.join(", ")}`));
|
|
3613
|
+
} else {
|
|
3614
|
+
const versionsToShow = info.versions.slice(-10);
|
|
3615
|
+
console.log(source_default.dim(` ${versionsToShow.join(", ")}`));
|
|
3616
|
+
if (info.versions.length > 10) {
|
|
3617
|
+
console.log(source_default.dim(` ... and ${info.versions.length - 10} more (use --all-versions to see all)`));
|
|
3618
|
+
}
|
|
3619
|
+
}
|
|
3139
3620
|
}
|
|
3140
3621
|
}
|
|
3141
3622
|
console.log();
|
|
3142
3623
|
console.log(source_default.dim(`Install with: omp install ${packageName}`));
|
|
3143
3624
|
} catch (err) {
|
|
3144
3625
|
console.log(source_default.red(`Error fetching info: ${err.message}`));
|
|
3626
|
+
process.exitCode = 1;
|
|
3145
3627
|
}
|
|
3146
3628
|
}
|
|
3147
3629
|
|
|
3148
3630
|
// src/commands/init.ts
|
|
3149
|
-
|
|
3631
|
+
init_paths();
|
|
3632
|
+
init_source();
|
|
3633
|
+
import { existsSync as existsSync6 } from "fs";
|
|
3150
3634
|
import { mkdir as mkdir4, writeFile as writeFile3 } from "fs/promises";
|
|
3635
|
+
function formatPermissionError3(err, path) {
|
|
3636
|
+
if (err.code === "EACCES" || err.code === "EPERM") {
|
|
3637
|
+
return `Permission denied: Cannot write to ${path}. Check directory permissions or run with appropriate privileges.`;
|
|
3638
|
+
}
|
|
3639
|
+
return err.message;
|
|
3640
|
+
}
|
|
3151
3641
|
async function initProject(options = {}) {
|
|
3152
|
-
if (
|
|
3642
|
+
if (existsSync6(PROJECT_PLUGINS_JSON) && !options.force) {
|
|
3153
3643
|
console.log(source_default.yellow(`${PROJECT_PLUGINS_JSON} already exists.`));
|
|
3154
3644
|
console.log(source_default.dim("Use --force to overwrite"));
|
|
3645
|
+
process.exitCode = 1;
|
|
3155
3646
|
return;
|
|
3156
3647
|
}
|
|
3157
3648
|
try {
|
|
@@ -3168,22 +3659,49 @@ async function initProject(options = {}) {
|
|
|
3168
3659
|
console.log(source_default.dim(" 2. Or edit plugins.json directly"));
|
|
3169
3660
|
console.log(source_default.dim(" 3. Run: omp install (to install all)"));
|
|
3170
3661
|
} catch (err) {
|
|
3171
|
-
|
|
3662
|
+
const error = err;
|
|
3663
|
+
if (error.code === "EACCES" || error.code === "EPERM") {
|
|
3664
|
+
console.log(source_default.red(formatPermissionError3(error, PROJECT_PI_DIR)));
|
|
3665
|
+
console.log(source_default.dim(" Check directory permissions or run with appropriate privileges."));
|
|
3666
|
+
} else {
|
|
3667
|
+
console.log(source_default.red(`Error initializing project: ${error.message}`));
|
|
3668
|
+
}
|
|
3669
|
+
process.exitCode = 1;
|
|
3172
3670
|
}
|
|
3173
3671
|
}
|
|
3174
3672
|
|
|
3175
3673
|
// src/commands/install.ts
|
|
3176
|
-
import {
|
|
3177
|
-
import { existsSync as
|
|
3178
|
-
import { cp, mkdir as mkdir5, readFile as
|
|
3179
|
-
import { basename, join as join5, resolve } from "path";
|
|
3674
|
+
import { execFileSync as execFileSync2 } from "child_process";
|
|
3675
|
+
import { existsSync as existsSync8 } from "fs";
|
|
3676
|
+
import { cp, mkdir as mkdir5, readFile as readFile3, rm as rm2 } from "fs/promises";
|
|
3677
|
+
import { basename, join as join5, resolve as resolve3 } from "path";
|
|
3180
3678
|
import { createInterface } from "readline";
|
|
3679
|
+
init_lockfile();
|
|
3680
|
+
init_paths();
|
|
3681
|
+
init_source();
|
|
3682
|
+
async function processOmpDependencies(pkgJson, isGlobal, seen) {
|
|
3683
|
+
if (!pkgJson.dependencies)
|
|
3684
|
+
return;
|
|
3685
|
+
for (const depName of Object.keys(pkgJson.dependencies)) {
|
|
3686
|
+
if (seen.has(depName)) {
|
|
3687
|
+
console.log(source_default.yellow(` Skipping circular dependency: ${depName}`));
|
|
3688
|
+
continue;
|
|
3689
|
+
}
|
|
3690
|
+
seen.add(depName);
|
|
3691
|
+
const depPkgJson = await readPluginPackageJson(depName, isGlobal);
|
|
3692
|
+
if (depPkgJson?.omp?.install) {
|
|
3693
|
+
console.log(source_default.dim(` Processing dependency: ${depName}`));
|
|
3694
|
+
await createPluginSymlinks(depName, depPkgJson, isGlobal);
|
|
3695
|
+
await processOmpDependencies(depPkgJson, isGlobal, seen);
|
|
3696
|
+
}
|
|
3697
|
+
}
|
|
3698
|
+
}
|
|
3181
3699
|
async function promptConflictResolution(conflict) {
|
|
3182
3700
|
const rl = createInterface({
|
|
3183
3701
|
input: process.stdin,
|
|
3184
3702
|
output: process.stdout
|
|
3185
3703
|
});
|
|
3186
|
-
return new Promise((
|
|
3704
|
+
return new Promise((resolve4) => {
|
|
3187
3705
|
console.log(source_default.yellow(`
|
|
3188
3706
|
\u26A0 Conflict: ${formatConflicts([conflict])[0]}`));
|
|
3189
3707
|
conflict.plugins.forEach((p, i) => {
|
|
@@ -3194,9 +3712,9 @@ async function promptConflictResolution(conflict) {
|
|
|
3194
3712
|
rl.close();
|
|
3195
3713
|
const choice = parseInt(answer, 10);
|
|
3196
3714
|
if (choice > 0 && choice <= conflict.plugins.length) {
|
|
3197
|
-
|
|
3715
|
+
resolve4(choice - 1);
|
|
3198
3716
|
} else {
|
|
3199
|
-
|
|
3717
|
+
resolve4(null);
|
|
3200
3718
|
}
|
|
3201
3719
|
});
|
|
3202
3720
|
});
|
|
@@ -3225,23 +3743,25 @@ function isLocalPath(spec) {
|
|
|
3225
3743
|
return spec.startsWith("/") || spec.startsWith("./") || spec.startsWith("../") || spec.startsWith("~");
|
|
3226
3744
|
}
|
|
3227
3745
|
async function installPlugin(packages, options = {}) {
|
|
3228
|
-
const isGlobal = options
|
|
3746
|
+
const isGlobal = resolveScope(options);
|
|
3229
3747
|
const prefix = isGlobal ? PLUGINS_DIR : ".pi";
|
|
3230
3748
|
const _nodeModules = isGlobal ? NODE_MODULES_DIR : PROJECT_NODE_MODULES;
|
|
3231
3749
|
if (isGlobal) {
|
|
3232
3750
|
await initGlobalPlugins();
|
|
3233
3751
|
} else {
|
|
3234
|
-
await
|
|
3235
|
-
if (!existsSync6(PROJECT_PLUGINS_JSON)) {
|
|
3236
|
-
await savePluginsJson({ plugins: {} }, false);
|
|
3237
|
-
}
|
|
3752
|
+
await initProjectPlugins();
|
|
3238
3753
|
}
|
|
3239
3754
|
if (!packages || packages.length === 0) {
|
|
3240
3755
|
const pluginsJson = await loadPluginsJson(isGlobal);
|
|
3241
|
-
|
|
3756
|
+
const lockFile = await Promise.resolve().then(() => (init_lockfile(), exports_lockfile)).then((m) => m.loadLockFile(isGlobal));
|
|
3757
|
+
packages = await Promise.all(Object.entries(pluginsJson.plugins).map(async ([name, version]) => {
|
|
3758
|
+
const lockedVersion = lockFile?.packages[name]?.version;
|
|
3759
|
+
return `${name}@${lockedVersion || version}`;
|
|
3760
|
+
}));
|
|
3242
3761
|
if (packages.length === 0) {
|
|
3243
3762
|
console.log(source_default.yellow("No plugins to install."));
|
|
3244
3763
|
console.log(source_default.dim(isGlobal ? "Add plugins with: omp install <package>" : "Add plugins to .pi/plugins.json"));
|
|
3764
|
+
process.exitCode = 1;
|
|
3245
3765
|
return;
|
|
3246
3766
|
}
|
|
3247
3767
|
console.log(source_default.blue(`Installing ${packages.length} plugin(s) from ${isGlobal ? "package.json" : "plugins.json"}...`));
|
|
@@ -3256,57 +3776,168 @@ async function installPlugin(packages, options = {}) {
|
|
|
3256
3776
|
}
|
|
3257
3777
|
const { name, version } = parsePackageSpec(spec);
|
|
3258
3778
|
const pkgSpec = version === "latest" ? name : `${name}@${version}`;
|
|
3779
|
+
let npmInstallSucceeded = false;
|
|
3780
|
+
let createdSymlinks = [];
|
|
3781
|
+
let resolvedVersion = version;
|
|
3259
3782
|
try {
|
|
3260
3783
|
console.log(source_default.blue(`
|
|
3261
3784
|
Installing ${pkgSpec}...`));
|
|
3262
3785
|
const info = await npmInfo(pkgSpec);
|
|
3263
3786
|
if (!info) {
|
|
3264
3787
|
console.log(source_default.red(` \u2717 Package not found: ${name}`));
|
|
3788
|
+
process.exitCode = 1;
|
|
3265
3789
|
results.push({ name, version, success: false, error: "Package not found" });
|
|
3266
3790
|
continue;
|
|
3267
3791
|
}
|
|
3792
|
+
resolvedVersion = info.version;
|
|
3793
|
+
const skipDestinations = new Set;
|
|
3794
|
+
const preInstallPkgJson = info.omp?.install ? { name: info.name, version: info.version, omp: info.omp } : null;
|
|
3795
|
+
if (preInstallPkgJson) {
|
|
3796
|
+
const intraDupes = detectIntraPluginDuplicates(preInstallPkgJson);
|
|
3797
|
+
if (intraDupes.length > 0) {
|
|
3798
|
+
console.log(source_default.red(` \u2717 Plugin has duplicate destinations:`));
|
|
3799
|
+
for (const dupe of intraDupes) {
|
|
3800
|
+
console.log(source_default.red(` ${dupe.dest} \u2190 ${dupe.sources.join(", ")}`));
|
|
3801
|
+
}
|
|
3802
|
+
process.exitCode = 1;
|
|
3803
|
+
results.push({ name, version: info.version, success: false, error: "Duplicate destinations in plugin" });
|
|
3804
|
+
continue;
|
|
3805
|
+
}
|
|
3806
|
+
const preInstallConflicts = detectConflicts(name, preInstallPkgJson, existingPlugins);
|
|
3807
|
+
if (preInstallConflicts.length > 0 && !options.force) {
|
|
3808
|
+
if (!process.stdout.isTTY || !process.stdin.isTTY) {
|
|
3809
|
+
console.log(source_default.red("Conflicts detected in non-interactive mode. Use --force to override."));
|
|
3810
|
+
for (const conflict of preInstallConflicts) {
|
|
3811
|
+
console.log(source_default.yellow(` \u26A0 ${formatConflicts([conflict])[0]}`));
|
|
3812
|
+
}
|
|
3813
|
+
process.exitCode = 1;
|
|
3814
|
+
results.push({
|
|
3815
|
+
name,
|
|
3816
|
+
version: info.version,
|
|
3817
|
+
success: false,
|
|
3818
|
+
error: "Conflicts in non-interactive mode"
|
|
3819
|
+
});
|
|
3820
|
+
continue;
|
|
3821
|
+
}
|
|
3822
|
+
let abort = false;
|
|
3823
|
+
for (const conflict of preInstallConflicts) {
|
|
3824
|
+
const choice = await promptConflictResolution(conflict);
|
|
3825
|
+
if (choice === null) {
|
|
3826
|
+
abort = true;
|
|
3827
|
+
break;
|
|
3828
|
+
}
|
|
3829
|
+
const newPluginIndex = conflict.plugins.length - 1;
|
|
3830
|
+
if (choice !== newPluginIndex) {
|
|
3831
|
+
skipDestinations.add(conflict.dest);
|
|
3832
|
+
}
|
|
3833
|
+
}
|
|
3834
|
+
if (abort) {
|
|
3835
|
+
console.log(source_default.yellow(` Aborted due to conflicts (before download)`));
|
|
3836
|
+
process.exitCode = 1;
|
|
3837
|
+
results.push({ name, version: info.version, success: false, error: "Conflicts" });
|
|
3838
|
+
continue;
|
|
3839
|
+
}
|
|
3840
|
+
}
|
|
3841
|
+
}
|
|
3268
3842
|
console.log(source_default.dim(` Fetching from npm...`));
|
|
3269
3843
|
await npmInstall([pkgSpec], prefix, { save: options.save || isGlobal });
|
|
3844
|
+
npmInstallSucceeded = true;
|
|
3270
3845
|
const pkgJson = await readPluginPackageJson(name, isGlobal);
|
|
3271
3846
|
if (!pkgJson) {
|
|
3272
3847
|
console.log(source_default.yellow(` \u26A0 Installed but no package.json found`));
|
|
3273
3848
|
results.push({ name, version: info.version, success: true });
|
|
3274
3849
|
continue;
|
|
3275
3850
|
}
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
const
|
|
3281
|
-
|
|
3282
|
-
abort = true;
|
|
3283
|
-
break;
|
|
3851
|
+
if (!preInstallPkgJson) {
|
|
3852
|
+
const intraDupes = detectIntraPluginDuplicates(pkgJson);
|
|
3853
|
+
if (intraDupes.length > 0) {
|
|
3854
|
+
console.log(source_default.red(` \u2717 Plugin has duplicate destinations:`));
|
|
3855
|
+
for (const dupe of intraDupes) {
|
|
3856
|
+
console.log(source_default.red(` ${dupe.dest} \u2190 ${dupe.sources.join(", ")}`));
|
|
3284
3857
|
}
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
execSync2(`npm uninstall --prefix ${prefix} ${name}`, { stdio: "pipe" });
|
|
3289
|
-
results.push({ name, version: info.version, success: false, error: "Conflicts" });
|
|
3858
|
+
execFileSync2("npm", ["uninstall", "--prefix", prefix, name], { stdio: "pipe" });
|
|
3859
|
+
process.exitCode = 1;
|
|
3860
|
+
results.push({ name, version: info.version, success: false, error: "Duplicate destinations in plugin" });
|
|
3290
3861
|
continue;
|
|
3291
3862
|
}
|
|
3863
|
+
const conflicts = detectConflicts(name, pkgJson, existingPlugins);
|
|
3864
|
+
if (conflicts.length > 0 && !options.force) {
|
|
3865
|
+
if (!process.stdout.isTTY || !process.stdin.isTTY) {
|
|
3866
|
+
console.log(source_default.red("Conflicts detected in non-interactive mode. Use --force to override."));
|
|
3867
|
+
for (const conflict of conflicts) {
|
|
3868
|
+
console.log(source_default.yellow(` \u26A0 ${formatConflicts([conflict])[0]}`));
|
|
3869
|
+
}
|
|
3870
|
+
execFileSync2("npm", ["uninstall", "--prefix", prefix, name], { stdio: "pipe" });
|
|
3871
|
+
process.exitCode = 1;
|
|
3872
|
+
results.push({
|
|
3873
|
+
name,
|
|
3874
|
+
version: info.version,
|
|
3875
|
+
success: false,
|
|
3876
|
+
error: "Conflicts in non-interactive mode"
|
|
3877
|
+
});
|
|
3878
|
+
continue;
|
|
3879
|
+
}
|
|
3880
|
+
let abort = false;
|
|
3881
|
+
for (const conflict of conflicts) {
|
|
3882
|
+
const choice = await promptConflictResolution(conflict);
|
|
3883
|
+
if (choice === null) {
|
|
3884
|
+
abort = true;
|
|
3885
|
+
break;
|
|
3886
|
+
}
|
|
3887
|
+
const newPluginIndex = conflict.plugins.length - 1;
|
|
3888
|
+
if (choice !== newPluginIndex) {
|
|
3889
|
+
skipDestinations.add(conflict.dest);
|
|
3890
|
+
}
|
|
3891
|
+
}
|
|
3892
|
+
if (abort) {
|
|
3893
|
+
console.log(source_default.yellow(` Aborted due to conflicts`));
|
|
3894
|
+
execFileSync2("npm", ["uninstall", "--prefix", prefix, name], { stdio: "pipe" });
|
|
3895
|
+
process.exitCode = 1;
|
|
3896
|
+
results.push({ name, version: info.version, success: false, error: "Conflicts" });
|
|
3897
|
+
continue;
|
|
3898
|
+
}
|
|
3899
|
+
}
|
|
3292
3900
|
}
|
|
3293
|
-
const
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3901
|
+
const symlinkResult = await createPluginSymlinks(name, pkgJson, isGlobal, true, skipDestinations);
|
|
3902
|
+
createdSymlinks = symlinkResult.created;
|
|
3903
|
+
await processOmpDependencies(pkgJson, isGlobal, new Set([name]));
|
|
3904
|
+
if (options.save || options.saveDev) {
|
|
3905
|
+
const pluginsJson = await loadPluginsJson(isGlobal);
|
|
3906
|
+
if (options.saveDev) {
|
|
3907
|
+
if (!pluginsJson.devDependencies) {
|
|
3908
|
+
pluginsJson.devDependencies = {};
|
|
3300
3909
|
}
|
|
3910
|
+
pluginsJson.devDependencies[name] = info.version;
|
|
3911
|
+
delete pluginsJson.plugins[name];
|
|
3912
|
+
} else if (!isGlobal) {
|
|
3913
|
+
pluginsJson.plugins[name] = info.version;
|
|
3301
3914
|
}
|
|
3915
|
+
await savePluginsJson(pluginsJson, isGlobal);
|
|
3302
3916
|
}
|
|
3303
3917
|
existingPlugins.set(name, pkgJson);
|
|
3918
|
+
await updateLockFile(name, info.version, isGlobal);
|
|
3304
3919
|
console.log(source_default.green(`\u2713 Installed ${name}@${info.version}`));
|
|
3305
3920
|
results.push({ name, version: info.version, success: true });
|
|
3306
3921
|
} catch (err) {
|
|
3307
3922
|
const errorMsg = err.message;
|
|
3308
3923
|
console.log(source_default.red(` \u2717 Failed to install ${name}: ${errorMsg}`));
|
|
3309
|
-
|
|
3924
|
+
if (createdSymlinks.length > 0) {
|
|
3925
|
+
console.log(source_default.dim(" Rolling back symlinks..."));
|
|
3926
|
+
const baseDir = isGlobal ? PI_CONFIG_DIR : PROJECT_PI_DIR;
|
|
3927
|
+
for (const dest of createdSymlinks) {
|
|
3928
|
+
try {
|
|
3929
|
+
await rm2(join5(baseDir, dest), { force: true, recursive: true });
|
|
3930
|
+
} catch {}
|
|
3931
|
+
}
|
|
3932
|
+
}
|
|
3933
|
+
if (npmInstallSucceeded) {
|
|
3934
|
+
console.log(source_default.dim(" Rolling back npm install..."));
|
|
3935
|
+
try {
|
|
3936
|
+
execFileSync2("npm", ["uninstall", "--prefix", prefix, name], { stdio: "pipe" });
|
|
3937
|
+
} catch {}
|
|
3938
|
+
}
|
|
3939
|
+
process.exitCode = 1;
|
|
3940
|
+
results.push({ name, version: resolvedVersion, success: false, error: errorMsg });
|
|
3310
3941
|
}
|
|
3311
3942
|
}
|
|
3312
3943
|
const successful = results.filter((r) => r.success);
|
|
@@ -3317,6 +3948,7 @@ Installing ${pkgSpec}...`));
|
|
|
3317
3948
|
}
|
|
3318
3949
|
if (failed.length > 0) {
|
|
3319
3950
|
console.log(source_default.red(`\u2717 Failed to install ${failed.length} plugin(s)`));
|
|
3951
|
+
process.exitCode = 1;
|
|
3320
3952
|
}
|
|
3321
3953
|
if (options.json) {
|
|
3322
3954
|
console.log(JSON.stringify({ results }, null, 2));
|
|
@@ -3326,9 +3958,10 @@ async function installLocalPlugin(localPath, isGlobal, _options) {
|
|
|
3326
3958
|
if (localPath.startsWith("~")) {
|
|
3327
3959
|
localPath = join5(process.env.HOME || "", localPath.slice(1));
|
|
3328
3960
|
}
|
|
3329
|
-
localPath =
|
|
3330
|
-
if (!
|
|
3961
|
+
localPath = resolve3(localPath);
|
|
3962
|
+
if (!existsSync8(localPath)) {
|
|
3331
3963
|
console.log(source_default.red(`Error: Path does not exist: ${localPath}`));
|
|
3964
|
+
process.exitCode = 1;
|
|
3332
3965
|
return { name: basename(localPath), version: "local", success: false, error: "Path not found" };
|
|
3333
3966
|
}
|
|
3334
3967
|
const _prefix = isGlobal ? PLUGINS_DIR : ".pi";
|
|
@@ -3336,12 +3969,12 @@ async function installLocalPlugin(localPath, isGlobal, _options) {
|
|
|
3336
3969
|
try {
|
|
3337
3970
|
const localPkgJsonPath = join5(localPath, "package.json");
|
|
3338
3971
|
let pkgJson;
|
|
3339
|
-
if (
|
|
3340
|
-
pkgJson = JSON.parse(await
|
|
3972
|
+
if (existsSync8(localPkgJsonPath)) {
|
|
3973
|
+
pkgJson = JSON.parse(await readFile3(localPkgJsonPath, "utf-8"));
|
|
3341
3974
|
} else {
|
|
3342
3975
|
const ompJsonPath = join5(localPath, "omp.json");
|
|
3343
|
-
if (
|
|
3344
|
-
const ompJson = JSON.parse(await
|
|
3976
|
+
if (existsSync8(ompJsonPath)) {
|
|
3977
|
+
const ompJson = JSON.parse(await readFile3(ompJsonPath, "utf-8"));
|
|
3345
3978
|
pkgJson = {
|
|
3346
3979
|
name: ompJson.name || basename(localPath),
|
|
3347
3980
|
version: ompJson.version || "0.0.0",
|
|
@@ -3361,49 +3994,91 @@ async function installLocalPlugin(localPath, isGlobal, _options) {
|
|
|
3361
3994
|
}
|
|
3362
3995
|
const pluginName = pkgJson.name;
|
|
3363
3996
|
const pluginDir = join5(nodeModules, pluginName);
|
|
3997
|
+
const intraDupes = detectIntraPluginDuplicates(pkgJson);
|
|
3998
|
+
if (intraDupes.length > 0) {
|
|
3999
|
+
console.log(source_default.red(`
|
|
4000
|
+
Error: Plugin has duplicate destinations:`));
|
|
4001
|
+
for (const dupe of intraDupes) {
|
|
4002
|
+
console.log(source_default.red(` ${dupe.dest} \u2190 ${dupe.sources.join(", ")}`));
|
|
4003
|
+
}
|
|
4004
|
+
process.exitCode = 1;
|
|
4005
|
+
return {
|
|
4006
|
+
name: pluginName,
|
|
4007
|
+
version: pkgJson.version,
|
|
4008
|
+
success: false,
|
|
4009
|
+
error: "Duplicate destinations in plugin"
|
|
4010
|
+
};
|
|
4011
|
+
}
|
|
3364
4012
|
console.log(source_default.blue(`
|
|
3365
4013
|
Installing ${pluginName} from ${localPath}...`));
|
|
3366
4014
|
await mkdir5(nodeModules, { recursive: true });
|
|
3367
|
-
if (
|
|
4015
|
+
if (existsSync8(pluginDir)) {
|
|
3368
4016
|
await rm2(pluginDir, { recursive: true, force: true });
|
|
3369
4017
|
}
|
|
3370
4018
|
await cp(localPath, pluginDir, { recursive: true });
|
|
3371
4019
|
console.log(source_default.dim(` Copied to ${pluginDir}`));
|
|
3372
4020
|
const pluginsJson = await loadPluginsJson(isGlobal);
|
|
3373
|
-
|
|
4021
|
+
if (_options.saveDev) {
|
|
4022
|
+
if (!pluginsJson.devDependencies) {
|
|
4023
|
+
pluginsJson.devDependencies = {};
|
|
4024
|
+
}
|
|
4025
|
+
pluginsJson.devDependencies[pluginName] = `file:${localPath}`;
|
|
4026
|
+
delete pluginsJson.plugins[pluginName];
|
|
4027
|
+
} else {
|
|
4028
|
+
pluginsJson.plugins[pluginName] = `file:${localPath}`;
|
|
4029
|
+
}
|
|
3374
4030
|
await savePluginsJson(pluginsJson, isGlobal);
|
|
3375
4031
|
await createPluginSymlinks(pluginName, pkgJson, isGlobal);
|
|
4032
|
+
await updateLockFile(pluginName, pkgJson.version, isGlobal);
|
|
3376
4033
|
console.log(source_default.green(`\u2713 Installed ${pluginName}@${pkgJson.version}`));
|
|
3377
4034
|
return { name: pluginName, version: pkgJson.version, success: true };
|
|
3378
4035
|
} catch (err) {
|
|
3379
4036
|
const errorMsg = err.message;
|
|
3380
4037
|
console.log(source_default.red(` \u2717 Failed: ${errorMsg}`));
|
|
4038
|
+
process.exitCode = 1;
|
|
3381
4039
|
return { name: basename(localPath), version: "local", success: false, error: errorMsg };
|
|
3382
4040
|
}
|
|
3383
4041
|
}
|
|
3384
4042
|
|
|
3385
4043
|
// src/commands/link.ts
|
|
3386
|
-
import { existsSync as
|
|
3387
|
-
import { mkdir as mkdir6, readFile as
|
|
3388
|
-
import { basename as basename2, dirname as
|
|
4044
|
+
import { existsSync as existsSync9 } from "fs";
|
|
4045
|
+
import { mkdir as mkdir6, readFile as readFile4, rm as rm3, symlink as symlink2, writeFile as writeFile5 } from "fs/promises";
|
|
4046
|
+
import { basename as basename2, dirname as dirname4, join as join6, resolve as resolve4 } from "path";
|
|
4047
|
+
import { createInterface as createInterface2 } from "readline";
|
|
4048
|
+
init_paths();
|
|
4049
|
+
init_source();
|
|
4050
|
+
async function confirmCreate(path) {
|
|
4051
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
4052
|
+
console.log(source_default.dim(" Non-interactive mode: auto-creating package.json"));
|
|
4053
|
+
return true;
|
|
4054
|
+
}
|
|
4055
|
+
const rl = createInterface2({ input: process.stdin, output: process.stdout });
|
|
4056
|
+
return new Promise((resolve5) => {
|
|
4057
|
+
rl.question(source_default.yellow(` Create minimal package.json at ${path}? [Y/n] `), (answer) => {
|
|
4058
|
+
rl.close();
|
|
4059
|
+
resolve5(answer.toLowerCase() !== "n");
|
|
4060
|
+
});
|
|
4061
|
+
});
|
|
4062
|
+
}
|
|
3389
4063
|
async function linkPlugin(localPath, options = {}) {
|
|
3390
|
-
const isGlobal = options
|
|
4064
|
+
const isGlobal = resolveScope(options);
|
|
3391
4065
|
const nodeModules = isGlobal ? NODE_MODULES_DIR : PROJECT_NODE_MODULES;
|
|
3392
4066
|
if (localPath.startsWith("~")) {
|
|
3393
4067
|
localPath = join6(process.env.HOME || "", localPath.slice(1));
|
|
3394
4068
|
}
|
|
3395
|
-
localPath =
|
|
3396
|
-
if (!
|
|
4069
|
+
localPath = resolve4(localPath);
|
|
4070
|
+
if (!existsSync9(localPath)) {
|
|
3397
4071
|
console.log(source_default.red(`Error: Path does not exist: ${localPath}`));
|
|
4072
|
+
process.exitCode = 1;
|
|
3398
4073
|
return;
|
|
3399
4074
|
}
|
|
3400
4075
|
let pkgJson;
|
|
3401
4076
|
const localPkgJsonPath = join6(localPath, "package.json");
|
|
3402
4077
|
const localOmpJsonPath = join6(localPath, "omp.json");
|
|
3403
|
-
if (
|
|
3404
|
-
pkgJson = JSON.parse(await
|
|
3405
|
-
} else if (
|
|
3406
|
-
const ompJson = JSON.parse(await
|
|
4078
|
+
if (existsSync9(localPkgJsonPath)) {
|
|
4079
|
+
pkgJson = JSON.parse(await readFile4(localPkgJsonPath, "utf-8"));
|
|
4080
|
+
} else if (existsSync9(localOmpJsonPath)) {
|
|
4081
|
+
const ompJson = JSON.parse(await readFile4(localOmpJsonPath, "utf-8"));
|
|
3407
4082
|
pkgJson = {
|
|
3408
4083
|
name: ompJson.name || options.name || basename2(localPath),
|
|
3409
4084
|
version: ompJson.version || "0.0.0-dev",
|
|
@@ -3413,26 +4088,51 @@ async function linkPlugin(localPath, options = {}) {
|
|
|
3413
4088
|
install: ompJson.install
|
|
3414
4089
|
}
|
|
3415
4090
|
};
|
|
4091
|
+
console.log(source_default.dim(" Converting omp.json to package.json..."));
|
|
4092
|
+
await writeFile5(localPkgJsonPath, JSON.stringify(pkgJson, null, 2));
|
|
3416
4093
|
} else {
|
|
4094
|
+
console.log(source_default.yellow(" No package.json found in target directory."));
|
|
4095
|
+
const shouldCreate = await confirmCreate(localPkgJsonPath);
|
|
4096
|
+
if (!shouldCreate) {
|
|
4097
|
+
console.log(source_default.yellow(" Aborted: package.json required for linking"));
|
|
4098
|
+
process.exitCode = 1;
|
|
4099
|
+
return;
|
|
4100
|
+
}
|
|
3417
4101
|
pkgJson = {
|
|
3418
4102
|
name: options.name || basename2(localPath),
|
|
3419
4103
|
version: "0.0.0-dev",
|
|
3420
|
-
keywords: ["omp-plugin"]
|
|
4104
|
+
keywords: ["omp-plugin"],
|
|
4105
|
+
omp: {
|
|
4106
|
+
install: []
|
|
4107
|
+
}
|
|
3421
4108
|
};
|
|
3422
|
-
console.log(source_default.
|
|
4109
|
+
console.log(source_default.dim(" Creating minimal package.json..."));
|
|
4110
|
+
await writeFile5(localPkgJsonPath, JSON.stringify(pkgJson, null, 2));
|
|
3423
4111
|
}
|
|
3424
4112
|
const pluginName = options.name || pkgJson.name;
|
|
3425
4113
|
const pluginDir = join6(nodeModules, pluginName);
|
|
3426
4114
|
const pluginsJson = await loadPluginsJson(isGlobal);
|
|
3427
4115
|
if (pluginsJson.plugins[pluginName]) {
|
|
3428
|
-
|
|
3429
|
-
|
|
3430
|
-
|
|
4116
|
+
const existingSpec = pluginsJson.plugins[pluginName];
|
|
4117
|
+
const isLinked = existingSpec.startsWith("file:");
|
|
4118
|
+
if (isLinked) {
|
|
4119
|
+
console.log(source_default.yellow(`Plugin "${pluginName}" is already linked.`));
|
|
4120
|
+
console.log(source_default.dim(` Current link: ${existingSpec}`));
|
|
4121
|
+
console.log(source_default.dim(" Re-linking..."));
|
|
4122
|
+
} else if (options.force) {
|
|
4123
|
+
console.log(source_default.yellow(`Plugin "${pluginName}" is installed from npm. Overwriting with link...`));
|
|
4124
|
+
} else {
|
|
4125
|
+
console.log(source_default.yellow(`Plugin "${pluginName}" is already installed from npm.`));
|
|
4126
|
+
console.log(source_default.dim("Use omp uninstall first, or specify a different name with -n"));
|
|
4127
|
+
console.log(source_default.dim("Or use --force to overwrite the npm installation"));
|
|
4128
|
+
process.exitCode = 1;
|
|
4129
|
+
return;
|
|
4130
|
+
}
|
|
3431
4131
|
}
|
|
3432
4132
|
try {
|
|
3433
4133
|
console.log(source_default.blue(`Linking ${localPath}...`));
|
|
3434
|
-
await mkdir6(
|
|
3435
|
-
if (
|
|
4134
|
+
await mkdir6(dirname4(pluginDir), { recursive: true });
|
|
4135
|
+
if (existsSync9(pluginDir)) {
|
|
3436
4136
|
await rm3(pluginDir, { force: true, recursive: true });
|
|
3437
4137
|
}
|
|
3438
4138
|
await symlink2(localPath, pluginDir);
|
|
@@ -3447,6 +4147,7 @@ async function linkPlugin(localPath, options = {}) {
|
|
|
3447
4147
|
console.log(source_default.dim(" Changes to the source will be reflected immediately"));
|
|
3448
4148
|
} catch (err) {
|
|
3449
4149
|
console.log(source_default.red(`Error linking plugin: ${err.message}`));
|
|
4150
|
+
process.exitCode = 1;
|
|
3450
4151
|
try {
|
|
3451
4152
|
await rm3(pluginDir, { force: true });
|
|
3452
4153
|
} catch {}
|
|
@@ -3454,13 +4155,16 @@ async function linkPlugin(localPath, options = {}) {
|
|
|
3454
4155
|
}
|
|
3455
4156
|
|
|
3456
4157
|
// src/commands/list.ts
|
|
4158
|
+
init_paths();
|
|
4159
|
+
init_source();
|
|
3457
4160
|
async function listPlugins(options = {}) {
|
|
3458
|
-
const isGlobal = options
|
|
4161
|
+
const isGlobal = resolveScope(options);
|
|
3459
4162
|
const pluginsJson = await loadPluginsJson(isGlobal);
|
|
3460
4163
|
const pluginNames = Object.keys(pluginsJson.plugins);
|
|
3461
4164
|
if (pluginNames.length === 0) {
|
|
3462
4165
|
console.log(source_default.yellow("No plugins installed."));
|
|
3463
4166
|
console.log(source_default.dim("Install one with: omp install <package>"));
|
|
4167
|
+
process.exitCode = 1;
|
|
3464
4168
|
return;
|
|
3465
4169
|
}
|
|
3466
4170
|
if (options.json) {
|
|
@@ -3486,11 +4190,13 @@ async function listPlugins(options = {}) {
|
|
|
3486
4190
|
const specifier = pluginsJson.plugins[name];
|
|
3487
4191
|
const isLocal = specifier.startsWith("file:");
|
|
3488
4192
|
const disabled = pluginsJson.disabled?.includes(name);
|
|
3489
|
-
const
|
|
4193
|
+
const isMissing = !pkgJson;
|
|
4194
|
+
const version = pkgJson?.version ? source_default.dim(` v${pkgJson.version}`) : source_default.dim(` (${specifier})`);
|
|
3490
4195
|
const localBadge = isLocal ? source_default.cyan(" (local)") : "";
|
|
3491
4196
|
const disabledBadge = disabled ? source_default.yellow(" (disabled)") : "";
|
|
3492
|
-
const
|
|
3493
|
-
|
|
4197
|
+
const missingBadge = isMissing ? source_default.red(" (missing)") : "";
|
|
4198
|
+
const icon = disabled ? source_default.gray("\u25CB") : isMissing ? source_default.red("\u2717") : source_default.green("\u25C6");
|
|
4199
|
+
console.log(`${icon} ${source_default.bold(name)}${version}${localBadge}${disabledBadge}${missingBadge}`);
|
|
3494
4200
|
if (pkgJson?.description) {
|
|
3495
4201
|
console.log(source_default.dim(` ${pkgJson.description}`));
|
|
3496
4202
|
}
|
|
@@ -3507,15 +4213,22 @@ async function listPlugins(options = {}) {
|
|
|
3507
4213
|
}
|
|
3508
4214
|
|
|
3509
4215
|
// src/commands/outdated.ts
|
|
4216
|
+
init_paths();
|
|
4217
|
+
init_source();
|
|
3510
4218
|
async function showOutdated(options = {}) {
|
|
3511
|
-
const isGlobal = options
|
|
4219
|
+
const isGlobal = resolveScope(options);
|
|
3512
4220
|
const prefix = isGlobal ? PLUGINS_DIR : ".pi";
|
|
3513
4221
|
console.log(source_default.blue("Checking for outdated plugins..."));
|
|
3514
4222
|
try {
|
|
3515
4223
|
const outdated = await npmOutdated(prefix);
|
|
3516
4224
|
const pluginsJson = await loadPluginsJson(isGlobal);
|
|
3517
4225
|
const managedOutdated = Object.entries(outdated).filter(([name]) => {
|
|
3518
|
-
|
|
4226
|
+
const specifier = pluginsJson.plugins[name];
|
|
4227
|
+
if (!specifier)
|
|
4228
|
+
return false;
|
|
4229
|
+
if (specifier.startsWith("file:"))
|
|
4230
|
+
return false;
|
|
4231
|
+
return true;
|
|
3519
4232
|
});
|
|
3520
4233
|
if (managedOutdated.length === 0) {
|
|
3521
4234
|
console.log(source_default.green(`
|
|
@@ -3541,16 +4254,28 @@ Outdated plugins (${managedOutdated.length}):
|
|
|
3541
4254
|
const latestColor = hasMajorUpdate ? source_default.red : wantedColor;
|
|
3542
4255
|
console.log(` ${source_default.white(name.padEnd(28))}` + `${source_default.dim(current.padEnd(15))}` + `${wantedColor(wanted.padEnd(15))}` + `${latestColor(latest)}`);
|
|
3543
4256
|
}
|
|
4257
|
+
const localPlugins = Object.entries(pluginsJson.plugins).filter(([_, spec]) => spec.startsWith("file:"));
|
|
4258
|
+
if (localPlugins.length > 0) {
|
|
4259
|
+
console.log(source_default.dim(`
|
|
4260
|
+
Note: ${localPlugins.length} local plugin(s) excluded from check`));
|
|
4261
|
+
}
|
|
3544
4262
|
console.log();
|
|
3545
4263
|
console.log(source_default.dim("Update with: omp update [package]"));
|
|
3546
4264
|
console.log(source_default.dim(" - 'wanted' = latest within semver range"));
|
|
3547
4265
|
console.log(source_default.dim(" - 'latest' = latest available version"));
|
|
3548
4266
|
} catch (err) {
|
|
3549
4267
|
console.log(source_default.red(`Error checking outdated: ${err.message}`));
|
|
4268
|
+
process.exitCode = 1;
|
|
3550
4269
|
}
|
|
3551
4270
|
}
|
|
3552
4271
|
|
|
3553
4272
|
// src/commands/search.ts
|
|
4273
|
+
init_source();
|
|
4274
|
+
function truncate(str, maxLen) {
|
|
4275
|
+
if (!str || str.length <= maxLen)
|
|
4276
|
+
return str;
|
|
4277
|
+
return `${str.slice(0, maxLen - 3)}...`;
|
|
4278
|
+
}
|
|
3554
4279
|
async function searchPlugins(query, options = {}) {
|
|
3555
4280
|
console.log(source_default.blue(`Searching npm for "${query}" with omp-plugin keyword...`));
|
|
3556
4281
|
try {
|
|
@@ -3560,6 +4285,7 @@ async function searchPlugins(query, options = {}) {
|
|
|
3560
4285
|
No plugins found.`));
|
|
3561
4286
|
console.log(source_default.dim("Try a different search term, or search without keyword:"));
|
|
3562
4287
|
console.log(source_default.dim(" npm search omp-plugin"));
|
|
4288
|
+
process.exitCode = 1;
|
|
3563
4289
|
return;
|
|
3564
4290
|
}
|
|
3565
4291
|
const limit = options.limit || 20;
|
|
@@ -3574,7 +4300,7 @@ Found ${results.length} plugin(s):
|
|
|
3574
4300
|
for (const result of displayResults) {
|
|
3575
4301
|
console.log(source_default.green("\u25C6 ") + source_default.bold(result.name) + source_default.dim(` v${result.version}`));
|
|
3576
4302
|
if (result.description) {
|
|
3577
|
-
console.log(source_default.dim(` ${result.description}`));
|
|
4303
|
+
console.log(source_default.dim(` ${truncate(result.description, 100)}`));
|
|
3578
4304
|
}
|
|
3579
4305
|
if (result.keywords?.length) {
|
|
3580
4306
|
const otherKeywords = result.keywords.filter((k) => k !== "omp-plugin");
|
|
@@ -3589,34 +4315,89 @@ Found ${results.length} plugin(s):
|
|
|
3589
4315
|
}
|
|
3590
4316
|
console.log(source_default.dim("Install with: omp install <package-name>"));
|
|
3591
4317
|
} catch (err) {
|
|
3592
|
-
|
|
4318
|
+
const error = err;
|
|
4319
|
+
if (error.message.includes("ENOTFOUND") || error.message.includes("ETIMEDOUT") || error.message.includes("EAI_AGAIN")) {
|
|
4320
|
+
console.log(source_default.red(`
|
|
4321
|
+
Network error: Unable to reach npm registry.`));
|
|
4322
|
+
console.log(source_default.dim(" Check your internet connection and try again."));
|
|
4323
|
+
} else {
|
|
4324
|
+
console.log(source_default.red(`
|
|
4325
|
+
Search failed: ${error.message}`));
|
|
4326
|
+
}
|
|
4327
|
+
process.exitCode = 1;
|
|
3593
4328
|
}
|
|
3594
4329
|
}
|
|
3595
4330
|
|
|
3596
4331
|
// src/commands/uninstall.ts
|
|
3597
|
-
import { existsSync as
|
|
4332
|
+
import { existsSync as existsSync10 } from "fs";
|
|
3598
4333
|
import { rm as rm4 } from "fs/promises";
|
|
3599
4334
|
import { join as join7 } from "path";
|
|
4335
|
+
import { createInterface as createInterface3 } from "readline";
|
|
4336
|
+
init_paths();
|
|
4337
|
+
init_source();
|
|
3600
4338
|
async function uninstallPlugin(name, options = {}) {
|
|
3601
|
-
const isGlobal = options
|
|
4339
|
+
const isGlobal = resolveScope(options);
|
|
3602
4340
|
const prefix = isGlobal ? PLUGINS_DIR : ".pi";
|
|
3603
4341
|
const nodeModules = isGlobal ? NODE_MODULES_DIR : PROJECT_NODE_MODULES;
|
|
3604
4342
|
const pluginsJson = await loadPluginsJson(isGlobal);
|
|
3605
4343
|
if (!pluginsJson.plugins[name]) {
|
|
3606
4344
|
console.log(source_default.yellow(`Plugin "${name}" is not installed.`));
|
|
4345
|
+
process.exitCode = 1;
|
|
3607
4346
|
return;
|
|
3608
4347
|
}
|
|
3609
4348
|
try {
|
|
3610
4349
|
console.log(source_default.blue(`Uninstalling ${name}...`));
|
|
3611
4350
|
const pkgJson = await readPluginPackageJson(name, isGlobal);
|
|
4351
|
+
if (pkgJson?.dependencies) {
|
|
4352
|
+
const allPlugins = await getInstalledPlugins(isGlobal);
|
|
4353
|
+
const sharedDeps = [];
|
|
4354
|
+
for (const depName of Object.keys(pkgJson.dependencies)) {
|
|
4355
|
+
for (const [otherName, otherPkgJson] of allPlugins) {
|
|
4356
|
+
if (otherName !== name && otherPkgJson.dependencies?.[depName]) {
|
|
4357
|
+
sharedDeps.push(`${depName} (also used by ${otherName})`);
|
|
4358
|
+
break;
|
|
4359
|
+
}
|
|
4360
|
+
}
|
|
4361
|
+
}
|
|
4362
|
+
if (sharedDeps.length > 0) {
|
|
4363
|
+
console.log(source_default.yellow(`
|
|
4364
|
+
\u26A0 Warning: This plugin shares dependencies with other plugins:`));
|
|
4365
|
+
for (const dep of sharedDeps) {
|
|
4366
|
+
console.log(source_default.dim(` - ${dep}`));
|
|
4367
|
+
}
|
|
4368
|
+
console.log(source_default.dim(" These dependencies will remain installed."));
|
|
4369
|
+
}
|
|
4370
|
+
}
|
|
3612
4371
|
if (pkgJson) {
|
|
3613
|
-
await removePluginSymlinks(name, pkgJson);
|
|
4372
|
+
const result = await removePluginSymlinks(name, pkgJson, isGlobal);
|
|
4373
|
+
if (result.skippedNonSymlinks.length > 0) {
|
|
4374
|
+
console.log(source_default.yellow(`
|
|
4375
|
+
The following files are not symlinks and were not removed:`));
|
|
4376
|
+
for (const file of result.skippedNonSymlinks) {
|
|
4377
|
+
console.log(source_default.dim(` - ${file}`));
|
|
4378
|
+
}
|
|
4379
|
+
if (process.stdin.isTTY && process.stdout.isTTY) {
|
|
4380
|
+
const rl = createInterface3({ input: process.stdin, output: process.stdout });
|
|
4381
|
+
const answer = await new Promise((resolve5) => {
|
|
4382
|
+
rl.question(source_default.yellow("Delete these files anyway? [y/N] "), (ans) => {
|
|
4383
|
+
rl.close();
|
|
4384
|
+
resolve5(ans);
|
|
4385
|
+
});
|
|
4386
|
+
});
|
|
4387
|
+
if (answer.toLowerCase() === "y") {
|
|
4388
|
+
for (const file of result.skippedNonSymlinks) {
|
|
4389
|
+
await rm4(file, { force: true, recursive: true });
|
|
4390
|
+
console.log(source_default.dim(` Deleted: ${file}`));
|
|
4391
|
+
}
|
|
4392
|
+
}
|
|
4393
|
+
}
|
|
4394
|
+
}
|
|
3614
4395
|
}
|
|
3615
4396
|
try {
|
|
3616
4397
|
await npmUninstall([name], prefix);
|
|
3617
4398
|
} catch (_err) {
|
|
3618
4399
|
const pluginDir = join7(nodeModules, name);
|
|
3619
|
-
if (
|
|
4400
|
+
if (existsSync10(pluginDir)) {
|
|
3620
4401
|
await rm4(pluginDir, { recursive: true, force: true });
|
|
3621
4402
|
}
|
|
3622
4403
|
}
|
|
@@ -3631,6 +4412,7 @@ async function uninstallPlugin(name, options = {}) {
|
|
|
3631
4412
|
}
|
|
3632
4413
|
} catch (err) {
|
|
3633
4414
|
console.log(source_default.red(`Error uninstalling plugin: ${err.message}`));
|
|
4415
|
+
process.exitCode = 1;
|
|
3634
4416
|
if (options.json) {
|
|
3635
4417
|
console.log(JSON.stringify({ name, success: false, error: err.message }, null, 2));
|
|
3636
4418
|
}
|
|
@@ -3638,18 +4420,24 @@ async function uninstallPlugin(name, options = {}) {
|
|
|
3638
4420
|
}
|
|
3639
4421
|
|
|
3640
4422
|
// src/commands/update.ts
|
|
4423
|
+
import { rm as rm5 } from "fs/promises";
|
|
4424
|
+
import { join as join8 } from "path";
|
|
4425
|
+
init_paths();
|
|
4426
|
+
init_source();
|
|
3641
4427
|
async function updatePlugin(name, options = {}) {
|
|
3642
|
-
const isGlobal = options
|
|
4428
|
+
const isGlobal = resolveScope(options);
|
|
3643
4429
|
const prefix = isGlobal ? PLUGINS_DIR : ".pi";
|
|
3644
4430
|
const _nodeModules = isGlobal ? NODE_MODULES_DIR : PROJECT_NODE_MODULES;
|
|
3645
4431
|
const pluginsJson = await loadPluginsJson(isGlobal);
|
|
3646
4432
|
const pluginNames = Object.keys(pluginsJson.plugins);
|
|
3647
4433
|
if (pluginNames.length === 0) {
|
|
3648
4434
|
console.log(source_default.yellow("No plugins installed."));
|
|
4435
|
+
process.exitCode = 1;
|
|
3649
4436
|
return;
|
|
3650
4437
|
}
|
|
3651
4438
|
if (name && !pluginsJson.plugins[name]) {
|
|
3652
4439
|
console.log(source_default.yellow(`Plugin "${name}" is not installed.`));
|
|
4440
|
+
process.exitCode = 1;
|
|
3653
4441
|
return;
|
|
3654
4442
|
}
|
|
3655
4443
|
const toUpdate = name ? [name] : pluginNames;
|
|
@@ -3666,25 +4454,45 @@ async function updatePlugin(name, options = {}) {
|
|
|
3666
4454
|
}
|
|
3667
4455
|
if (npmPlugins.length === 0) {
|
|
3668
4456
|
console.log(source_default.yellow("No npm plugins to update."));
|
|
4457
|
+
process.exitCode = 1;
|
|
3669
4458
|
return;
|
|
3670
4459
|
}
|
|
3671
4460
|
console.log(source_default.blue(`Updating ${npmPlugins.length} plugin(s)...`));
|
|
3672
4461
|
const results = [];
|
|
4462
|
+
const oldPkgJsons = new Map;
|
|
4463
|
+
const beforeVersions = {};
|
|
4464
|
+
const oldInstallEntries = new Map;
|
|
3673
4465
|
try {
|
|
3674
|
-
const beforeVersions = {};
|
|
3675
4466
|
for (const pluginName of npmPlugins) {
|
|
3676
4467
|
const pkgJson = await readPluginPackageJson(pluginName, isGlobal);
|
|
3677
4468
|
if (pkgJson) {
|
|
4469
|
+
oldPkgJsons.set(pluginName, pkgJson);
|
|
3678
4470
|
beforeVersions[pluginName] = pkgJson.version;
|
|
3679
|
-
|
|
4471
|
+
if (pkgJson.omp?.install) {
|
|
4472
|
+
oldInstallEntries.set(pluginName, [...pkgJson.omp.install]);
|
|
4473
|
+
}
|
|
4474
|
+
await removePluginSymlinks(pluginName, pkgJson, isGlobal);
|
|
3680
4475
|
}
|
|
3681
4476
|
}
|
|
3682
4477
|
await npmUpdate(npmPlugins, prefix);
|
|
4478
|
+
const baseDir = isGlobal ? PI_CONFIG_DIR : PROJECT_PI_DIR;
|
|
3683
4479
|
for (const pluginName of npmPlugins) {
|
|
3684
4480
|
const pkgJson = await readPluginPackageJson(pluginName, isGlobal);
|
|
3685
4481
|
if (pkgJson) {
|
|
3686
4482
|
const beforeVersion = beforeVersions[pluginName] || "unknown";
|
|
3687
4483
|
const afterVersion = pkgJson.version;
|
|
4484
|
+
const oldEntries = oldInstallEntries.get(pluginName) || [];
|
|
4485
|
+
const newEntries = pkgJson.omp?.install || [];
|
|
4486
|
+
const newDests = new Set(newEntries.map((e) => e.dest));
|
|
4487
|
+
for (const oldEntry of oldEntries) {
|
|
4488
|
+
if (!newDests.has(oldEntry.dest)) {
|
|
4489
|
+
const dest = join8(baseDir, oldEntry.dest);
|
|
4490
|
+
try {
|
|
4491
|
+
await rm5(dest, { force: true });
|
|
4492
|
+
console.log(source_default.dim(` Removed orphaned: ${oldEntry.dest}`));
|
|
4493
|
+
} catch {}
|
|
4494
|
+
}
|
|
4495
|
+
}
|
|
3688
4496
|
await createPluginSymlinks(pluginName, pkgJson, isGlobal);
|
|
3689
4497
|
const changed = beforeVersion !== afterVersion;
|
|
3690
4498
|
if (changed) {
|
|
@@ -3707,32 +4515,56 @@ async function updatePlugin(name, options = {}) {
|
|
|
3707
4515
|
console.log(JSON.stringify({ results }, null, 2));
|
|
3708
4516
|
}
|
|
3709
4517
|
} catch (err) {
|
|
4518
|
+
if (oldPkgJsons.size > 0) {
|
|
4519
|
+
console.log(source_default.yellow(" Update failed, restoring symlinks..."));
|
|
4520
|
+
for (const [pluginName, pkgJson] of oldPkgJsons) {
|
|
4521
|
+
try {
|
|
4522
|
+
await createPluginSymlinks(pluginName, pkgJson, isGlobal);
|
|
4523
|
+
} catch (restoreErr) {
|
|
4524
|
+
console.log(source_default.red(` Failed to restore symlinks for ${pluginName}: ${restoreErr.message}`));
|
|
4525
|
+
}
|
|
4526
|
+
}
|
|
4527
|
+
}
|
|
3710
4528
|
console.log(source_default.red(`Error updating plugins: ${err.message}`));
|
|
4529
|
+
process.exitCode = 1;
|
|
3711
4530
|
}
|
|
3712
4531
|
}
|
|
3713
4532
|
|
|
3714
4533
|
// src/commands/why.ts
|
|
3715
|
-
import { existsSync as
|
|
4534
|
+
import { existsSync as existsSync11, lstatSync as lstatSync2 } from "fs";
|
|
3716
4535
|
import { readlink as readlink2 } from "fs/promises";
|
|
3717
|
-
import { join as
|
|
4536
|
+
import { join as join9, relative, resolve as resolve5 } from "path";
|
|
4537
|
+
init_paths();
|
|
4538
|
+
init_source();
|
|
3718
4539
|
async function whyFile(filePath, options = {}) {
|
|
3719
|
-
const isGlobal = options
|
|
4540
|
+
const isGlobal = resolveScope(options);
|
|
4541
|
+
const baseDir = isGlobal ? PI_CONFIG_DIR : resolve5(PROJECT_PI_DIR);
|
|
3720
4542
|
let relativePath = filePath;
|
|
3721
|
-
if (
|
|
3722
|
-
|
|
3723
|
-
|
|
3724
|
-
|
|
4543
|
+
if (isGlobal) {
|
|
4544
|
+
if (filePath.startsWith(PI_CONFIG_DIR)) {
|
|
4545
|
+
relativePath = relative(PI_CONFIG_DIR, filePath);
|
|
4546
|
+
} else if (filePath.startsWith("~/.pi/")) {
|
|
4547
|
+
relativePath = filePath.slice(6);
|
|
4548
|
+
}
|
|
4549
|
+
} else {
|
|
4550
|
+
const resolvedProjectDir = resolve5(PROJECT_PI_DIR);
|
|
4551
|
+
if (filePath.startsWith(resolvedProjectDir)) {
|
|
4552
|
+
relativePath = relative(resolvedProjectDir, filePath);
|
|
4553
|
+
} else if (filePath.startsWith(".pi/")) {
|
|
4554
|
+
relativePath = filePath.slice(4);
|
|
4555
|
+
}
|
|
3725
4556
|
}
|
|
3726
4557
|
if (!relativePath.startsWith("agent/")) {
|
|
3727
4558
|
const withAgent = `agent/${relativePath}`;
|
|
3728
|
-
const fullWithAgent =
|
|
3729
|
-
if (
|
|
4559
|
+
const fullWithAgent = join9(baseDir, withAgent);
|
|
4560
|
+
if (existsSync11(fullWithAgent)) {
|
|
3730
4561
|
relativePath = withAgent;
|
|
3731
4562
|
}
|
|
3732
4563
|
}
|
|
3733
|
-
const fullPath =
|
|
3734
|
-
if (!
|
|
4564
|
+
const fullPath = join9(baseDir, relativePath);
|
|
4565
|
+
if (!existsSync11(fullPath)) {
|
|
3735
4566
|
console.log(source_default.yellow(`File not found: ${fullPath}`));
|
|
4567
|
+
process.exitCode = 1;
|
|
3736
4568
|
return;
|
|
3737
4569
|
}
|
|
3738
4570
|
const stats = lstatSync2(fullPath);
|
|
@@ -3742,7 +4574,7 @@ async function whyFile(filePath, options = {}) {
|
|
|
3742
4574
|
target = await readlink2(fullPath);
|
|
3743
4575
|
}
|
|
3744
4576
|
const installedPlugins = await getInstalledPlugins(isGlobal);
|
|
3745
|
-
const result = await traceInstalledFile(relativePath, installedPlugins);
|
|
4577
|
+
const result = await traceInstalledFile(relativePath, installedPlugins, isGlobal);
|
|
3746
4578
|
if (options.json) {
|
|
3747
4579
|
console.log(JSON.stringify({
|
|
3748
4580
|
path: relativePath,
|
|
@@ -3763,9 +4595,23 @@ async function whyFile(filePath, options = {}) {
|
|
|
3763
4595
|
console.log();
|
|
3764
4596
|
}
|
|
3765
4597
|
if (result) {
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
4598
|
+
if (!isSymlink) {
|
|
4599
|
+
console.log(source_default.yellow("\u26A0 This file exists but is not a symlink"));
|
|
4600
|
+
console.log(source_default.dim(" It may have been manually created or the symlink was replaced."));
|
|
4601
|
+
console.log(source_default.dim(` Expected to be installed by: ${result.plugin}`));
|
|
4602
|
+
} else {
|
|
4603
|
+
const expectedSrc = join9(getPluginSourceDir(result.plugin, isGlobal), result.entry.src);
|
|
4604
|
+
if (target !== expectedSrc) {
|
|
4605
|
+
console.log(source_default.yellow("\u26A0 Symlink target does not match expected source"));
|
|
4606
|
+
console.log(source_default.dim(` Expected: ${expectedSrc}`));
|
|
4607
|
+
console.log(source_default.dim(` Actual: ${target}`));
|
|
4608
|
+
console.log(source_default.dim(` Expected to be installed by: ${result.plugin}`));
|
|
4609
|
+
} else {
|
|
4610
|
+
console.log(source_default.green(`\u2713 Installed by: ${result.plugin}`));
|
|
4611
|
+
console.log(source_default.dim(` Source: ${result.entry.src}`));
|
|
4612
|
+
console.log(source_default.dim(` Dest: ${result.entry.dest}`));
|
|
4613
|
+
}
|
|
4614
|
+
}
|
|
3769
4615
|
const pkgJson = await readPluginPackageJson(result.plugin, isGlobal);
|
|
3770
4616
|
if (pkgJson) {
|
|
3771
4617
|
console.log();
|
|
@@ -3780,20 +4626,39 @@ async function whyFile(filePath, options = {}) {
|
|
|
3780
4626
|
}
|
|
3781
4627
|
}
|
|
3782
4628
|
|
|
4629
|
+
// src/errors.ts
|
|
4630
|
+
init_source();
|
|
4631
|
+
function withErrorHandling(fn) {
|
|
4632
|
+
return async (...args) => {
|
|
4633
|
+
try {
|
|
4634
|
+
await fn(...args);
|
|
4635
|
+
} catch (err) {
|
|
4636
|
+
const error = err;
|
|
4637
|
+
console.log(source_default.red(`Error: ${error.message}`));
|
|
4638
|
+
if (process.env.DEBUG) {
|
|
4639
|
+
console.log(source_default.dim(error.stack));
|
|
4640
|
+
}
|
|
4641
|
+
process.exitCode = 1;
|
|
4642
|
+
}
|
|
4643
|
+
};
|
|
4644
|
+
}
|
|
4645
|
+
|
|
3783
4646
|
// src/migrate.ts
|
|
3784
|
-
import { existsSync as
|
|
3785
|
-
import { mkdir as mkdir7, readFile as
|
|
3786
|
-
import { basename as basename3, join as
|
|
3787
|
-
import { createInterface as
|
|
4647
|
+
import { existsSync as existsSync12 } from "fs";
|
|
4648
|
+
import { mkdir as mkdir7, readFile as readFile5, rename, rm as rm6, symlink as symlink3, writeFile as writeFile6 } from "fs/promises";
|
|
4649
|
+
import { basename as basename3, join as join10 } from "path";
|
|
4650
|
+
import { createInterface as createInterface4 } from "readline";
|
|
4651
|
+
init_paths();
|
|
4652
|
+
init_source();
|
|
3788
4653
|
async function promptMigration() {
|
|
3789
|
-
const rl =
|
|
4654
|
+
const rl = createInterface4({
|
|
3790
4655
|
input: process.stdin,
|
|
3791
4656
|
output: process.stdout
|
|
3792
4657
|
});
|
|
3793
|
-
return new Promise((
|
|
4658
|
+
return new Promise((resolve6) => {
|
|
3794
4659
|
rl.question(source_default.yellow("Migrate to npm-native format? [y/N] "), (answer) => {
|
|
3795
4660
|
rl.close();
|
|
3796
|
-
|
|
4661
|
+
resolve6(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
|
|
3797
4662
|
});
|
|
3798
4663
|
});
|
|
3799
4664
|
}
|
|
@@ -3838,7 +4703,7 @@ Migrating to npm-native format...`));
|
|
|
3838
4703
|
} else if (info.type === "local" && info.path) {
|
|
3839
4704
|
newPluginsJson.plugins[name] = `file:${info.path}`;
|
|
3840
4705
|
} else if (info.type === "github" && info.repo) {
|
|
3841
|
-
newPluginsJson.plugins[name] = `file:${
|
|
4706
|
+
newPluginsJson.plugins[name] = `file:${join10(NODE_MODULES_DIR, name)}`;
|
|
3842
4707
|
}
|
|
3843
4708
|
migrated.push(name);
|
|
3844
4709
|
} catch (err) {
|
|
@@ -3848,6 +4713,13 @@ Migrating to npm-native format...`));
|
|
|
3848
4713
|
}
|
|
3849
4714
|
await savePluginsJson(newPluginsJson, true);
|
|
3850
4715
|
await archiveLegacyManifest();
|
|
4716
|
+
console.log(source_default.dim(" Creating symlinks..."));
|
|
4717
|
+
for (const [name] of Object.entries(newPluginsJson.plugins)) {
|
|
4718
|
+
const pkgJson = await readPluginPackageJson(name, true);
|
|
4719
|
+
if (pkgJson?.omp?.install?.length) {
|
|
4720
|
+
await createPluginSymlinks(name, pkgJson, true);
|
|
4721
|
+
}
|
|
4722
|
+
}
|
|
3851
4723
|
console.log();
|
|
3852
4724
|
console.log(source_default.green(`\u2713 Migrated ${migrated.length} plugin(s)`));
|
|
3853
4725
|
if (failed.length > 0) {
|
|
@@ -3860,28 +4732,28 @@ Migrating to npm-native format...`));
|
|
|
3860
4732
|
}
|
|
3861
4733
|
}
|
|
3862
4734
|
async function migratePlugin(name, info) {
|
|
3863
|
-
const oldPluginDir =
|
|
3864
|
-
const newPluginDir =
|
|
3865
|
-
if (!
|
|
4735
|
+
const oldPluginDir = join10(PLUGINS_DIR, name);
|
|
4736
|
+
const newPluginDir = join10(NODE_MODULES_DIR, name);
|
|
4737
|
+
if (!existsSync12(oldPluginDir)) {
|
|
3866
4738
|
throw new Error(`Plugin directory not found: ${oldPluginDir}`);
|
|
3867
4739
|
}
|
|
3868
4740
|
if (info.linked && info.path) {
|
|
3869
4741
|
await mkdir7(NODE_MODULES_DIR, { recursive: true });
|
|
3870
|
-
if (
|
|
3871
|
-
await
|
|
4742
|
+
if (existsSync12(newPluginDir)) {
|
|
4743
|
+
await rm6(newPluginDir, { force: true, recursive: true });
|
|
3872
4744
|
}
|
|
3873
4745
|
await symlink3(info.path, newPluginDir);
|
|
3874
|
-
await
|
|
4746
|
+
await rm6(oldPluginDir, { force: true });
|
|
3875
4747
|
return;
|
|
3876
4748
|
}
|
|
3877
|
-
if (
|
|
3878
|
-
await
|
|
4749
|
+
if (existsSync12(newPluginDir)) {
|
|
4750
|
+
await rm6(newPluginDir, { force: true, recursive: true });
|
|
3879
4751
|
}
|
|
3880
4752
|
await rename(oldPluginDir, newPluginDir);
|
|
3881
|
-
const pkgJsonPath =
|
|
3882
|
-
const ompJsonPath =
|
|
3883
|
-
if (!
|
|
3884
|
-
const ompJson = JSON.parse(await
|
|
4753
|
+
const pkgJsonPath = join10(newPluginDir, "package.json");
|
|
4754
|
+
const ompJsonPath = join10(newPluginDir, "omp.json");
|
|
4755
|
+
if (!existsSync12(pkgJsonPath) && existsSync12(ompJsonPath)) {
|
|
4756
|
+
const ompJson = JSON.parse(await readFile5(ompJsonPath, "utf-8"));
|
|
3885
4757
|
const pkgJson = {
|
|
3886
4758
|
name: ompJson.name || name,
|
|
3887
4759
|
version: ompJson.version || info.version || "0.0.0",
|
|
@@ -3891,20 +4763,44 @@ async function migratePlugin(name, info) {
|
|
|
3891
4763
|
install: ompJson.install
|
|
3892
4764
|
}
|
|
3893
4765
|
};
|
|
3894
|
-
await
|
|
4766
|
+
await writeFile6(pkgJsonPath, JSON.stringify(pkgJson, null, 2));
|
|
3895
4767
|
}
|
|
3896
4768
|
}
|
|
3897
4769
|
async function archiveLegacyManifest() {
|
|
3898
|
-
if (!
|
|
4770
|
+
if (!existsSync12(LEGACY_MANIFEST_PATH)) {
|
|
3899
4771
|
return;
|
|
3900
4772
|
}
|
|
3901
|
-
const archivePath =
|
|
4773
|
+
const archivePath = join10(PLUGINS_DIR, `manifest.json.bak.${Date.now()}`);
|
|
3902
4774
|
await rename(LEGACY_MANIFEST_PATH, archivePath);
|
|
3903
4775
|
console.log(source_default.dim(` Archived old manifest to ${basename3(archivePath)}`));
|
|
3904
4776
|
}
|
|
3905
4777
|
|
|
3906
4778
|
// src/cli.ts
|
|
3907
|
-
|
|
4779
|
+
init_source();
|
|
4780
|
+
|
|
4781
|
+
// node_modules/commander/esm.mjs
|
|
4782
|
+
var import__ = __toESM(require_commander(), 1);
|
|
4783
|
+
var {
|
|
4784
|
+
program,
|
|
4785
|
+
createCommand,
|
|
4786
|
+
createArgument,
|
|
4787
|
+
createOption,
|
|
4788
|
+
CommanderError,
|
|
4789
|
+
InvalidArgumentError,
|
|
4790
|
+
InvalidOptionArgumentError,
|
|
4791
|
+
Command,
|
|
4792
|
+
Argument,
|
|
4793
|
+
Option,
|
|
4794
|
+
Help
|
|
4795
|
+
} = import__.default;
|
|
4796
|
+
|
|
4797
|
+
// src/cli.ts
|
|
4798
|
+
var npmCheck = checkNpmAvailable();
|
|
4799
|
+
if (!npmCheck.available) {
|
|
4800
|
+
console.log(source_default.red(npmCheck.error));
|
|
4801
|
+
process.exit(1);
|
|
4802
|
+
}
|
|
4803
|
+
program.name("omp").description("Oh My Pi - Plugin manager for pi configuration").version("0.2.0");
|
|
3908
4804
|
program.hook("preAction", async (thisCommand) => {
|
|
3909
4805
|
const migratingCommands = ["install", "uninstall", "update", "list", "link"];
|
|
3910
4806
|
if (migratingCommands.includes(thisCommand.name())) {
|
|
@@ -3918,24 +4814,24 @@ Examples:
|
|
|
3918
4814
|
$ omp install @myorg/cool-theme # Scoped package
|
|
3919
4815
|
$ omp install ./local/path # Local directory (copies)
|
|
3920
4816
|
$ omp install # Install all from plugins.json
|
|
3921
|
-
`).option("-g, --global", "Install globally to ~/.pi
|
|
3922
|
-
program.command("uninstall <name>").alias("rm").description("Remove plugin and its symlinks").option("-g, --global", "Uninstall from ~/.pi
|
|
3923
|
-
program.command("update [name]").alias("up").description("Update to latest within semver range").option("-g, --global", "Update global plugins
|
|
3924
|
-
program.command("list").alias("ls").description("Show installed plugins").option("-g, --global", "List global plugins
|
|
4817
|
+
`).option("-g, --global", "Install globally to ~/.pi").option("-l, --local", "Install to project-local .pi/").option("-S, --save", "Add to plugins.json").option("-D, --save-dev", "Add as dev dependency").option("--force", "Overwrite conflicts without prompting").option("--json", "Output as JSON").action(withErrorHandling(installPlugin));
|
|
4818
|
+
program.command("uninstall <name>").alias("rm").description("Remove plugin and its symlinks").option("-g, --global", "Uninstall from ~/.pi").option("-l, --local", "Uninstall from project-local .pi/").option("--json", "Output as JSON").action(withErrorHandling(uninstallPlugin));
|
|
4819
|
+
program.command("update [name]").alias("up").description("Update to latest within semver range").option("-g, --global", "Update global plugins").option("-l, --local", "Update project-local plugins").option("--json", "Output as JSON").action(withErrorHandling(updatePlugin));
|
|
4820
|
+
program.command("list").alias("ls").description("Show installed plugins").option("-g, --global", "List global plugins").option("-l, --local", "List project-local plugins").option("--json", "Output as JSON").action(withErrorHandling(listPlugins));
|
|
3925
4821
|
program.command("link <path>").description("Symlink local plugin (dev mode)").addHelpText("after", `
|
|
3926
4822
|
Unlike install, link creates a symlink to the original directory,
|
|
3927
4823
|
so changes are reflected immediately without reinstalling.
|
|
3928
|
-
`).option("-n, --name <name>", "Custom name for the plugin").option("-g, --global", "Link globally (
|
|
3929
|
-
program.command("init").description("Create .pi/plugins.json in current project").option("--force", "Overwrite existing plugins.json").action(initProject);
|
|
3930
|
-
program.command("search <query>").description("Search npm for omp-plugin keyword").option("--json", "Output as JSON").option("--limit <n>", "Maximum results to show", "20").action((query, options) => searchPlugins(query, { ...options, limit: parseInt(options.limit, 10) }));
|
|
3931
|
-
program.command("info <package>").description("Show plugin details before install").option("--json", "Output as JSON").option("--versions", "Show available versions").action(showInfo);
|
|
3932
|
-
program.command("outdated").description("List plugins with newer versions").option("-g, --global", "Check global plugins
|
|
3933
|
-
program.command("doctor").description("Check for broken symlinks, conflicts").option("-g, --global", "Check global plugins
|
|
3934
|
-
program.command("create <name>").description("Scaffold new plugin from template").option("-d, --description <desc>", "Plugin description").option("-a, --author <author>", "Plugin author").action(createPlugin);
|
|
3935
|
-
program.command("why <file>").description("Show which plugin installed a file").option("-g, --global", "Check global plugins
|
|
3936
|
-
program.command("enable <name>").description("Enable a disabled plugin").option("-g, --global", "Target global plugins
|
|
3937
|
-
program.command("disable <name>").description("Disable plugin without uninstalling").option("-g, --global", "Target global plugins
|
|
3938
|
-
program.command("migrate").description("Migrate from legacy manifest.json to npm-native format").action(async () => {
|
|
4824
|
+
`).option("-n, --name <name>", "Custom name for the plugin").option("-g, --global", "Link globally").option("-l, --local", "Link to project-local .pi/").option("--force", "Overwrite existing npm-installed plugin").action(withErrorHandling(linkPlugin));
|
|
4825
|
+
program.command("init").description("Create .pi/plugins.json in current project").option("--force", "Overwrite existing plugins.json").action(withErrorHandling(initProject));
|
|
4826
|
+
program.command("search <query>").description("Search npm for omp-plugin keyword").option("--json", "Output as JSON").option("--limit <n>", "Maximum results to show", "20").action(withErrorHandling((query, options) => searchPlugins(query, { ...options, limit: parseInt(options.limit, 10) })));
|
|
4827
|
+
program.command("info <package>").description("Show plugin details before install").option("--json", "Output as JSON").option("--versions", "Show available versions").option("--all-versions", "Show all published versions").action(withErrorHandling(showInfo));
|
|
4828
|
+
program.command("outdated").description("List plugins with newer versions").option("-g, --global", "Check global plugins").option("-l, --local", "Check project-local plugins").option("--json", "Output as JSON").action(withErrorHandling(showOutdated));
|
|
4829
|
+
program.command("doctor").description("Check for broken symlinks, conflicts").option("-g, --global", "Check global plugins").option("-l, --local", "Check project-local plugins").option("--fix", "Attempt to fix issues").option("--json", "Output as JSON").action(withErrorHandling(runDoctor));
|
|
4830
|
+
program.command("create <name>").description("Scaffold new plugin from template").option("-d, --description <desc>", "Plugin description").option("-a, --author <author>", "Plugin author").action(withErrorHandling(createPlugin));
|
|
4831
|
+
program.command("why <file>").description("Show which plugin installed a file").option("-g, --global", "Check global plugins").option("-l, --local", "Check project-local plugins").option("--json", "Output as JSON").action(withErrorHandling(whyFile));
|
|
4832
|
+
program.command("enable <name>").description("Enable a disabled plugin").option("-g, --global", "Target global plugins").option("-l, --local", "Target project-local plugins").option("--json", "Output as JSON").action(withErrorHandling(enablePlugin));
|
|
4833
|
+
program.command("disable <name>").description("Disable plugin without uninstalling").option("-g, --global", "Target global plugins").option("-l, --local", "Target project-local plugins").option("--json", "Output as JSON").action(withErrorHandling(disablePlugin));
|
|
4834
|
+
program.command("migrate").description("Migrate from legacy manifest.json to npm-native format").action(withErrorHandling(async () => {
|
|
3939
4835
|
await migrateToNpm();
|
|
3940
|
-
});
|
|
4836
|
+
}));
|
|
3941
4837
|
program.parse();
|