@codemcp/skills 2.1.0 → 2.1.1
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/dist/api.js +1 -2
- package/dist/{chunk-US7NTYE7.js → chunk-BF4FUODT.js} +364 -1116
- package/dist/cli.js +122 -817
- package/package.json +2 -2
- package/dist/chunk-JSBRDJBE.js +0 -30
- package/dist/chunk-OAWSLH2D.js +0 -1294
- package/dist/dist-TGUYKB34.js +0 -41
|
@@ -1,7 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
8
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
19
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
20
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
21
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
22
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
23
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
24
|
+
mod
|
|
25
|
+
));
|
|
5
26
|
|
|
6
27
|
// ../../node_modules/.pnpm/sisteransi@1.0.5/node_modules/sisteransi/src/index.js
|
|
7
28
|
var require_src = __commonJS({
|
|
@@ -194,6 +215,10 @@ var AGENTS_DIR = ".agents";
|
|
|
194
215
|
var LOCK_FILE = ".skill-lock.json";
|
|
195
216
|
var CURRENT_VERSION = 3;
|
|
196
217
|
function getSkillLockPath() {
|
|
218
|
+
const xdgStateHome = process.env.XDG_STATE_HOME;
|
|
219
|
+
if (xdgStateHome) {
|
|
220
|
+
return join(xdgStateHome, "skills", LOCK_FILE);
|
|
221
|
+
}
|
|
197
222
|
return join(homedir(), AGENTS_DIR, LOCK_FILE);
|
|
198
223
|
}
|
|
199
224
|
async function readSkillLock() {
|
|
@@ -421,7 +446,6 @@ import { stripVTControlCharacters as S2 } from "util";
|
|
|
421
446
|
|
|
422
447
|
// ../../node_modules/.pnpm/@clack+core@0.5.0/node_modules/@clack/core/dist/index.mjs
|
|
423
448
|
var import_sisteransi = __toESM(require_src(), 1);
|
|
424
|
-
var import_picocolors = __toESM(require_picocolors(), 1);
|
|
425
449
|
import { stdin as j, stdout as M } from "process";
|
|
426
450
|
import * as g from "readline";
|
|
427
451
|
import O from "readline";
|
|
@@ -884,25 +908,9 @@ var LD = class extends x {
|
|
|
884
908
|
this.value = this._value.value;
|
|
885
909
|
}
|
|
886
910
|
};
|
|
887
|
-
var RD = class extends x {
|
|
888
|
-
get valueWithCursor() {
|
|
889
|
-
if (this.state === "submit") return this.value;
|
|
890
|
-
if (this.cursor >= this.value.length) return `${this.value}\u2588`;
|
|
891
|
-
const u2 = this.value.slice(0, this.cursor), [t, ...F2] = this.value.slice(this.cursor);
|
|
892
|
-
return `${u2}${import_picocolors.default.inverse(t)}${F2.join("")}`;
|
|
893
|
-
}
|
|
894
|
-
get cursor() {
|
|
895
|
-
return this._cursor;
|
|
896
|
-
}
|
|
897
|
-
constructor(u2) {
|
|
898
|
-
super(u2), this.on("finalize", () => {
|
|
899
|
-
this.value || (this.value = u2.defaultValue);
|
|
900
|
-
});
|
|
901
|
-
}
|
|
902
|
-
};
|
|
903
911
|
|
|
904
912
|
// ../../node_modules/.pnpm/@clack+prompts@0.11.0/node_modules/@clack/prompts/dist/index.mjs
|
|
905
|
-
var
|
|
913
|
+
var import_picocolors = __toESM(require_picocolors(), 1);
|
|
906
914
|
var import_sisteransi2 = __toESM(require_src(), 1);
|
|
907
915
|
import y2 from "process";
|
|
908
916
|
function ce() {
|
|
@@ -935,13 +943,13 @@ var b2 = (t) => {
|
|
|
935
943
|
switch (t) {
|
|
936
944
|
case "initial":
|
|
937
945
|
case "active":
|
|
938
|
-
return
|
|
946
|
+
return import_picocolors.default.cyan(le);
|
|
939
947
|
case "cancel":
|
|
940
|
-
return
|
|
948
|
+
return import_picocolors.default.red(L2);
|
|
941
949
|
case "error":
|
|
942
|
-
return
|
|
950
|
+
return import_picocolors.default.yellow(W2);
|
|
943
951
|
case "submit":
|
|
944
|
-
return
|
|
952
|
+
return import_picocolors.default.green(C);
|
|
945
953
|
}
|
|
946
954
|
};
|
|
947
955
|
var G2 = (t) => {
|
|
@@ -949,47 +957,26 @@ var G2 = (t) => {
|
|
|
949
957
|
let l2 = 0;
|
|
950
958
|
n >= l2 + a - 3 ? l2 = Math.max(Math.min(n - a + 3, r2.length - a), 0) : n < l2 + 2 && (l2 = Math.max(n - 2, 0));
|
|
951
959
|
const $2 = a < r2.length && l2 > 0, g2 = a < r2.length && l2 + a < r2.length;
|
|
952
|
-
return r2.slice(l2, l2 + a).map((p2,
|
|
953
|
-
const j2 =
|
|
954
|
-
return j2 || E ?
|
|
960
|
+
return r2.slice(l2, l2 + a).map((p2, v, f) => {
|
|
961
|
+
const j2 = v === 0 && $2, E = v === f.length - 1 && g2;
|
|
962
|
+
return j2 || E ? import_picocolors.default.dim("...") : i(p2, v + l2 === n);
|
|
955
963
|
});
|
|
956
964
|
};
|
|
957
|
-
var he = (t) => new RD({ validate: t.validate, placeholder: t.placeholder, defaultValue: t.defaultValue, initialValue: t.initialValue, render() {
|
|
958
|
-
const n = `${import_picocolors2.default.gray(o)}
|
|
959
|
-
${b2(this.state)} ${t.message}
|
|
960
|
-
`, r2 = t.placeholder ? import_picocolors2.default.inverse(t.placeholder[0]) + import_picocolors2.default.dim(t.placeholder.slice(1)) : import_picocolors2.default.inverse(import_picocolors2.default.hidden("_")), i = this.value ? this.valueWithCursor : r2;
|
|
961
|
-
switch (this.state) {
|
|
962
|
-
case "error":
|
|
963
|
-
return `${n.trim()}
|
|
964
|
-
${import_picocolors2.default.yellow(o)} ${i}
|
|
965
|
-
${import_picocolors2.default.yellow(d2)} ${import_picocolors2.default.yellow(this.error)}
|
|
966
|
-
`;
|
|
967
|
-
case "submit":
|
|
968
|
-
return `${n}${import_picocolors2.default.gray(o)} ${import_picocolors2.default.dim(this.value || t.placeholder)}`;
|
|
969
|
-
case "cancel":
|
|
970
|
-
return `${n}${import_picocolors2.default.gray(o)} ${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(this.value ?? ""))}${this.value?.trim() ? `
|
|
971
|
-
${import_picocolors2.default.gray(o)}` : ""}`;
|
|
972
|
-
default:
|
|
973
|
-
return `${n}${import_picocolors2.default.cyan(o)} ${i}
|
|
974
|
-
${import_picocolors2.default.cyan(d2)}
|
|
975
|
-
`;
|
|
976
|
-
}
|
|
977
|
-
} }).prompt();
|
|
978
965
|
var ye = (t) => {
|
|
979
966
|
const n = t.active ?? "Yes", r2 = t.inactive ?? "No";
|
|
980
967
|
return new dD({ active: n, inactive: r2, initialValue: t.initialValue ?? true, render() {
|
|
981
|
-
const i = `${
|
|
968
|
+
const i = `${import_picocolors.default.gray(o)}
|
|
982
969
|
${b2(this.state)} ${t.message}
|
|
983
970
|
`, s = this.value ? n : r2;
|
|
984
971
|
switch (this.state) {
|
|
985
972
|
case "submit":
|
|
986
|
-
return `${i}${
|
|
973
|
+
return `${i}${import_picocolors.default.gray(o)} ${import_picocolors.default.dim(s)}`;
|
|
987
974
|
case "cancel":
|
|
988
|
-
return `${i}${
|
|
989
|
-
${
|
|
975
|
+
return `${i}${import_picocolors.default.gray(o)} ${import_picocolors.default.strikethrough(import_picocolors.default.dim(s))}
|
|
976
|
+
${import_picocolors.default.gray(o)}`;
|
|
990
977
|
default:
|
|
991
|
-
return `${i}${
|
|
992
|
-
${
|
|
978
|
+
return `${i}${import_picocolors.default.cyan(o)} ${this.value ? `${import_picocolors.default.green(k2)} ${n}` : `${import_picocolors.default.dim(P2)} ${import_picocolors.default.dim(n)}`} ${import_picocolors.default.dim("/")} ${this.value ? `${import_picocolors.default.dim(P2)} ${import_picocolors.default.dim(r2)}` : `${import_picocolors.default.green(k2)} ${r2}`}
|
|
979
|
+
${import_picocolors.default.cyan(d2)}
|
|
993
980
|
`;
|
|
994
981
|
}
|
|
995
982
|
} }).prompt();
|
|
@@ -999,29 +986,29 @@ var ve = (t) => {
|
|
|
999
986
|
const s = r2.label ?? String(r2.value);
|
|
1000
987
|
switch (i) {
|
|
1001
988
|
case "selected":
|
|
1002
|
-
return `${
|
|
989
|
+
return `${import_picocolors.default.dim(s)}`;
|
|
1003
990
|
case "active":
|
|
1004
|
-
return `${
|
|
991
|
+
return `${import_picocolors.default.green(k2)} ${s} ${r2.hint ? import_picocolors.default.dim(`(${r2.hint})`) : ""}`;
|
|
1005
992
|
case "cancelled":
|
|
1006
|
-
return `${
|
|
993
|
+
return `${import_picocolors.default.strikethrough(import_picocolors.default.dim(s))}`;
|
|
1007
994
|
default:
|
|
1008
|
-
return `${
|
|
995
|
+
return `${import_picocolors.default.dim(P2)} ${import_picocolors.default.dim(s)}`;
|
|
1009
996
|
}
|
|
1010
997
|
};
|
|
1011
998
|
return new LD({ options: t.options, initialValue: t.initialValue, render() {
|
|
1012
|
-
const r2 = `${
|
|
999
|
+
const r2 = `${import_picocolors.default.gray(o)}
|
|
1013
1000
|
${b2(this.state)} ${t.message}
|
|
1014
1001
|
`;
|
|
1015
1002
|
switch (this.state) {
|
|
1016
1003
|
case "submit":
|
|
1017
|
-
return `${r2}${
|
|
1004
|
+
return `${r2}${import_picocolors.default.gray(o)} ${n(this.options[this.cursor], "selected")}`;
|
|
1018
1005
|
case "cancel":
|
|
1019
|
-
return `${r2}${
|
|
1020
|
-
${
|
|
1006
|
+
return `${r2}${import_picocolors.default.gray(o)} ${n(this.options[this.cursor], "cancelled")}
|
|
1007
|
+
${import_picocolors.default.gray(o)}`;
|
|
1021
1008
|
default:
|
|
1022
|
-
return `${r2}${
|
|
1023
|
-
${
|
|
1024
|
-
${
|
|
1009
|
+
return `${r2}${import_picocolors.default.cyan(o)} ${G2({ cursor: this.cursor, options: this.options, maxItems: t.maxItems, style: (i, s) => n(i, s ? "active" : "inactive") }).join(`
|
|
1010
|
+
${import_picocolors.default.cyan(o)} `)}
|
|
1011
|
+
${import_picocolors.default.cyan(d2)}
|
|
1025
1012
|
`;
|
|
1026
1013
|
}
|
|
1027
1014
|
} }).prompt();
|
|
@@ -1029,13 +1016,13 @@ ${import_picocolors2.default.cyan(d2)}
|
|
|
1029
1016
|
var fe = (t) => {
|
|
1030
1017
|
const n = (r2, i) => {
|
|
1031
1018
|
const s = r2.label ?? String(r2.value);
|
|
1032
|
-
return i === "active" ? `${
|
|
1019
|
+
return i === "active" ? `${import_picocolors.default.cyan(A2)} ${s} ${r2.hint ? import_picocolors.default.dim(`(${r2.hint})`) : ""}` : i === "selected" ? `${import_picocolors.default.green(T2)} ${import_picocolors.default.dim(s)} ${r2.hint ? import_picocolors.default.dim(`(${r2.hint})`) : ""}` : i === "cancelled" ? `${import_picocolors.default.strikethrough(import_picocolors.default.dim(s))}` : i === "active-selected" ? `${import_picocolors.default.green(T2)} ${s} ${r2.hint ? import_picocolors.default.dim(`(${r2.hint})`) : ""}` : i === "submitted" ? `${import_picocolors.default.dim(s)}` : `${import_picocolors.default.dim(F)} ${import_picocolors.default.dim(s)}`;
|
|
1033
1020
|
};
|
|
1034
1021
|
return new SD({ options: t.options, initialValues: t.initialValues, required: t.required ?? true, cursorAt: t.cursorAt, validate(r2) {
|
|
1035
1022
|
if (this.required && r2.length === 0) return `Please select at least one option.
|
|
1036
|
-
${
|
|
1023
|
+
${import_picocolors.default.reset(import_picocolors.default.dim(`Press ${import_picocolors.default.gray(import_picocolors.default.bgWhite(import_picocolors.default.inverse(" space ")))} to select, ${import_picocolors.default.gray(import_picocolors.default.bgWhite(import_picocolors.default.inverse(" enter ")))} to submit`))}`;
|
|
1037
1024
|
}, render() {
|
|
1038
|
-
const r2 = `${
|
|
1025
|
+
const r2 = `${import_picocolors.default.gray(o)}
|
|
1039
1026
|
${b2(this.state)} ${t.message}
|
|
1040
1027
|
`, i = (s, c) => {
|
|
1041
1028
|
const a = this.value.includes(s.value);
|
|
@@ -1043,25 +1030,25 @@ ${b2(this.state)} ${t.message}
|
|
|
1043
1030
|
};
|
|
1044
1031
|
switch (this.state) {
|
|
1045
1032
|
case "submit":
|
|
1046
|
-
return `${r2}${
|
|
1033
|
+
return `${r2}${import_picocolors.default.gray(o)} ${this.options.filter(({ value: s }) => this.value.includes(s)).map((s) => n(s, "submitted")).join(import_picocolors.default.dim(", ")) || import_picocolors.default.dim("none")}`;
|
|
1047
1034
|
case "cancel": {
|
|
1048
|
-
const s = this.options.filter(({ value: c }) => this.value.includes(c)).map((c) => n(c, "cancelled")).join(
|
|
1049
|
-
return `${r2}${
|
|
1050
|
-
${
|
|
1035
|
+
const s = this.options.filter(({ value: c }) => this.value.includes(c)).map((c) => n(c, "cancelled")).join(import_picocolors.default.dim(", "));
|
|
1036
|
+
return `${r2}${import_picocolors.default.gray(o)} ${s.trim() ? `${s}
|
|
1037
|
+
${import_picocolors.default.gray(o)}` : ""}`;
|
|
1051
1038
|
}
|
|
1052
1039
|
case "error": {
|
|
1053
1040
|
const s = this.error.split(`
|
|
1054
|
-
`).map((c, a) => a === 0 ? `${
|
|
1041
|
+
`).map((c, a) => a === 0 ? `${import_picocolors.default.yellow(d2)} ${import_picocolors.default.yellow(c)}` : ` ${c}`).join(`
|
|
1055
1042
|
`);
|
|
1056
|
-
return `${r2 +
|
|
1057
|
-
${
|
|
1043
|
+
return `${r2 + import_picocolors.default.yellow(o)} ${G2({ options: this.options, cursor: this.cursor, maxItems: t.maxItems, style: i }).join(`
|
|
1044
|
+
${import_picocolors.default.yellow(o)} `)}
|
|
1058
1045
|
${s}
|
|
1059
1046
|
`;
|
|
1060
1047
|
}
|
|
1061
1048
|
default:
|
|
1062
|
-
return `${r2}${
|
|
1063
|
-
${
|
|
1064
|
-
${
|
|
1049
|
+
return `${r2}${import_picocolors.default.cyan(o)} ${G2({ options: this.options, cursor: this.cursor, maxItems: t.maxItems, style: i }).join(`
|
|
1050
|
+
${import_picocolors.default.cyan(o)} `)}
|
|
1051
|
+
${import_picocolors.default.cyan(d2)}
|
|
1065
1052
|
`;
|
|
1066
1053
|
}
|
|
1067
1054
|
} }).prompt();
|
|
@@ -1069,53 +1056,53 @@ ${import_picocolors2.default.cyan(d2)}
|
|
|
1069
1056
|
var be = (t) => {
|
|
1070
1057
|
const { selectableGroups: n = true } = t, r2 = (i, s, c = []) => {
|
|
1071
1058
|
const a = i.label ?? String(i.value), l2 = typeof i.group == "string", $2 = l2 && (c[c.indexOf(i) + 1] ?? { group: true }), g2 = l2 && $2.group === true, p2 = l2 ? n ? `${g2 ? d2 : o} ` : " " : "";
|
|
1072
|
-
if (s === "active") return `${
|
|
1073
|
-
if (s === "group-active") return `${p2}${
|
|
1074
|
-
if (s === "group-active-selected") return `${p2}${
|
|
1059
|
+
if (s === "active") return `${import_picocolors.default.dim(p2)}${import_picocolors.default.cyan(A2)} ${a} ${i.hint ? import_picocolors.default.dim(`(${i.hint})`) : ""}`;
|
|
1060
|
+
if (s === "group-active") return `${p2}${import_picocolors.default.cyan(A2)} ${import_picocolors.default.dim(a)}`;
|
|
1061
|
+
if (s === "group-active-selected") return `${p2}${import_picocolors.default.green(T2)} ${import_picocolors.default.dim(a)}`;
|
|
1075
1062
|
if (s === "selected") {
|
|
1076
|
-
const f = l2 || n ?
|
|
1077
|
-
return `${
|
|
1078
|
-
}
|
|
1079
|
-
if (s === "cancelled") return `${
|
|
1080
|
-
if (s === "active-selected") return `${
|
|
1081
|
-
if (s === "submitted") return `${
|
|
1082
|
-
const
|
|
1083
|
-
return `${
|
|
1063
|
+
const f = l2 || n ? import_picocolors.default.green(T2) : "";
|
|
1064
|
+
return `${import_picocolors.default.dim(p2)}${f} ${import_picocolors.default.dim(a)} ${i.hint ? import_picocolors.default.dim(`(${i.hint})`) : ""}`;
|
|
1065
|
+
}
|
|
1066
|
+
if (s === "cancelled") return `${import_picocolors.default.strikethrough(import_picocolors.default.dim(a))}`;
|
|
1067
|
+
if (s === "active-selected") return `${import_picocolors.default.dim(p2)}${import_picocolors.default.green(T2)} ${a} ${i.hint ? import_picocolors.default.dim(`(${i.hint})`) : ""}`;
|
|
1068
|
+
if (s === "submitted") return `${import_picocolors.default.dim(a)}`;
|
|
1069
|
+
const v = l2 || n ? import_picocolors.default.dim(F) : "";
|
|
1070
|
+
return `${import_picocolors.default.dim(p2)}${v} ${import_picocolors.default.dim(a)}`;
|
|
1084
1071
|
};
|
|
1085
1072
|
return new _D({ options: t.options, initialValues: t.initialValues, required: t.required ?? true, cursorAt: t.cursorAt, selectableGroups: n, validate(i) {
|
|
1086
1073
|
if (this.required && i.length === 0) return `Please select at least one option.
|
|
1087
|
-
${
|
|
1074
|
+
${import_picocolors.default.reset(import_picocolors.default.dim(`Press ${import_picocolors.default.gray(import_picocolors.default.bgWhite(import_picocolors.default.inverse(" space ")))} to select, ${import_picocolors.default.gray(import_picocolors.default.bgWhite(import_picocolors.default.inverse(" enter ")))} to submit`))}`;
|
|
1088
1075
|
}, render() {
|
|
1089
|
-
const i = `${
|
|
1076
|
+
const i = `${import_picocolors.default.gray(o)}
|
|
1090
1077
|
${b2(this.state)} ${t.message}
|
|
1091
1078
|
`;
|
|
1092
1079
|
switch (this.state) {
|
|
1093
1080
|
case "submit":
|
|
1094
|
-
return `${i}${
|
|
1081
|
+
return `${i}${import_picocolors.default.gray(o)} ${this.options.filter(({ value: s }) => this.value.includes(s)).map((s) => r2(s, "submitted")).join(import_picocolors.default.dim(", "))}`;
|
|
1095
1082
|
case "cancel": {
|
|
1096
|
-
const s = this.options.filter(({ value: c }) => this.value.includes(c)).map((c) => r2(c, "cancelled")).join(
|
|
1097
|
-
return `${i}${
|
|
1098
|
-
${
|
|
1083
|
+
const s = this.options.filter(({ value: c }) => this.value.includes(c)).map((c) => r2(c, "cancelled")).join(import_picocolors.default.dim(", "));
|
|
1084
|
+
return `${i}${import_picocolors.default.gray(o)} ${s.trim() ? `${s}
|
|
1085
|
+
${import_picocolors.default.gray(o)}` : ""}`;
|
|
1099
1086
|
}
|
|
1100
1087
|
case "error": {
|
|
1101
1088
|
const s = this.error.split(`
|
|
1102
|
-
`).map((c, a) => a === 0 ? `${
|
|
1089
|
+
`).map((c, a) => a === 0 ? `${import_picocolors.default.yellow(d2)} ${import_picocolors.default.yellow(c)}` : ` ${c}`).join(`
|
|
1103
1090
|
`);
|
|
1104
|
-
return `${i}${
|
|
1091
|
+
return `${i}${import_picocolors.default.yellow(o)} ${this.options.map((c, a, l2) => {
|
|
1105
1092
|
const $2 = this.value.includes(c.value) || c.group === true && this.isGroupSelected(`${c.value}`), g2 = a === this.cursor;
|
|
1106
1093
|
return !g2 && typeof c.group == "string" && this.options[this.cursor].value === c.group ? r2(c, $2 ? "group-active-selected" : "group-active", l2) : g2 && $2 ? r2(c, "active-selected", l2) : $2 ? r2(c, "selected", l2) : r2(c, g2 ? "active" : "inactive", l2);
|
|
1107
1094
|
}).join(`
|
|
1108
|
-
${
|
|
1095
|
+
${import_picocolors.default.yellow(o)} `)}
|
|
1109
1096
|
${s}
|
|
1110
1097
|
`;
|
|
1111
1098
|
}
|
|
1112
1099
|
default:
|
|
1113
|
-
return `${i}${
|
|
1100
|
+
return `${i}${import_picocolors.default.cyan(o)} ${this.options.map((s, c, a) => {
|
|
1114
1101
|
const l2 = this.value.includes(s.value) || s.group === true && this.isGroupSelected(`${s.value}`), $2 = c === this.cursor;
|
|
1115
1102
|
return !$2 && typeof s.group == "string" && this.options[this.cursor].value === s.group ? r2(s, l2 ? "group-active-selected" : "group-active", a) : $2 && l2 ? r2(s, "active-selected", a) : l2 ? r2(s, "selected", a) : r2(s, $2 ? "active" : "inactive", a);
|
|
1116
1103
|
}).join(`
|
|
1117
|
-
${
|
|
1118
|
-
${
|
|
1104
|
+
${import_picocolors.default.cyan(o)} `)}
|
|
1105
|
+
${import_picocolors.default.cyan(d2)}
|
|
1119
1106
|
`;
|
|
1120
1107
|
}
|
|
1121
1108
|
} }).prompt();
|
|
@@ -1127,63 +1114,63 @@ ${t}
|
|
|
1127
1114
|
`), i = S2(n).length, s = Math.max(r2.reduce((a, l2) => {
|
|
1128
1115
|
const $2 = S2(l2);
|
|
1129
1116
|
return $2.length > a ? $2.length : a;
|
|
1130
|
-
}, 0), i) + 2, c = r2.map((a) => `${
|
|
1117
|
+
}, 0), i) + 2, c = r2.map((a) => `${import_picocolors.default.gray(o)} ${import_picocolors.default.dim(a)}${" ".repeat(s - S2(a).length)}${import_picocolors.default.gray(o)}`).join(`
|
|
1131
1118
|
`);
|
|
1132
|
-
process.stdout.write(`${
|
|
1133
|
-
${
|
|
1119
|
+
process.stdout.write(`${import_picocolors.default.gray(o)}
|
|
1120
|
+
${import_picocolors.default.green(C)} ${import_picocolors.default.reset(n)} ${import_picocolors.default.gray(_2.repeat(Math.max(s - i - 1, 1)) + me)}
|
|
1134
1121
|
${c}
|
|
1135
|
-
${
|
|
1122
|
+
${import_picocolors.default.gray(de + _2.repeat(s + 2) + pe)}
|
|
1136
1123
|
`);
|
|
1137
1124
|
};
|
|
1138
1125
|
var xe = (t = "") => {
|
|
1139
|
-
process.stdout.write(`${
|
|
1126
|
+
process.stdout.write(`${import_picocolors.default.gray(d2)} ${import_picocolors.default.red(t)}
|
|
1140
1127
|
|
|
1141
1128
|
`);
|
|
1142
1129
|
};
|
|
1143
1130
|
var Ie = (t = "") => {
|
|
1144
|
-
process.stdout.write(`${
|
|
1131
|
+
process.stdout.write(`${import_picocolors.default.gray(ue)} ${t}
|
|
1145
1132
|
`);
|
|
1146
1133
|
};
|
|
1147
1134
|
var Se = (t = "") => {
|
|
1148
|
-
process.stdout.write(`${
|
|
1149
|
-
${
|
|
1135
|
+
process.stdout.write(`${import_picocolors.default.gray(o)}
|
|
1136
|
+
${import_picocolors.default.gray(d2)} ${t}
|
|
1150
1137
|
|
|
1151
1138
|
`);
|
|
1152
1139
|
};
|
|
1153
|
-
var M2 = { message: (t = "", { symbol: n =
|
|
1154
|
-
const r2 = [`${
|
|
1140
|
+
var M2 = { message: (t = "", { symbol: n = import_picocolors.default.gray(o) } = {}) => {
|
|
1141
|
+
const r2 = [`${import_picocolors.default.gray(o)}`];
|
|
1155
1142
|
if (t) {
|
|
1156
1143
|
const [i, ...s] = t.split(`
|
|
1157
1144
|
`);
|
|
1158
|
-
r2.push(`${n} ${i}`, ...s.map((c) => `${
|
|
1145
|
+
r2.push(`${n} ${i}`, ...s.map((c) => `${import_picocolors.default.gray(o)} ${c}`));
|
|
1159
1146
|
}
|
|
1160
1147
|
process.stdout.write(`${r2.join(`
|
|
1161
1148
|
`)}
|
|
1162
1149
|
`);
|
|
1163
1150
|
}, info: (t) => {
|
|
1164
|
-
M2.message(t, { symbol:
|
|
1151
|
+
M2.message(t, { symbol: import_picocolors.default.blue(q2) });
|
|
1165
1152
|
}, success: (t) => {
|
|
1166
|
-
M2.message(t, { symbol:
|
|
1153
|
+
M2.message(t, { symbol: import_picocolors.default.green(D) });
|
|
1167
1154
|
}, step: (t) => {
|
|
1168
|
-
M2.message(t, { symbol:
|
|
1155
|
+
M2.message(t, { symbol: import_picocolors.default.green(C) });
|
|
1169
1156
|
}, warn: (t) => {
|
|
1170
|
-
M2.message(t, { symbol:
|
|
1157
|
+
M2.message(t, { symbol: import_picocolors.default.yellow(U) });
|
|
1171
1158
|
}, warning: (t) => {
|
|
1172
1159
|
M2.warn(t);
|
|
1173
1160
|
}, error: (t) => {
|
|
1174
|
-
M2.message(t, { symbol:
|
|
1161
|
+
M2.message(t, { symbol: import_picocolors.default.red(K2) });
|
|
1175
1162
|
} };
|
|
1176
|
-
var J2 = `${
|
|
1163
|
+
var J2 = `${import_picocolors.default.gray(o)} `;
|
|
1177
1164
|
var Y2 = ({ indicator: t = "dots" } = {}) => {
|
|
1178
1165
|
const n = V2 ? ["\u25D2", "\u25D0", "\u25D3", "\u25D1"] : ["\u2022", "o", "O", "0"], r2 = V2 ? 80 : 120, i = process.env.CI === "true";
|
|
1179
1166
|
let s, c, a = false, l2 = "", $2, g2 = performance.now();
|
|
1180
1167
|
const p2 = (m2) => {
|
|
1181
1168
|
const h2 = m2 > 1 ? "Something went wrong" : "Canceled";
|
|
1182
1169
|
a && N2(h2, m2);
|
|
1183
|
-
},
|
|
1184
|
-
process.on("uncaughtExceptionMonitor",
|
|
1170
|
+
}, v = () => p2(2), f = () => p2(1), j2 = () => {
|
|
1171
|
+
process.on("uncaughtExceptionMonitor", v), process.on("unhandledRejection", v), process.on("SIGINT", f), process.on("SIGTERM", f), process.on("exit", p2);
|
|
1185
1172
|
}, E = () => {
|
|
1186
|
-
process.removeListener("uncaughtExceptionMonitor",
|
|
1173
|
+
process.removeListener("uncaughtExceptionMonitor", v), process.removeListener("unhandledRejection", v), process.removeListener("SIGINT", f), process.removeListener("SIGTERM", f), process.removeListener("exit", p2);
|
|
1187
1174
|
}, B2 = () => {
|
|
1188
1175
|
if ($2 === void 0) return;
|
|
1189
1176
|
i && process.stdout.write(`
|
|
@@ -1195,13 +1182,13 @@ var Y2 = ({ indicator: t = "dots" } = {}) => {
|
|
|
1195
1182
|
const h2 = (performance.now() - m2) / 1e3, w2 = Math.floor(h2 / 60), I2 = Math.floor(h2 % 60);
|
|
1196
1183
|
return w2 > 0 ? `[${w2}m ${I2}s]` : `[${I2}s]`;
|
|
1197
1184
|
}, H2 = (m2 = "") => {
|
|
1198
|
-
a = true, s = fD(), l2 = R2(m2), g2 = performance.now(), process.stdout.write(`${
|
|
1185
|
+
a = true, s = fD(), l2 = R2(m2), g2 = performance.now(), process.stdout.write(`${import_picocolors.default.gray(o)}
|
|
1199
1186
|
`);
|
|
1200
1187
|
let h2 = 0, w2 = 0;
|
|
1201
1188
|
j2(), c = setInterval(() => {
|
|
1202
1189
|
if (i && l2 === $2) return;
|
|
1203
1190
|
B2(), $2 = l2;
|
|
1204
|
-
const I2 =
|
|
1191
|
+
const I2 = import_picocolors.default.magenta(n[h2]);
|
|
1205
1192
|
if (i) process.stdout.write(`${I2} ${l2}...`);
|
|
1206
1193
|
else if (t === "timer") process.stdout.write(`${I2} ${l2} ${O2(g2)}`);
|
|
1207
1194
|
else {
|
|
@@ -1212,7 +1199,7 @@ var Y2 = ({ indicator: t = "dots" } = {}) => {
|
|
|
1212
1199
|
}, r2);
|
|
1213
1200
|
}, N2 = (m2 = "", h2 = 0) => {
|
|
1214
1201
|
a = false, clearInterval(c), B2();
|
|
1215
|
-
const w2 = h2 === 0 ?
|
|
1202
|
+
const w2 = h2 === 0 ? import_picocolors.default.green(C) : h2 === 1 ? import_picocolors.default.red(L2) : import_picocolors.default.red(W2);
|
|
1216
1203
|
l2 = R2(m2 ?? l2), t === "timer" ? process.stdout.write(`${w2} ${l2} ${O2(g2)}
|
|
1217
1204
|
`) : process.stdout.write(`${w2} ${l2}
|
|
1218
1205
|
`), E(), s();
|
|
@@ -1223,10 +1210,10 @@ var Y2 = ({ indicator: t = "dots" } = {}) => {
|
|
|
1223
1210
|
};
|
|
1224
1211
|
|
|
1225
1212
|
// src/add.ts
|
|
1226
|
-
var
|
|
1213
|
+
var import_picocolors3 = __toESM(require_picocolors(), 1);
|
|
1227
1214
|
import { existsSync as existsSync2 } from "fs";
|
|
1228
1215
|
import { homedir as homedir4 } from "os";
|
|
1229
|
-
import { sep as
|
|
1216
|
+
import { sep as sep5 } from "path";
|
|
1230
1217
|
|
|
1231
1218
|
// src/source-parser.ts
|
|
1232
1219
|
import { isAbsolute, resolve } from "path";
|
|
@@ -1234,6 +1221,15 @@ function getOwnerRepo(parsed) {
|
|
|
1234
1221
|
if (parsed.type === "local") {
|
|
1235
1222
|
return null;
|
|
1236
1223
|
}
|
|
1224
|
+
const sshMatch = parsed.url.match(/^git@[^:]+:(.+)$/);
|
|
1225
|
+
if (sshMatch) {
|
|
1226
|
+
let path2 = sshMatch[1];
|
|
1227
|
+
path2 = path2.replace(/\.git$/, "");
|
|
1228
|
+
if (path2.includes("/")) {
|
|
1229
|
+
return path2;
|
|
1230
|
+
}
|
|
1231
|
+
return null;
|
|
1232
|
+
}
|
|
1237
1233
|
if (!parsed.url.startsWith("http://") && !parsed.url.startsWith("https://")) {
|
|
1238
1234
|
return null;
|
|
1239
1235
|
}
|
|
@@ -1267,27 +1263,22 @@ async function isRepoPrivate(owner, repo) {
|
|
|
1267
1263
|
return null;
|
|
1268
1264
|
}
|
|
1269
1265
|
}
|
|
1266
|
+
function sanitizeSubpath(subpath) {
|
|
1267
|
+
const normalized = subpath.replace(/\\/g, "/");
|
|
1268
|
+
const segments = normalized.split("/");
|
|
1269
|
+
for (const segment of segments) {
|
|
1270
|
+
if (segment === "..") {
|
|
1271
|
+
throw new Error(
|
|
1272
|
+
`Unsafe subpath: "${subpath}" contains path traversal segments. Subpaths must not contain ".." components.`
|
|
1273
|
+
);
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1276
|
+
return subpath;
|
|
1277
|
+
}
|
|
1270
1278
|
function isLocalPath(input) {
|
|
1271
1279
|
return isAbsolute(input) || input.startsWith("./") || input.startsWith("../") || input === "." || input === ".." || // Windows absolute paths like C:\ or D:\
|
|
1272
1280
|
/^[a-zA-Z]:[/\\]/.test(input);
|
|
1273
1281
|
}
|
|
1274
|
-
function isDirectSkillUrl(input) {
|
|
1275
|
-
if (!input.startsWith("http://") && !input.startsWith("https://")) {
|
|
1276
|
-
return false;
|
|
1277
|
-
}
|
|
1278
|
-
if (!input.toLowerCase().endsWith("/skill.md")) {
|
|
1279
|
-
return false;
|
|
1280
|
-
}
|
|
1281
|
-
if (input.includes("github.com/") && !input.includes("raw.githubusercontent.com")) {
|
|
1282
|
-
if (!input.includes("/blob/") && !input.includes("/raw/")) {
|
|
1283
|
-
return false;
|
|
1284
|
-
}
|
|
1285
|
-
}
|
|
1286
|
-
if (input.includes("gitlab.com/") && !input.includes("/-/raw/")) {
|
|
1287
|
-
return false;
|
|
1288
|
-
}
|
|
1289
|
-
return true;
|
|
1290
|
-
}
|
|
1291
1282
|
var SOURCE_ALIASES = {
|
|
1292
1283
|
"coinbase/agentWallet": "coinbase/agentic-wallet-skills"
|
|
1293
1284
|
};
|
|
@@ -1296,6 +1287,14 @@ function parseSource(input) {
|
|
|
1296
1287
|
if (alias) {
|
|
1297
1288
|
input = alias;
|
|
1298
1289
|
}
|
|
1290
|
+
const githubPrefixMatch = input.match(/^github:(.+)$/);
|
|
1291
|
+
if (githubPrefixMatch) {
|
|
1292
|
+
return parseSource(githubPrefixMatch[1]);
|
|
1293
|
+
}
|
|
1294
|
+
const gitlabPrefixMatch = input.match(/^gitlab:(.+)$/);
|
|
1295
|
+
if (gitlabPrefixMatch) {
|
|
1296
|
+
return parseSource(`https://gitlab.com/${gitlabPrefixMatch[1]}`);
|
|
1297
|
+
}
|
|
1299
1298
|
if (isLocalPath(input)) {
|
|
1300
1299
|
const resolvedPath = resolve(input);
|
|
1301
1300
|
return {
|
|
@@ -1305,12 +1304,6 @@ function parseSource(input) {
|
|
|
1305
1304
|
localPath: resolvedPath
|
|
1306
1305
|
};
|
|
1307
1306
|
}
|
|
1308
|
-
if (isDirectSkillUrl(input)) {
|
|
1309
|
-
return {
|
|
1310
|
-
type: "direct-url",
|
|
1311
|
-
url: input
|
|
1312
|
-
};
|
|
1313
|
-
}
|
|
1314
1307
|
const githubTreeWithPathMatch = input.match(/github\.com\/([^/]+)\/([^/]+)\/tree\/([^/]+)\/(.+)/);
|
|
1315
1308
|
if (githubTreeWithPathMatch) {
|
|
1316
1309
|
const [, owner, repo, ref, subpath] = githubTreeWithPathMatch;
|
|
@@ -1318,7 +1311,7 @@ function parseSource(input) {
|
|
|
1318
1311
|
type: "github",
|
|
1319
1312
|
url: `https://github.com/${owner}/${repo}.git`,
|
|
1320
1313
|
ref,
|
|
1321
|
-
subpath
|
|
1314
|
+
subpath: subpath ? sanitizeSubpath(subpath) : subpath
|
|
1322
1315
|
};
|
|
1323
1316
|
}
|
|
1324
1317
|
const githubTreeMatch = input.match(/github\.com\/([^/]+)\/([^/]+)\/tree\/([^/]+)$/);
|
|
@@ -1349,7 +1342,7 @@ function parseSource(input) {
|
|
|
1349
1342
|
type: "gitlab",
|
|
1350
1343
|
url: `${protocol}://${hostname}/${repoPath.replace(/\.git$/, "")}.git`,
|
|
1351
1344
|
ref,
|
|
1352
|
-
subpath
|
|
1345
|
+
subpath: subpath ? sanitizeSubpath(subpath) : subpath
|
|
1353
1346
|
};
|
|
1354
1347
|
}
|
|
1355
1348
|
}
|
|
@@ -1389,7 +1382,7 @@ function parseSource(input) {
|
|
|
1389
1382
|
return {
|
|
1390
1383
|
type: "github",
|
|
1391
1384
|
url: `https://github.com/${owner}/${repo}.git`,
|
|
1392
|
-
subpath
|
|
1385
|
+
subpath: subpath ? sanitizeSubpath(subpath) : subpath
|
|
1393
1386
|
};
|
|
1394
1387
|
}
|
|
1395
1388
|
if (isWellKnownUrl(input)) {
|
|
@@ -1409,18 +1402,10 @@ function isWellKnownUrl(input) {
|
|
|
1409
1402
|
}
|
|
1410
1403
|
try {
|
|
1411
1404
|
const parsed = new URL(input);
|
|
1412
|
-
const excludedHosts = [
|
|
1413
|
-
"github.com",
|
|
1414
|
-
"gitlab.com",
|
|
1415
|
-
"huggingface.co",
|
|
1416
|
-
"raw.githubusercontent.com"
|
|
1417
|
-
];
|
|
1405
|
+
const excludedHosts = ["github.com", "gitlab.com", "raw.githubusercontent.com"];
|
|
1418
1406
|
if (excludedHosts.includes(parsed.hostname)) {
|
|
1419
1407
|
return false;
|
|
1420
1408
|
}
|
|
1421
|
-
if (input.toLowerCase().endsWith("/skill.md")) {
|
|
1422
|
-
return false;
|
|
1423
|
-
}
|
|
1424
1409
|
if (input.endsWith(".git")) {
|
|
1425
1410
|
return false;
|
|
1426
1411
|
}
|
|
@@ -1431,7 +1416,7 @@ function isWellKnownUrl(input) {
|
|
|
1431
1416
|
}
|
|
1432
1417
|
|
|
1433
1418
|
// src/prompts/search-multiselect.ts
|
|
1434
|
-
var
|
|
1419
|
+
var import_picocolors2 = __toESM(require_picocolors(), 1);
|
|
1435
1420
|
import * as readline from "readline";
|
|
1436
1421
|
import { Writable } from "stream";
|
|
1437
1422
|
var silentOutput = new Writable({
|
|
@@ -1439,15 +1424,15 @@ var silentOutput = new Writable({
|
|
|
1439
1424
|
callback();
|
|
1440
1425
|
}
|
|
1441
1426
|
});
|
|
1442
|
-
var S_STEP_ACTIVE =
|
|
1443
|
-
var S_STEP_CANCEL =
|
|
1444
|
-
var S_STEP_SUBMIT =
|
|
1445
|
-
var S_RADIO_ACTIVE =
|
|
1446
|
-
var S_RADIO_INACTIVE =
|
|
1447
|
-
var S_CHECKBOX_LOCKED =
|
|
1448
|
-
var S_BULLET =
|
|
1449
|
-
var S_BAR =
|
|
1450
|
-
var S_BAR_H =
|
|
1427
|
+
var S_STEP_ACTIVE = import_picocolors2.default.green("\u25C6");
|
|
1428
|
+
var S_STEP_CANCEL = import_picocolors2.default.red("\u25A0");
|
|
1429
|
+
var S_STEP_SUBMIT = import_picocolors2.default.green("\u25C7");
|
|
1430
|
+
var S_RADIO_ACTIVE = import_picocolors2.default.green("\u25CF");
|
|
1431
|
+
var S_RADIO_INACTIVE = import_picocolors2.default.dim("\u25CB");
|
|
1432
|
+
var S_CHECKBOX_LOCKED = import_picocolors2.default.green("\u2713");
|
|
1433
|
+
var S_BULLET = import_picocolors2.default.green("\u2022");
|
|
1434
|
+
var S_BAR = import_picocolors2.default.dim("\u2502");
|
|
1435
|
+
var S_BAR_H = import_picocolors2.default.dim("\u2500");
|
|
1451
1436
|
var cancelSymbol = /* @__PURE__ */ Symbol("cancel");
|
|
1452
1437
|
async function searchMultiselect(options) {
|
|
1453
1438
|
const {
|
|
@@ -1495,23 +1480,23 @@ async function searchMultiselect(options) {
|
|
|
1495
1480
|
const lines = [];
|
|
1496
1481
|
const filtered = getFiltered();
|
|
1497
1482
|
const icon = state === "active" ? S_STEP_ACTIVE : state === "cancel" ? S_STEP_CANCEL : S_STEP_SUBMIT;
|
|
1498
|
-
lines.push(`${icon} ${
|
|
1483
|
+
lines.push(`${icon} ${import_picocolors2.default.bold(message)}`);
|
|
1499
1484
|
if (state === "active") {
|
|
1500
1485
|
if (lockedSection && lockedSection.items.length > 0) {
|
|
1501
1486
|
lines.push(`${S_BAR}`);
|
|
1502
|
-
const lockedTitle = `${
|
|
1487
|
+
const lockedTitle = `${import_picocolors2.default.bold(lockedSection.title)} ${import_picocolors2.default.dim("\u2500\u2500 always included")}`;
|
|
1503
1488
|
lines.push(`${S_BAR} ${S_BAR_H}${S_BAR_H} ${lockedTitle} ${S_BAR_H.repeat(12)}`);
|
|
1504
1489
|
for (const item of lockedSection.items) {
|
|
1505
|
-
lines.push(`${S_BAR} ${S_BULLET} ${
|
|
1490
|
+
lines.push(`${S_BAR} ${S_BULLET} ${import_picocolors2.default.bold(item.label)}`);
|
|
1506
1491
|
}
|
|
1507
1492
|
lines.push(`${S_BAR}`);
|
|
1508
1493
|
lines.push(
|
|
1509
|
-
`${S_BAR} ${S_BAR_H}${S_BAR_H} ${
|
|
1494
|
+
`${S_BAR} ${S_BAR_H}${S_BAR_H} ${import_picocolors2.default.bold("Additional agents")} ${S_BAR_H.repeat(29)}`
|
|
1510
1495
|
);
|
|
1511
1496
|
}
|
|
1512
|
-
const searchLine = `${S_BAR} ${
|
|
1497
|
+
const searchLine = `${S_BAR} ${import_picocolors2.default.dim("Search:")} ${query}${import_picocolors2.default.inverse(" ")}`;
|
|
1513
1498
|
lines.push(searchLine);
|
|
1514
|
-
lines.push(`${S_BAR} ${
|
|
1499
|
+
lines.push(`${S_BAR} ${import_picocolors2.default.dim("\u2191\u2193 move, space select, enter confirm")}`);
|
|
1515
1500
|
lines.push(`${S_BAR}`);
|
|
1516
1501
|
const visibleStart = Math.max(
|
|
1517
1502
|
0,
|
|
@@ -1520,7 +1505,7 @@ async function searchMultiselect(options) {
|
|
|
1520
1505
|
const visibleEnd = Math.min(filtered.length, visibleStart + maxVisible);
|
|
1521
1506
|
const visibleItems = filtered.slice(visibleStart, visibleEnd);
|
|
1522
1507
|
if (filtered.length === 0) {
|
|
1523
|
-
lines.push(`${S_BAR} ${
|
|
1508
|
+
lines.push(`${S_BAR} ${import_picocolors2.default.dim("No matches found")}`);
|
|
1524
1509
|
} else {
|
|
1525
1510
|
for (let i = 0; i < visibleItems.length; i++) {
|
|
1526
1511
|
const item = visibleItems[i];
|
|
@@ -1528,9 +1513,9 @@ async function searchMultiselect(options) {
|
|
|
1528
1513
|
const isSelected = selected.has(item.value);
|
|
1529
1514
|
const isCursor = actualIndex === cursor;
|
|
1530
1515
|
const radio = isSelected ? S_RADIO_ACTIVE : S_RADIO_INACTIVE;
|
|
1531
|
-
const label = isCursor ?
|
|
1532
|
-
const hint = item.hint ?
|
|
1533
|
-
const prefix = isCursor ?
|
|
1516
|
+
const label = isCursor ? import_picocolors2.default.underline(item.label) : item.label;
|
|
1517
|
+
const hint = item.hint ? import_picocolors2.default.dim(` (${item.hint})`) : "";
|
|
1518
|
+
const prefix = isCursor ? import_picocolors2.default.cyan("\u276F") : " ";
|
|
1534
1519
|
lines.push(`${S_BAR} ${prefix} ${radio} ${label}${hint}`);
|
|
1535
1520
|
}
|
|
1536
1521
|
const hiddenBefore = visibleStart;
|
|
@@ -1539,7 +1524,7 @@ async function searchMultiselect(options) {
|
|
|
1539
1524
|
const parts = [];
|
|
1540
1525
|
if (hiddenBefore > 0) parts.push(`\u2191 ${hiddenBefore} more`);
|
|
1541
1526
|
if (hiddenAfter > 0) parts.push(`\u2193 ${hiddenAfter} more`);
|
|
1542
|
-
lines.push(`${S_BAR} ${
|
|
1527
|
+
lines.push(`${S_BAR} ${import_picocolors2.default.dim(parts.join(" "))}`);
|
|
1543
1528
|
}
|
|
1544
1529
|
}
|
|
1545
1530
|
lines.push(`${S_BAR}`);
|
|
@@ -1548,20 +1533,20 @@ async function searchMultiselect(options) {
|
|
|
1548
1533
|
...items.filter((item) => selected.has(item.value)).map((item) => item.label)
|
|
1549
1534
|
];
|
|
1550
1535
|
if (allSelectedLabels.length === 0) {
|
|
1551
|
-
lines.push(`${S_BAR} ${
|
|
1536
|
+
lines.push(`${S_BAR} ${import_picocolors2.default.dim("Selected: (none)")}`);
|
|
1552
1537
|
} else {
|
|
1553
1538
|
const summary = allSelectedLabels.length <= 3 ? allSelectedLabels.join(", ") : `${allSelectedLabels.slice(0, 3).join(", ")} +${allSelectedLabels.length - 3} more`;
|
|
1554
|
-
lines.push(`${S_BAR} ${
|
|
1539
|
+
lines.push(`${S_BAR} ${import_picocolors2.default.green("Selected:")} ${summary}`);
|
|
1555
1540
|
}
|
|
1556
|
-
lines.push(`${
|
|
1541
|
+
lines.push(`${import_picocolors2.default.dim("\u2514")}`);
|
|
1557
1542
|
} else if (state === "submit") {
|
|
1558
1543
|
const allSelectedLabels = [
|
|
1559
1544
|
...lockedSection ? lockedSection.items.map((i) => i.label) : [],
|
|
1560
1545
|
...items.filter((item) => selected.has(item.value)).map((item) => item.label)
|
|
1561
1546
|
];
|
|
1562
|
-
lines.push(`${S_BAR} ${
|
|
1547
|
+
lines.push(`${S_BAR} ${import_picocolors2.default.dim(allSelectedLabels.join(", "))}`);
|
|
1563
1548
|
} else if (state === "cancel") {
|
|
1564
|
-
lines.push(`${S_BAR} ${
|
|
1549
|
+
lines.push(`${S_BAR} ${import_picocolors2.default.strikethrough(import_picocolors2.default.dim("Cancelled"))}`);
|
|
1565
1550
|
}
|
|
1566
1551
|
process.stdout.write(lines.join("\n") + "\n");
|
|
1567
1552
|
lastRenderHeight = lines.length;
|
|
@@ -1707,7 +1692,7 @@ async function cleanupTempDir(dir) {
|
|
|
1707
1692
|
|
|
1708
1693
|
// src/skills.ts
|
|
1709
1694
|
import { readdir as readdir2, readFile as readFile4, stat as stat2 } from "fs/promises";
|
|
1710
|
-
import { join as join5, basename, dirname as dirname3, resolve as resolve4 } from "path";
|
|
1695
|
+
import { join as join5, basename, dirname as dirname3, resolve as resolve4, normalize as normalize3, sep as sep3 } from "path";
|
|
1711
1696
|
import matter from "gray-matter";
|
|
1712
1697
|
|
|
1713
1698
|
// src/plugin-manifest.ts
|
|
@@ -1832,20 +1817,12 @@ async function parseSkillMd(skillMdPath, options) {
|
|
|
1832
1817
|
if (isInternal && !shouldInstallInternalSkills() && !options?.includeInternal) {
|
|
1833
1818
|
return null;
|
|
1834
1819
|
}
|
|
1835
|
-
const rawMcpDeps = data["requires-mcp-servers"];
|
|
1836
|
-
const rawAllowedTools = data["allowed-tools"];
|
|
1837
|
-
let allowedTools;
|
|
1838
|
-
if (typeof rawAllowedTools === "string") {
|
|
1839
|
-
allowedTools = rawAllowedTools.split(/\s+/).filter(Boolean);
|
|
1840
|
-
}
|
|
1841
1820
|
return {
|
|
1842
1821
|
name: data.name,
|
|
1843
1822
|
description: data.description,
|
|
1844
1823
|
path: dirname3(skillMdPath),
|
|
1845
1824
|
rawContent: content,
|
|
1846
|
-
metadata: data.metadata
|
|
1847
|
-
requiresMcpServers: Array.isArray(rawMcpDeps) ? rawMcpDeps : void 0,
|
|
1848
|
-
allowedTools
|
|
1825
|
+
metadata: data.metadata
|
|
1849
1826
|
};
|
|
1850
1827
|
} catch {
|
|
1851
1828
|
return null;
|
|
@@ -1867,9 +1844,19 @@ async function findSkillDirs(dir, depth = 0, maxDepth = 5) {
|
|
|
1867
1844
|
return [];
|
|
1868
1845
|
}
|
|
1869
1846
|
}
|
|
1847
|
+
function isSubpathSafe(basePath, subpath) {
|
|
1848
|
+
const normalizedBase = normalize3(resolve4(basePath));
|
|
1849
|
+
const normalizedTarget = normalize3(resolve4(join5(basePath, subpath)));
|
|
1850
|
+
return normalizedTarget.startsWith(normalizedBase + sep3) || normalizedTarget === normalizedBase;
|
|
1851
|
+
}
|
|
1870
1852
|
async function discoverSkills(basePath, subpath, options) {
|
|
1871
1853
|
const skills = [];
|
|
1872
1854
|
const seenNames = /* @__PURE__ */ new Set();
|
|
1855
|
+
if (subpath && !isSubpathSafe(basePath, subpath)) {
|
|
1856
|
+
throw new Error(
|
|
1857
|
+
`Invalid subpath: "${subpath}" resolves outside the repository directory. Subpath must not contain ".." segments that escape the base path.`
|
|
1858
|
+
);
|
|
1859
|
+
}
|
|
1873
1860
|
const searchPath = subpath ? join5(basePath, subpath) : basePath;
|
|
1874
1861
|
const pluginGroupings = await getPluginGroupings(searchPath);
|
|
1875
1862
|
const enhanceSkill = (skill) => {
|
|
@@ -1980,7 +1967,7 @@ import {
|
|
|
1980
1967
|
stat as stat3,
|
|
1981
1968
|
realpath
|
|
1982
1969
|
} from "fs/promises";
|
|
1983
|
-
import { join as join7, basename as basename2, normalize as
|
|
1970
|
+
import { join as join7, basename as basename2, normalize as normalize4, resolve as resolve5, sep as sep4, relative as relative2, dirname as dirname4 } from "path";
|
|
1984
1971
|
import { homedir as homedir3, platform } from "os";
|
|
1985
1972
|
|
|
1986
1973
|
// src/agents.ts
|
|
@@ -2073,8 +2060,8 @@ var agents = {
|
|
|
2073
2060
|
cline: {
|
|
2074
2061
|
name: "cline",
|
|
2075
2062
|
displayName: "Cline",
|
|
2076
|
-
skillsDir: ".
|
|
2077
|
-
globalSkillsDir: join6(home, ".
|
|
2063
|
+
skillsDir: ".agents/skills",
|
|
2064
|
+
globalSkillsDir: join6(home, ".agents", "skills"),
|
|
2078
2065
|
detectInstalled: async () => {
|
|
2079
2066
|
return existsSync(join6(home, ".cline"));
|
|
2080
2067
|
}
|
|
@@ -2167,10 +2154,6 @@ var agents = {
|
|
|
2167
2154
|
globalSkillsDir: join6(home, ".copilot/skills"),
|
|
2168
2155
|
detectInstalled: async () => {
|
|
2169
2156
|
return existsSync(join6(home, ".copilot"));
|
|
2170
|
-
},
|
|
2171
|
-
agentConfigSupport: {
|
|
2172
|
-
activationHint: 'Open Copilot Chat in your IDE and select the "skills-mcp" agent from the agent picker.',
|
|
2173
|
-
verified: true
|
|
2174
2157
|
}
|
|
2175
2158
|
},
|
|
2176
2159
|
goose: {
|
|
@@ -2225,10 +2208,6 @@ var agents = {
|
|
|
2225
2208
|
globalSkillsDir: join6(home, ".kiro/skills"),
|
|
2226
2209
|
detectInstalled: async () => {
|
|
2227
2210
|
return existsSync(join6(home, ".kiro"));
|
|
2228
|
-
},
|
|
2229
|
-
agentConfigSupport: {
|
|
2230
|
-
activationHint: "kiro-cli chat --agent skills-mcp",
|
|
2231
|
-
verified: true
|
|
2232
2211
|
}
|
|
2233
2212
|
},
|
|
2234
2213
|
kode: {
|
|
@@ -2274,10 +2253,6 @@ var agents = {
|
|
|
2274
2253
|
globalSkillsDir: join6(configHome, "opencode/skills"),
|
|
2275
2254
|
detectInstalled: async () => {
|
|
2276
2255
|
return existsSync(join6(configHome, "opencode"));
|
|
2277
|
-
},
|
|
2278
|
-
agentConfigSupport: {
|
|
2279
|
-
activationHint: "opencode --agent skills-mcp (or type @skills-mcp inside the TUI)",
|
|
2280
|
-
verified: true
|
|
2281
2256
|
}
|
|
2282
2257
|
},
|
|
2283
2258
|
openhands: {
|
|
@@ -2353,6 +2328,15 @@ var agents = {
|
|
|
2353
2328
|
return existsSync(join6(home, ".trae-cn"));
|
|
2354
2329
|
}
|
|
2355
2330
|
},
|
|
2331
|
+
warp: {
|
|
2332
|
+
name: "warp",
|
|
2333
|
+
displayName: "Warp",
|
|
2334
|
+
skillsDir: ".agents/skills",
|
|
2335
|
+
globalSkillsDir: join6(home, ".agents/skills"),
|
|
2336
|
+
detectInstalled: async () => {
|
|
2337
|
+
return existsSync(join6(home, ".warp"));
|
|
2338
|
+
}
|
|
2339
|
+
},
|
|
2356
2340
|
windsurf: {
|
|
2357
2341
|
name: "windsurf",
|
|
2358
2342
|
displayName: "Windsurf",
|
|
@@ -2438,9 +2422,9 @@ function sanitizeName(name) {
|
|
|
2438
2422
|
return sanitized.substring(0, 255) || "unnamed-skill";
|
|
2439
2423
|
}
|
|
2440
2424
|
function isPathSafe(basePath, targetPath) {
|
|
2441
|
-
const normalizedBase =
|
|
2442
|
-
const normalizedTarget =
|
|
2443
|
-
return normalizedTarget.startsWith(normalizedBase +
|
|
2425
|
+
const normalizedBase = normalize4(resolve5(basePath));
|
|
2426
|
+
const normalizedTarget = normalize4(resolve5(targetPath));
|
|
2427
|
+
return normalizedTarget.startsWith(normalizedBase + sep4) || normalizedTarget === normalizedBase;
|
|
2444
2428
|
}
|
|
2445
2429
|
function getCanonicalSkillsDir(global, cwd) {
|
|
2446
2430
|
const baseDir = global ? homedir3() : cwd || process.cwd();
|
|
@@ -2624,10 +2608,10 @@ async function installSkillForAgent(skill, agentType, options = {}) {
|
|
|
2624
2608
|
}
|
|
2625
2609
|
}
|
|
2626
2610
|
var EXCLUDE_FILES = /* @__PURE__ */ new Set(["metadata.json"]);
|
|
2627
|
-
var EXCLUDE_DIRS = /* @__PURE__ */ new Set([".git"]);
|
|
2611
|
+
var EXCLUDE_DIRS = /* @__PURE__ */ new Set([".git", "__pycache__", "__pypackages__"]);
|
|
2628
2612
|
var isExcluded = (name, isDirectory = false) => {
|
|
2629
2613
|
if (EXCLUDE_FILES.has(name)) return true;
|
|
2630
|
-
if (name.startsWith("
|
|
2614
|
+
if (name.startsWith(".")) return true;
|
|
2631
2615
|
if (isDirectory && EXCLUDE_DIRS.has(name)) return true;
|
|
2632
2616
|
return false;
|
|
2633
2617
|
};
|
|
@@ -2641,14 +2625,22 @@ async function copyDirectory(src, dest) {
|
|
|
2641
2625
|
if (entry.isDirectory()) {
|
|
2642
2626
|
await copyDirectory(srcPath, destPath);
|
|
2643
2627
|
} else {
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2628
|
+
try {
|
|
2629
|
+
await cp(srcPath, destPath, {
|
|
2630
|
+
// If the file is a symlink to elsewhere in a remote skill, it may not
|
|
2631
|
+
// resolve correctly once it has been copied to the local location.
|
|
2632
|
+
// `dereference: true` tells Node to copy the file instead of copying
|
|
2633
|
+
// the symlink. `recursive: true` handles symlinks pointing to directories.
|
|
2634
|
+
dereference: true,
|
|
2635
|
+
recursive: true
|
|
2636
|
+
});
|
|
2637
|
+
} catch (err) {
|
|
2638
|
+
if (err instanceof Error && "code" in err && err.code === "ENOENT" && entry.isSymbolicLink()) {
|
|
2639
|
+
console.warn(`Skipping broken symlink: ${srcPath}`);
|
|
2640
|
+
} else {
|
|
2641
|
+
throw err;
|
|
2642
|
+
}
|
|
2643
|
+
}
|
|
2652
2644
|
}
|
|
2653
2645
|
})
|
|
2654
2646
|
);
|
|
@@ -2691,101 +2683,6 @@ function getCanonicalPath(skillName, options = {}) {
|
|
|
2691
2683
|
}
|
|
2692
2684
|
return canonicalPath;
|
|
2693
2685
|
}
|
|
2694
|
-
async function installRemoteSkillForAgent(skill, agentType, options = {}) {
|
|
2695
|
-
const agent = agents[agentType];
|
|
2696
|
-
const isGlobal = options.global ?? false;
|
|
2697
|
-
const cwd = options.cwd || process.cwd();
|
|
2698
|
-
const installMode = options.mode ?? "symlink";
|
|
2699
|
-
if (isGlobal && agent.globalSkillsDir === void 0) {
|
|
2700
|
-
return {
|
|
2701
|
-
success: false,
|
|
2702
|
-
path: "",
|
|
2703
|
-
mode: installMode,
|
|
2704
|
-
error: `${agent.displayName} does not support global skill installation`
|
|
2705
|
-
};
|
|
2706
|
-
}
|
|
2707
|
-
const skillName = sanitizeName(skill.installName);
|
|
2708
|
-
const canonicalBase = installMode === "mcp-server" ? getMCPCanonicalSkillsDir(isGlobal, cwd) : getCanonicalSkillsDir(isGlobal, cwd);
|
|
2709
|
-
const canonicalDir = join7(canonicalBase, skillName);
|
|
2710
|
-
const agentBase = getAgentBaseDir(agentType, isGlobal, cwd);
|
|
2711
|
-
const agentDir = join7(agentBase, skillName);
|
|
2712
|
-
if (!isPathSafe(canonicalBase, canonicalDir)) {
|
|
2713
|
-
return {
|
|
2714
|
-
success: false,
|
|
2715
|
-
path: agentDir,
|
|
2716
|
-
mode: installMode,
|
|
2717
|
-
error: "Invalid skill name: potential path traversal detected"
|
|
2718
|
-
};
|
|
2719
|
-
}
|
|
2720
|
-
if (!isPathSafe(agentBase, agentDir)) {
|
|
2721
|
-
return {
|
|
2722
|
-
success: false,
|
|
2723
|
-
path: agentDir,
|
|
2724
|
-
mode: installMode,
|
|
2725
|
-
error: "Invalid skill name: potential path traversal detected"
|
|
2726
|
-
};
|
|
2727
|
-
}
|
|
2728
|
-
try {
|
|
2729
|
-
if (installMode === "mcp-server") {
|
|
2730
|
-
await cleanAndCreateDirectory(canonicalDir);
|
|
2731
|
-
const skillMdPath2 = join7(canonicalDir, "SKILL.md");
|
|
2732
|
-
await writeFile3(skillMdPath2, skill.content, "utf-8");
|
|
2733
|
-
return {
|
|
2734
|
-
success: true,
|
|
2735
|
-
path: canonicalDir,
|
|
2736
|
-
canonicalPath: canonicalDir,
|
|
2737
|
-
mode: "mcp-server"
|
|
2738
|
-
};
|
|
2739
|
-
}
|
|
2740
|
-
if (installMode === "copy") {
|
|
2741
|
-
await cleanAndCreateDirectory(agentDir);
|
|
2742
|
-
const skillMdPath2 = join7(agentDir, "SKILL.md");
|
|
2743
|
-
await writeFile3(skillMdPath2, skill.content, "utf-8");
|
|
2744
|
-
return {
|
|
2745
|
-
success: true,
|
|
2746
|
-
path: agentDir,
|
|
2747
|
-
mode: "copy"
|
|
2748
|
-
};
|
|
2749
|
-
}
|
|
2750
|
-
await cleanAndCreateDirectory(canonicalDir);
|
|
2751
|
-
const skillMdPath = join7(canonicalDir, "SKILL.md");
|
|
2752
|
-
await writeFile3(skillMdPath, skill.content, "utf-8");
|
|
2753
|
-
if (isGlobal && isUniversalAgent(agentType)) {
|
|
2754
|
-
return {
|
|
2755
|
-
success: true,
|
|
2756
|
-
path: canonicalDir,
|
|
2757
|
-
canonicalPath: canonicalDir,
|
|
2758
|
-
mode: "symlink"
|
|
2759
|
-
};
|
|
2760
|
-
}
|
|
2761
|
-
const symlinkCreated = await createSymlink(canonicalDir, agentDir);
|
|
2762
|
-
if (!symlinkCreated) {
|
|
2763
|
-
await cleanAndCreateDirectory(agentDir);
|
|
2764
|
-
const agentSkillMdPath = join7(agentDir, "SKILL.md");
|
|
2765
|
-
await writeFile3(agentSkillMdPath, skill.content, "utf-8");
|
|
2766
|
-
return {
|
|
2767
|
-
success: true,
|
|
2768
|
-
path: agentDir,
|
|
2769
|
-
canonicalPath: canonicalDir,
|
|
2770
|
-
mode: "symlink",
|
|
2771
|
-
symlinkFailed: true
|
|
2772
|
-
};
|
|
2773
|
-
}
|
|
2774
|
-
return {
|
|
2775
|
-
success: true,
|
|
2776
|
-
path: agentDir,
|
|
2777
|
-
canonicalPath: canonicalDir,
|
|
2778
|
-
mode: "symlink"
|
|
2779
|
-
};
|
|
2780
|
-
} catch (error) {
|
|
2781
|
-
return {
|
|
2782
|
-
success: false,
|
|
2783
|
-
path: agentDir,
|
|
2784
|
-
mode: installMode,
|
|
2785
|
-
error: error instanceof Error ? error.message : "Unknown error"
|
|
2786
|
-
};
|
|
2787
|
-
}
|
|
2788
|
-
}
|
|
2789
2686
|
async function installWellKnownSkillForAgent(skill, agentType, options = {}) {
|
|
2790
2687
|
const agent = agents[agentType];
|
|
2791
2688
|
const isGlobal = options.global ?? false;
|
|
@@ -3052,152 +2949,9 @@ var ProviderRegistryImpl = class {
|
|
|
3052
2949
|
}
|
|
3053
2950
|
};
|
|
3054
2951
|
var registry = new ProviderRegistryImpl();
|
|
3055
|
-
function registerProvider(provider) {
|
|
3056
|
-
registry.register(provider);
|
|
3057
|
-
}
|
|
3058
|
-
function findProvider(url) {
|
|
3059
|
-
return registry.findProvider(url);
|
|
3060
|
-
}
|
|
3061
|
-
|
|
3062
|
-
// src/providers/mintlify.ts
|
|
3063
|
-
import matter2 from "gray-matter";
|
|
3064
|
-
var MintlifyProvider = class {
|
|
3065
|
-
id = "mintlify";
|
|
3066
|
-
displayName = "Mintlify";
|
|
3067
|
-
match(url) {
|
|
3068
|
-
if (!url.startsWith("http://") && !url.startsWith("https://")) {
|
|
3069
|
-
return { matches: false };
|
|
3070
|
-
}
|
|
3071
|
-
if (!url.toLowerCase().endsWith("/skill.md")) {
|
|
3072
|
-
return { matches: false };
|
|
3073
|
-
}
|
|
3074
|
-
if (url.includes("github.com") || url.includes("gitlab.com")) {
|
|
3075
|
-
return { matches: false };
|
|
3076
|
-
}
|
|
3077
|
-
if (url.includes("huggingface.co")) {
|
|
3078
|
-
return { matches: false };
|
|
3079
|
-
}
|
|
3080
|
-
return { matches: true };
|
|
3081
|
-
}
|
|
3082
|
-
async fetchSkill(url) {
|
|
3083
|
-
try {
|
|
3084
|
-
const response = await fetch(url, { signal: AbortSignal.timeout(3e4) });
|
|
3085
|
-
if (!response.ok) {
|
|
3086
|
-
return null;
|
|
3087
|
-
}
|
|
3088
|
-
const content = await response.text();
|
|
3089
|
-
const { data } = matter2(content);
|
|
3090
|
-
const mintlifySite = data.metadata?.["mintlify-proj"];
|
|
3091
|
-
if (!mintlifySite) {
|
|
3092
|
-
return null;
|
|
3093
|
-
}
|
|
3094
|
-
if (!data.name || !data.description) {
|
|
3095
|
-
return null;
|
|
3096
|
-
}
|
|
3097
|
-
return {
|
|
3098
|
-
name: data.name,
|
|
3099
|
-
description: data.description,
|
|
3100
|
-
content,
|
|
3101
|
-
installName: mintlifySite,
|
|
3102
|
-
sourceUrl: url,
|
|
3103
|
-
metadata: data.metadata
|
|
3104
|
-
};
|
|
3105
|
-
} catch {
|
|
3106
|
-
return null;
|
|
3107
|
-
}
|
|
3108
|
-
}
|
|
3109
|
-
toRawUrl(url) {
|
|
3110
|
-
return url;
|
|
3111
|
-
}
|
|
3112
|
-
getSourceIdentifier(url) {
|
|
3113
|
-
return "mintlify/com";
|
|
3114
|
-
}
|
|
3115
|
-
};
|
|
3116
|
-
var mintlifyProvider = new MintlifyProvider();
|
|
3117
|
-
|
|
3118
|
-
// src/providers/huggingface.ts
|
|
3119
|
-
import matter3 from "gray-matter";
|
|
3120
|
-
var HuggingFaceProvider = class {
|
|
3121
|
-
id = "huggingface";
|
|
3122
|
-
displayName = "HuggingFace";
|
|
3123
|
-
HOST = "huggingface.co";
|
|
3124
|
-
match(url) {
|
|
3125
|
-
if (!url.startsWith("http://") && !url.startsWith("https://")) {
|
|
3126
|
-
return { matches: false };
|
|
3127
|
-
}
|
|
3128
|
-
try {
|
|
3129
|
-
const parsed = new URL(url);
|
|
3130
|
-
if (parsed.hostname !== this.HOST) {
|
|
3131
|
-
return { matches: false };
|
|
3132
|
-
}
|
|
3133
|
-
} catch {
|
|
3134
|
-
return { matches: false };
|
|
3135
|
-
}
|
|
3136
|
-
if (!url.toLowerCase().endsWith("/skill.md")) {
|
|
3137
|
-
return { matches: false };
|
|
3138
|
-
}
|
|
3139
|
-
if (!url.includes("/spaces/")) {
|
|
3140
|
-
return { matches: false };
|
|
3141
|
-
}
|
|
3142
|
-
return { matches: true };
|
|
3143
|
-
}
|
|
3144
|
-
async fetchSkill(url) {
|
|
3145
|
-
try {
|
|
3146
|
-
const rawUrl = this.toRawUrl(url);
|
|
3147
|
-
const response = await fetch(rawUrl, { signal: AbortSignal.timeout(3e4) });
|
|
3148
|
-
if (!response.ok) {
|
|
3149
|
-
return null;
|
|
3150
|
-
}
|
|
3151
|
-
const content = await response.text();
|
|
3152
|
-
const { data } = matter3(content);
|
|
3153
|
-
if (!data.name || !data.description) {
|
|
3154
|
-
return null;
|
|
3155
|
-
}
|
|
3156
|
-
const parsed = this.parseUrl(url);
|
|
3157
|
-
if (!parsed) {
|
|
3158
|
-
return null;
|
|
3159
|
-
}
|
|
3160
|
-
const installName = data.metadata?.["install-name"] || parsed.repo;
|
|
3161
|
-
return {
|
|
3162
|
-
name: data.name,
|
|
3163
|
-
description: data.description,
|
|
3164
|
-
content,
|
|
3165
|
-
installName,
|
|
3166
|
-
sourceUrl: url,
|
|
3167
|
-
metadata: data.metadata
|
|
3168
|
-
};
|
|
3169
|
-
} catch {
|
|
3170
|
-
return null;
|
|
3171
|
-
}
|
|
3172
|
-
}
|
|
3173
|
-
toRawUrl(url) {
|
|
3174
|
-
return url.replace("/blob/", "/raw/");
|
|
3175
|
-
}
|
|
3176
|
-
getSourceIdentifier(url) {
|
|
3177
|
-
const parsed = this.parseUrl(url);
|
|
3178
|
-
if (!parsed) {
|
|
3179
|
-
return "huggingface/unknown";
|
|
3180
|
-
}
|
|
3181
|
-
return `huggingface/${parsed.owner}/${parsed.repo}`;
|
|
3182
|
-
}
|
|
3183
|
-
/**
|
|
3184
|
-
* Parse a HuggingFace Spaces URL to extract owner and repo.
|
|
3185
|
-
*/
|
|
3186
|
-
parseUrl(url) {
|
|
3187
|
-
const match = url.match(/\/spaces\/([^/]+)\/([^/]+)/);
|
|
3188
|
-
if (!match || !match[1] || !match[2]) {
|
|
3189
|
-
return null;
|
|
3190
|
-
}
|
|
3191
|
-
return {
|
|
3192
|
-
owner: match[1],
|
|
3193
|
-
repo: match[2]
|
|
3194
|
-
};
|
|
3195
|
-
}
|
|
3196
|
-
};
|
|
3197
|
-
var huggingFaceProvider = new HuggingFaceProvider();
|
|
3198
2952
|
|
|
3199
2953
|
// src/providers/wellknown.ts
|
|
3200
|
-
import
|
|
2954
|
+
import matter2 from "gray-matter";
|
|
3201
2955
|
var WellKnownProvider = class {
|
|
3202
2956
|
id = "well-known";
|
|
3203
2957
|
displayName = "Well-Known Skills";
|
|
@@ -3343,7 +3097,7 @@ var WellKnownProvider = class {
|
|
|
3343
3097
|
return null;
|
|
3344
3098
|
}
|
|
3345
3099
|
const content = await response.text();
|
|
3346
|
-
const { data } =
|
|
3100
|
+
const { data } = matter2(content);
|
|
3347
3101
|
if (!data.name || !data.description) {
|
|
3348
3102
|
return null;
|
|
3349
3103
|
}
|
|
@@ -3424,22 +3178,18 @@ var WellKnownProvider = class {
|
|
|
3424
3178
|
}
|
|
3425
3179
|
/**
|
|
3426
3180
|
* Get the source identifier for telemetry/storage.
|
|
3427
|
-
* Returns the
|
|
3428
|
-
* e.g., "mintlify.com" → "mintlify
|
|
3429
|
-
*
|
|
3181
|
+
* Returns the full hostname with www. stripped.
|
|
3182
|
+
* e.g., "https://mintlify.com/docs" → "mintlify.com"
|
|
3183
|
+
* "https://mppx-discovery-skills.vercel.app" → "mppx-discovery-skills.vercel.app"
|
|
3184
|
+
* "https://www.example.com" → "example.com"
|
|
3185
|
+
* "https://docs.lovable.dev" → "docs.lovable.dev"
|
|
3430
3186
|
*/
|
|
3431
3187
|
getSourceIdentifier(url) {
|
|
3432
3188
|
try {
|
|
3433
3189
|
const parsed = new URL(url);
|
|
3434
|
-
|
|
3435
|
-
if (hostParts.length >= 2) {
|
|
3436
|
-
const tld = hostParts[hostParts.length - 1];
|
|
3437
|
-
const sld = hostParts[hostParts.length - 2];
|
|
3438
|
-
return `${sld}/${tld}`;
|
|
3439
|
-
}
|
|
3440
|
-
return parsed.hostname.replace(".", "/");
|
|
3190
|
+
return parsed.hostname.replace(/^www\./, "");
|
|
3441
3191
|
} catch {
|
|
3442
|
-
return "unknown
|
|
3192
|
+
return "unknown";
|
|
3443
3193
|
}
|
|
3444
3194
|
}
|
|
3445
3195
|
/**
|
|
@@ -3452,44 +3202,10 @@ var WellKnownProvider = class {
|
|
|
3452
3202
|
};
|
|
3453
3203
|
var wellKnownProvider = new WellKnownProvider();
|
|
3454
3204
|
|
|
3455
|
-
// src/providers/index.ts
|
|
3456
|
-
registerProvider(mintlifyProvider);
|
|
3457
|
-
registerProvider(huggingFaceProvider);
|
|
3458
|
-
|
|
3459
|
-
// src/mintlify.ts
|
|
3460
|
-
import matter5 from "gray-matter";
|
|
3461
|
-
async function fetchMintlifySkill(url) {
|
|
3462
|
-
try {
|
|
3463
|
-
const response = await fetch(url, { signal: AbortSignal.timeout(3e4) });
|
|
3464
|
-
if (!response.ok) {
|
|
3465
|
-
return null;
|
|
3466
|
-
}
|
|
3467
|
-
const content = await response.text();
|
|
3468
|
-
const { data } = matter5(content);
|
|
3469
|
-
const mintlifySite = data.metadata?.["mintlify-proj"];
|
|
3470
|
-
if (!mintlifySite) {
|
|
3471
|
-
return null;
|
|
3472
|
-
}
|
|
3473
|
-
if (!data.name || !data.description) {
|
|
3474
|
-
return null;
|
|
3475
|
-
}
|
|
3476
|
-
return {
|
|
3477
|
-
name: data.name,
|
|
3478
|
-
description: data.description,
|
|
3479
|
-
content,
|
|
3480
|
-
// Full content including frontmatter
|
|
3481
|
-
mintlifySite,
|
|
3482
|
-
sourceUrl: url
|
|
3483
|
-
};
|
|
3484
|
-
} catch {
|
|
3485
|
-
return null;
|
|
3486
|
-
}
|
|
3487
|
-
}
|
|
3488
|
-
|
|
3489
3205
|
// package.json
|
|
3490
3206
|
var package_default = {
|
|
3491
3207
|
name: "@codemcp/skills",
|
|
3492
|
-
version: "2.1.
|
|
3208
|
+
version: "2.1.1",
|
|
3493
3209
|
description: "Command-line interface for Agent Skills management",
|
|
3494
3210
|
type: "module",
|
|
3495
3211
|
publishConfig: {
|
|
@@ -3572,23 +3288,23 @@ function initTelemetry(version2) {
|
|
|
3572
3288
|
function riskLabel(risk) {
|
|
3573
3289
|
switch (risk) {
|
|
3574
3290
|
case "critical":
|
|
3575
|
-
return
|
|
3291
|
+
return import_picocolors3.default.red(import_picocolors3.default.bold("Critical Risk"));
|
|
3576
3292
|
case "high":
|
|
3577
|
-
return
|
|
3293
|
+
return import_picocolors3.default.red("High Risk");
|
|
3578
3294
|
case "medium":
|
|
3579
|
-
return
|
|
3295
|
+
return import_picocolors3.default.yellow("Med Risk");
|
|
3580
3296
|
case "low":
|
|
3581
|
-
return
|
|
3297
|
+
return import_picocolors3.default.green("Low Risk");
|
|
3582
3298
|
case "safe":
|
|
3583
|
-
return
|
|
3299
|
+
return import_picocolors3.default.green("Safe");
|
|
3584
3300
|
default:
|
|
3585
|
-
return
|
|
3301
|
+
return import_picocolors3.default.dim("--");
|
|
3586
3302
|
}
|
|
3587
3303
|
}
|
|
3588
3304
|
function socketLabel(audit) {
|
|
3589
|
-
if (!audit) return
|
|
3305
|
+
if (!audit) return import_picocolors3.default.dim("--");
|
|
3590
3306
|
const count = audit.alerts ?? 0;
|
|
3591
|
-
return count > 0 ?
|
|
3307
|
+
return count > 0 ? import_picocolors3.default.red(`${count} alert${count !== 1 ? "s" : ""}`) : import_picocolors3.default.green("0 alerts");
|
|
3592
3308
|
}
|
|
3593
3309
|
function padEnd(str, width) {
|
|
3594
3310
|
const visible = str.replace(/\x1b\[[0-9;]*m/g, "");
|
|
@@ -3604,26 +3320,26 @@ function buildSecurityLines(auditData, skills, source) {
|
|
|
3604
3320
|
if (!hasAny) return [];
|
|
3605
3321
|
const nameWidth = Math.min(Math.max(...skills.map((s) => s.displayName.length)), 36);
|
|
3606
3322
|
const lines = [];
|
|
3607
|
-
const header = padEnd("", nameWidth + 2) + padEnd(
|
|
3323
|
+
const header = padEnd("", nameWidth + 2) + padEnd(import_picocolors3.default.dim("Gen"), 18) + padEnd(import_picocolors3.default.dim("Socket"), 18) + import_picocolors3.default.dim("Snyk");
|
|
3608
3324
|
lines.push(header);
|
|
3609
3325
|
for (const skill of skills) {
|
|
3610
3326
|
const data = auditData[skill.slug];
|
|
3611
3327
|
const name = skill.displayName.length > nameWidth ? skill.displayName.slice(0, nameWidth - 1) + "\u2026" : skill.displayName;
|
|
3612
|
-
const ath = data?.ath ? riskLabel(data.ath.risk) :
|
|
3613
|
-
const socket = data?.socket ? socketLabel(data.socket) :
|
|
3614
|
-
const snyk = data?.snyk ? riskLabel(data.snyk.risk) :
|
|
3615
|
-
lines.push(padEnd(
|
|
3328
|
+
const ath = data?.ath ? riskLabel(data.ath.risk) : import_picocolors3.default.dim("--");
|
|
3329
|
+
const socket = data?.socket ? socketLabel(data.socket) : import_picocolors3.default.dim("--");
|
|
3330
|
+
const snyk = data?.snyk ? riskLabel(data.snyk.risk) : import_picocolors3.default.dim("--");
|
|
3331
|
+
lines.push(padEnd(import_picocolors3.default.cyan(name), nameWidth + 2) + padEnd(ath, 18) + padEnd(socket, 18) + snyk);
|
|
3616
3332
|
}
|
|
3617
3333
|
lines.push("");
|
|
3618
|
-
lines.push(`${
|
|
3334
|
+
lines.push(`${import_picocolors3.default.dim("Details:")} ${import_picocolors3.default.dim(`https://skills.sh/${source}`)}`);
|
|
3619
3335
|
return lines;
|
|
3620
3336
|
}
|
|
3621
3337
|
function shortenPath(fullPath, cwd) {
|
|
3622
3338
|
const home2 = homedir4();
|
|
3623
|
-
if (fullPath === home2 || fullPath.startsWith(home2 +
|
|
3339
|
+
if (fullPath === home2 || fullPath.startsWith(home2 + sep5)) {
|
|
3624
3340
|
return "~" + fullPath.slice(home2.length);
|
|
3625
3341
|
}
|
|
3626
|
-
if (fullPath === cwd || fullPath.startsWith(cwd +
|
|
3342
|
+
if (fullPath === cwd || fullPath.startsWith(cwd + sep5)) {
|
|
3627
3343
|
return "." + fullPath.slice(cwd.length);
|
|
3628
3344
|
}
|
|
3629
3345
|
return fullPath;
|
|
@@ -3652,17 +3368,17 @@ function buildAgentSummaryLines(targetAgents, installMode) {
|
|
|
3652
3368
|
const lines = [];
|
|
3653
3369
|
const { universal, symlinked } = splitAgentsByType(targetAgents);
|
|
3654
3370
|
if (installMode === "mcp-server") {
|
|
3655
|
-
lines.push(` ${
|
|
3371
|
+
lines.push(` ${import_picocolors3.default.dim("mcp-server \u2192")} @codemcp/skills-server`);
|
|
3656
3372
|
} else if (installMode === "symlink") {
|
|
3657
3373
|
if (universal.length > 0) {
|
|
3658
|
-
lines.push(` ${
|
|
3374
|
+
lines.push(` ${import_picocolors3.default.green("universal:")} ${formatList(universal)}`);
|
|
3659
3375
|
}
|
|
3660
3376
|
if (symlinked.length > 0) {
|
|
3661
|
-
lines.push(` ${
|
|
3377
|
+
lines.push(` ${import_picocolors3.default.dim("symlink \u2192")} ${formatList(symlinked)}`);
|
|
3662
3378
|
}
|
|
3663
3379
|
} else {
|
|
3664
3380
|
const allNames = targetAgents.map((a) => agents[a].displayName);
|
|
3665
|
-
lines.push(` ${
|
|
3381
|
+
lines.push(` ${import_picocolors3.default.dim("copy \u2192")} ${formatList(allNames)}`);
|
|
3666
3382
|
}
|
|
3667
3383
|
return lines;
|
|
3668
3384
|
}
|
|
@@ -3680,21 +3396,21 @@ function buildResultLines(results, targetAgents) {
|
|
|
3680
3396
|
const lines = [];
|
|
3681
3397
|
const isMcpMode = results.length > 0 && results[0].mode === "mcp-server";
|
|
3682
3398
|
if (isMcpMode) {
|
|
3683
|
-
lines.push(` ${
|
|
3684
|
-
lines.push(` ${
|
|
3399
|
+
lines.push(` ${import_picocolors3.default.dim("Important:")} Make sure your agent has configured`);
|
|
3400
|
+
lines.push(` ${import_picocolors3.default.cyan("@codemcp/skills-server")} as MCP server.`);
|
|
3685
3401
|
lines.push(` Then, the skill will automatically be picked up`);
|
|
3686
3402
|
} else {
|
|
3687
3403
|
const { universal, symlinked: symlinkAgents } = splitAgentsByType(targetAgents);
|
|
3688
3404
|
const successfulSymlinks = results.filter((r2) => !r2.symlinkFailed && !universal.includes(r2.agent)).map((r2) => r2.agent);
|
|
3689
3405
|
const failedSymlinks = results.filter((r2) => r2.symlinkFailed).map((r2) => r2.agent);
|
|
3690
3406
|
if (universal.length > 0) {
|
|
3691
|
-
lines.push(` ${
|
|
3407
|
+
lines.push(` ${import_picocolors3.default.green("universal:")} ${formatList(universal)}`);
|
|
3692
3408
|
}
|
|
3693
3409
|
if (successfulSymlinks.length > 0) {
|
|
3694
|
-
lines.push(` ${
|
|
3410
|
+
lines.push(` ${import_picocolors3.default.dim("symlinked:")} ${formatList(successfulSymlinks)}`);
|
|
3695
3411
|
}
|
|
3696
3412
|
if (failedSymlinks.length > 0) {
|
|
3697
|
-
lines.push(` ${
|
|
3413
|
+
lines.push(` ${import_picocolors3.default.yellow("copied:")} ${formatList(failedSymlinks)}`);
|
|
3698
3414
|
}
|
|
3699
3415
|
}
|
|
3700
3416
|
return lines;
|
|
@@ -3704,7 +3420,7 @@ function multiselect(opts) {
|
|
|
3704
3420
|
...opts,
|
|
3705
3421
|
// Cast is safe: our options always have labels, which satisfies p.Option requirements
|
|
3706
3422
|
options: opts.options,
|
|
3707
|
-
message: `${opts.message} ${
|
|
3423
|
+
message: `${opts.message} ${import_picocolors3.default.dim("(space to toggle)")}`
|
|
3708
3424
|
});
|
|
3709
3425
|
}
|
|
3710
3426
|
async function promptForAgents(message, choices) {
|
|
@@ -3777,263 +3493,34 @@ async function selectAgentsInteractive(options) {
|
|
|
3777
3493
|
}
|
|
3778
3494
|
var version = package_default.version;
|
|
3779
3495
|
setVersion(version);
|
|
3780
|
-
async function handleRemoteSkill(source, url, options, spinner) {
|
|
3781
|
-
const provider = findProvider(url);
|
|
3782
|
-
if (!provider) {
|
|
3783
|
-
await handleDirectUrlSkillLegacy(source, url, options, spinner);
|
|
3784
|
-
return;
|
|
3785
|
-
}
|
|
3786
|
-
spinner.start(`Fetching skill.md from ${provider.displayName}...`);
|
|
3787
|
-
const providerSkill = await provider.fetchSkill(url);
|
|
3788
|
-
if (!providerSkill) {
|
|
3789
|
-
spinner.stop(import_picocolors4.default.red("Invalid skill"));
|
|
3790
|
-
Se(
|
|
3791
|
-
import_picocolors4.default.red("Could not fetch skill.md or missing required frontmatter (name, description).")
|
|
3792
|
-
);
|
|
3793
|
-
process.exit(1);
|
|
3794
|
-
}
|
|
3795
|
-
const remoteSkill = {
|
|
3796
|
-
name: providerSkill.name,
|
|
3797
|
-
description: providerSkill.description,
|
|
3798
|
-
content: providerSkill.content,
|
|
3799
|
-
installName: providerSkill.installName,
|
|
3800
|
-
sourceUrl: providerSkill.sourceUrl,
|
|
3801
|
-
providerId: provider.id,
|
|
3802
|
-
sourceIdentifier: provider.getSourceIdentifier(url),
|
|
3803
|
-
metadata: providerSkill.metadata
|
|
3804
|
-
};
|
|
3805
|
-
spinner.stop(`Found skill: ${import_picocolors4.default.cyan(remoteSkill.installName)}`);
|
|
3806
|
-
M2.info(`Skill: ${import_picocolors4.default.cyan(remoteSkill.name)}`);
|
|
3807
|
-
M2.message(import_picocolors4.default.dim(remoteSkill.description));
|
|
3808
|
-
M2.message(import_picocolors4.default.dim(`Source: ${remoteSkill.sourceIdentifier}`));
|
|
3809
|
-
if (options.list) {
|
|
3810
|
-
console.log();
|
|
3811
|
-
M2.step(import_picocolors4.default.bold("Skill Details"));
|
|
3812
|
-
M2.message(` ${import_picocolors4.default.cyan("Name:")} ${remoteSkill.name}`);
|
|
3813
|
-
M2.message(` ${import_picocolors4.default.cyan("Install as:")} ${remoteSkill.installName}`);
|
|
3814
|
-
M2.message(` ${import_picocolors4.default.cyan("Provider:")} ${provider.displayName}`);
|
|
3815
|
-
M2.message(` ${import_picocolors4.default.cyan("Description:")} ${remoteSkill.description}`);
|
|
3816
|
-
console.log();
|
|
3817
|
-
Se("Run without --list to install");
|
|
3818
|
-
process.exit(0);
|
|
3819
|
-
}
|
|
3820
|
-
const universalAgents = getUniversalAgents();
|
|
3821
|
-
const targetAgents = universalAgents;
|
|
3822
|
-
let installGlobally = options.global ?? false;
|
|
3823
|
-
const supportsGlobal = targetAgents.some((a) => agents[a].globalSkillsDir !== void 0);
|
|
3824
|
-
if (options.global === void 0 && !options.yes && supportsGlobal) {
|
|
3825
|
-
const scope = await ve({
|
|
3826
|
-
message: "Installation scope",
|
|
3827
|
-
options: [
|
|
3828
|
-
{
|
|
3829
|
-
value: false,
|
|
3830
|
-
label: "Project",
|
|
3831
|
-
hint: "Install in current directory (committed with your project)"
|
|
3832
|
-
},
|
|
3833
|
-
{
|
|
3834
|
-
value: true,
|
|
3835
|
-
label: "Global",
|
|
3836
|
-
hint: "Install in home directory (available across all projects)"
|
|
3837
|
-
}
|
|
3838
|
-
]
|
|
3839
|
-
});
|
|
3840
|
-
if (pD(scope)) {
|
|
3841
|
-
xe("Installation cancelled");
|
|
3842
|
-
process.exit(0);
|
|
3843
|
-
}
|
|
3844
|
-
installGlobally = scope;
|
|
3845
|
-
}
|
|
3846
|
-
const installMode = "mcp-server";
|
|
3847
|
-
const cwd = process.cwd();
|
|
3848
|
-
const overwriteChecks = await Promise.all(
|
|
3849
|
-
targetAgents.map(async (agent) => ({
|
|
3850
|
-
agent,
|
|
3851
|
-
installed: await isSkillInstalled(remoteSkill.installName, agent, {
|
|
3852
|
-
global: installGlobally
|
|
3853
|
-
})
|
|
3854
|
-
}))
|
|
3855
|
-
);
|
|
3856
|
-
const overwriteStatus = new Map(
|
|
3857
|
-
overwriteChecks.map(({ agent, installed }) => [agent, installed])
|
|
3858
|
-
);
|
|
3859
|
-
const summaryLines = [];
|
|
3860
|
-
const canonicalPath = getCanonicalPath(remoteSkill.installName, { global: installGlobally });
|
|
3861
|
-
const shortCanonical = shortenPath(canonicalPath, cwd);
|
|
3862
|
-
summaryLines.push(`${import_picocolors4.default.cyan(shortCanonical)}`);
|
|
3863
|
-
summaryLines.push(...buildAgentSummaryLines(targetAgents, installMode));
|
|
3864
|
-
const overwriteAgents = targetAgents.filter((a) => overwriteStatus.get(a)).map((a) => agents[a].displayName);
|
|
3865
|
-
if (overwriteAgents.length > 0) {
|
|
3866
|
-
summaryLines.push(` ${import_picocolors4.default.yellow("overwrites:")} ${formatList(overwriteAgents)}`);
|
|
3867
|
-
}
|
|
3868
|
-
console.log();
|
|
3869
|
-
Me(summaryLines.join("\n"), "Installation Summary");
|
|
3870
|
-
if (!options.yes) {
|
|
3871
|
-
const confirmed = await ye({
|
|
3872
|
-
message: "Proceed with installation?"
|
|
3873
|
-
});
|
|
3874
|
-
if (pD(confirmed) || !confirmed) {
|
|
3875
|
-
xe("Installation cancelled");
|
|
3876
|
-
process.exit(0);
|
|
3877
|
-
}
|
|
3878
|
-
}
|
|
3879
|
-
spinner.start("Installing skill...");
|
|
3880
|
-
const results = [];
|
|
3881
|
-
if (installMode === "mcp-server") {
|
|
3882
|
-
const result = await installRemoteSkillForAgent(remoteSkill, "universal", {
|
|
3883
|
-
global: installGlobally,
|
|
3884
|
-
mode: installMode
|
|
3885
|
-
});
|
|
3886
|
-
results.push({
|
|
3887
|
-
skill: remoteSkill.installName,
|
|
3888
|
-
agent: "MCP Server",
|
|
3889
|
-
...result
|
|
3890
|
-
});
|
|
3891
|
-
} else {
|
|
3892
|
-
for (const agent of targetAgents) {
|
|
3893
|
-
const result = await installRemoteSkillForAgent(remoteSkill, agent, {
|
|
3894
|
-
global: installGlobally,
|
|
3895
|
-
mode: installMode
|
|
3896
|
-
});
|
|
3897
|
-
results.push({
|
|
3898
|
-
skill: remoteSkill.installName,
|
|
3899
|
-
agent: agents[agent].displayName,
|
|
3900
|
-
...result
|
|
3901
|
-
});
|
|
3902
|
-
}
|
|
3903
|
-
}
|
|
3904
|
-
spinner.stop("Installation complete");
|
|
3905
|
-
console.log();
|
|
3906
|
-
const successful = results.filter((r2) => r2.success);
|
|
3907
|
-
const failed = results.filter((r2) => !r2.success);
|
|
3908
|
-
const isPrivate = await isSourcePrivate(remoteSkill.sourceIdentifier);
|
|
3909
|
-
if (isPrivate !== true) {
|
|
3910
|
-
track({
|
|
3911
|
-
event: "install",
|
|
3912
|
-
source: remoteSkill.sourceIdentifier,
|
|
3913
|
-
skills: remoteSkill.installName,
|
|
3914
|
-
agents: targetAgents.join(","),
|
|
3915
|
-
...installGlobally && { global: "1" },
|
|
3916
|
-
skillFiles: JSON.stringify({ [remoteSkill.installName]: url }),
|
|
3917
|
-
sourceType: remoteSkill.providerId
|
|
3918
|
-
});
|
|
3919
|
-
}
|
|
3920
|
-
if (successful.length > 0 && installGlobally) {
|
|
3921
|
-
try {
|
|
3922
|
-
let skillFolderHash = "";
|
|
3923
|
-
if (remoteSkill.providerId === "github") {
|
|
3924
|
-
const hash = await fetchSkillFolderHash(remoteSkill.sourceIdentifier, url);
|
|
3925
|
-
if (hash) skillFolderHash = hash;
|
|
3926
|
-
}
|
|
3927
|
-
await addSkillToLock(remoteSkill.installName, {
|
|
3928
|
-
source: remoteSkill.sourceIdentifier,
|
|
3929
|
-
sourceType: remoteSkill.providerId,
|
|
3930
|
-
sourceUrl: url,
|
|
3931
|
-
skillFolderHash
|
|
3932
|
-
});
|
|
3933
|
-
} catch {
|
|
3934
|
-
}
|
|
3935
|
-
}
|
|
3936
|
-
if (successful.length > 0 && !installGlobally) {
|
|
3937
|
-
try {
|
|
3938
|
-
const firstResult = successful[0];
|
|
3939
|
-
const installDir = firstResult.canonicalPath || firstResult.path;
|
|
3940
|
-
const computedHash = await computeSkillFolderHash(installDir);
|
|
3941
|
-
await addSkillToLocalLock(
|
|
3942
|
-
remoteSkill.installName,
|
|
3943
|
-
{
|
|
3944
|
-
source: remoteSkill.sourceIdentifier,
|
|
3945
|
-
sourceType: remoteSkill.providerId,
|
|
3946
|
-
computedHash
|
|
3947
|
-
},
|
|
3948
|
-
cwd
|
|
3949
|
-
);
|
|
3950
|
-
} catch {
|
|
3951
|
-
}
|
|
3952
|
-
}
|
|
3953
|
-
if (successful.length > 0) {
|
|
3954
|
-
const resultLines = [];
|
|
3955
|
-
const firstResult = successful[0];
|
|
3956
|
-
if (firstResult.mode === "mcp-server") {
|
|
3957
|
-
if (firstResult.canonicalPath) {
|
|
3958
|
-
const shortPath = shortenPath(firstResult.canonicalPath, cwd);
|
|
3959
|
-
resultLines.push(`${import_picocolors4.default.green("\u2713")} ${shortPath}`);
|
|
3960
|
-
} else {
|
|
3961
|
-
resultLines.push(`${import_picocolors4.default.green("\u2713")} ${remoteSkill.installName}`);
|
|
3962
|
-
}
|
|
3963
|
-
} else if (firstResult.mode === "copy") {
|
|
3964
|
-
resultLines.push(`${import_picocolors4.default.green("\u2713")} ${remoteSkill.installName} ${import_picocolors4.default.dim("(copied)")}`);
|
|
3965
|
-
for (const r2 of successful) {
|
|
3966
|
-
const shortPath = shortenPath(r2.path, cwd);
|
|
3967
|
-
resultLines.push(` ${import_picocolors4.default.dim("\u2192")} ${shortPath}`);
|
|
3968
|
-
}
|
|
3969
|
-
} else {
|
|
3970
|
-
if (firstResult.canonicalPath) {
|
|
3971
|
-
const shortPath = shortenPath(firstResult.canonicalPath, cwd);
|
|
3972
|
-
resultLines.push(`${import_picocolors4.default.green("\u2713")} ${shortPath}`);
|
|
3973
|
-
} else {
|
|
3974
|
-
resultLines.push(`${import_picocolors4.default.green("\u2713")} ${remoteSkill.installName}`);
|
|
3975
|
-
}
|
|
3976
|
-
resultLines.push(...buildResultLines(successful, targetAgents));
|
|
3977
|
-
}
|
|
3978
|
-
const title = import_picocolors4.default.green("Installed 1 skill");
|
|
3979
|
-
Me(resultLines.join("\n"), title);
|
|
3980
|
-
if (firstResult.mode === "mcp-server") {
|
|
3981
|
-
M2.message("");
|
|
3982
|
-
M2.message(import_picocolors4.default.dim("To use with MCP clients, add to your MCP config:"));
|
|
3983
|
-
M2.message(import_picocolors4.default.cyan(' { "command": "npx", "args": ["-y", "@codemcp/skills-server"] }'));
|
|
3984
|
-
}
|
|
3985
|
-
const symlinkFailures = successful.filter((r2) => r2.mode === "symlink" && r2.symlinkFailed);
|
|
3986
|
-
if (symlinkFailures.length > 0) {
|
|
3987
|
-
const copiedAgentNames = symlinkFailures.map((r2) => r2.agent);
|
|
3988
|
-
M2.warn(import_picocolors4.default.yellow(`Symlinks failed for: ${formatList(copiedAgentNames)}`));
|
|
3989
|
-
M2.message(
|
|
3990
|
-
import_picocolors4.default.dim(
|
|
3991
|
-
" Files were copied instead. On Windows, enable Developer Mode for symlink support."
|
|
3992
|
-
)
|
|
3993
|
-
);
|
|
3994
|
-
}
|
|
3995
|
-
}
|
|
3996
|
-
if (failed.length > 0) {
|
|
3997
|
-
console.log();
|
|
3998
|
-
M2.error(import_picocolors4.default.red(`Failed to install ${failed.length}`));
|
|
3999
|
-
for (const r2 of failed) {
|
|
4000
|
-
M2.message(` ${import_picocolors4.default.red("\u2717")} ${r2.skill} \u2192 ${r2.agent}: ${import_picocolors4.default.dim(r2.error)}`);
|
|
4001
|
-
}
|
|
4002
|
-
}
|
|
4003
|
-
console.log();
|
|
4004
|
-
Se(
|
|
4005
|
-
import_picocolors4.default.green("Done!") + import_picocolors4.default.dim(" Review skills before use; they run with full agent permissions.")
|
|
4006
|
-
);
|
|
4007
|
-
await promptForFindSkills(options, targetAgents);
|
|
4008
|
-
}
|
|
4009
3496
|
async function handleWellKnownSkills(source, url, options, spinner) {
|
|
4010
3497
|
spinner.start("Discovering skills from well-known endpoint...");
|
|
4011
3498
|
const skills = await wellKnownProvider.fetchAllSkills(url);
|
|
4012
3499
|
if (skills.length === 0) {
|
|
4013
|
-
spinner.stop(
|
|
3500
|
+
spinner.stop(import_picocolors3.default.red("No skills found"));
|
|
4014
3501
|
Se(
|
|
4015
|
-
|
|
3502
|
+
import_picocolors3.default.red(
|
|
4016
3503
|
"No skills found at this URL. Make sure the server has a /.well-known/skills/index.json file."
|
|
4017
3504
|
)
|
|
4018
3505
|
);
|
|
4019
3506
|
process.exit(1);
|
|
4020
3507
|
}
|
|
4021
|
-
spinner.stop(`Found ${
|
|
3508
|
+
spinner.stop(`Found ${import_picocolors3.default.green(skills.length)} skill${skills.length > 1 ? "s" : ""}`);
|
|
4022
3509
|
for (const skill of skills) {
|
|
4023
|
-
M2.info(`Skill: ${
|
|
4024
|
-
M2.message(
|
|
3510
|
+
M2.info(`Skill: ${import_picocolors3.default.cyan(skill.installName)}`);
|
|
3511
|
+
M2.message(import_picocolors3.default.dim(skill.description));
|
|
4025
3512
|
if (skill.files.size > 1) {
|
|
4026
|
-
M2.message(
|
|
3513
|
+
M2.message(import_picocolors3.default.dim(` Files: ${Array.from(skill.files.keys()).join(", ")}`));
|
|
4027
3514
|
}
|
|
4028
3515
|
}
|
|
4029
3516
|
if (options.list) {
|
|
4030
3517
|
console.log();
|
|
4031
|
-
M2.step(
|
|
3518
|
+
M2.step(import_picocolors3.default.bold("Available Skills"));
|
|
4032
3519
|
for (const skill of skills) {
|
|
4033
|
-
M2.message(` ${
|
|
4034
|
-
M2.message(` ${
|
|
3520
|
+
M2.message(` ${import_picocolors3.default.cyan(skill.installName)}`);
|
|
3521
|
+
M2.message(` ${import_picocolors3.default.dim(skill.description)}`);
|
|
4035
3522
|
if (skill.files.size > 1) {
|
|
4036
|
-
M2.message(` ${
|
|
3523
|
+
M2.message(` ${import_picocolors3.default.dim(`Files: ${skill.files.size}`)}`);
|
|
4037
3524
|
}
|
|
4038
3525
|
}
|
|
4039
3526
|
console.log();
|
|
@@ -4061,7 +3548,7 @@ async function handleWellKnownSkills(source, url, options, spinner) {
|
|
|
4061
3548
|
} else if (skills.length === 1) {
|
|
4062
3549
|
selectedSkills = skills;
|
|
4063
3550
|
const firstSkill = skills[0];
|
|
4064
|
-
M2.info(`Skill: ${
|
|
3551
|
+
M2.info(`Skill: ${import_picocolors3.default.cyan(firstSkill.installName)}`);
|
|
4065
3552
|
} else if (options.yes) {
|
|
4066
3553
|
selectedSkills = skills;
|
|
4067
3554
|
M2.info(`Installing all ${skills.length} skills`);
|
|
@@ -4124,10 +3611,10 @@ async function handleWellKnownSkills(source, url, options, spinner) {
|
|
|
4124
3611
|
targetAgents = ensureUniversalAgents(installedAgents);
|
|
4125
3612
|
if (installedAgents.length === 1) {
|
|
4126
3613
|
const firstAgent = installedAgents[0];
|
|
4127
|
-
M2.info(`Installing to: ${
|
|
3614
|
+
M2.info(`Installing to: ${import_picocolors3.default.cyan(agents[firstAgent].displayName)}`);
|
|
4128
3615
|
} else {
|
|
4129
3616
|
M2.info(
|
|
4130
|
-
`Installing to: ${installedAgents.map((a) =>
|
|
3617
|
+
`Installing to: ${installedAgents.map((a) => import_picocolors3.default.cyan(agents[a].displayName)).join(", ")}`
|
|
4131
3618
|
);
|
|
4132
3619
|
}
|
|
4133
3620
|
} else {
|
|
@@ -4187,15 +3674,15 @@ async function handleWellKnownSkills(source, url, options, spinner) {
|
|
|
4187
3674
|
if (summaryLines.length > 0) summaryLines.push("");
|
|
4188
3675
|
const canonicalPath = getCanonicalPath(skill.installName, { global: installGlobally });
|
|
4189
3676
|
const shortCanonical = shortenPath(canonicalPath, cwd);
|
|
4190
|
-
summaryLines.push(`${
|
|
3677
|
+
summaryLines.push(`${import_picocolors3.default.cyan(shortCanonical)}`);
|
|
4191
3678
|
summaryLines.push(...buildAgentSummaryLines(targetAgents, installMode));
|
|
4192
3679
|
if (skill.files.size > 1) {
|
|
4193
|
-
summaryLines.push(` ${
|
|
3680
|
+
summaryLines.push(` ${import_picocolors3.default.dim("files:")} ${skill.files.size}`);
|
|
4194
3681
|
}
|
|
4195
3682
|
const skillOverwrites = overwriteStatus.get(skill.installName);
|
|
4196
3683
|
const overwriteAgents = targetAgents.filter((a) => skillOverwrites?.get(a)).map((a) => agents[a].displayName);
|
|
4197
3684
|
if (overwriteAgents.length > 0) {
|
|
4198
|
-
summaryLines.push(` ${
|
|
3685
|
+
summaryLines.push(` ${import_picocolors3.default.yellow("overwrites:")} ${formatList(overwriteAgents)}`);
|
|
4199
3686
|
}
|
|
4200
3687
|
}
|
|
4201
3688
|
console.log();
|
|
@@ -4298,27 +3785,27 @@ async function handleWellKnownSkills(source, url, options, spinner) {
|
|
|
4298
3785
|
for (const [skillName, skillResults] of bySkill) {
|
|
4299
3786
|
const firstResult = skillResults[0];
|
|
4300
3787
|
if (firstResult.mode === "copy") {
|
|
4301
|
-
resultLines.push(`${
|
|
3788
|
+
resultLines.push(`${import_picocolors3.default.green("\u2713")} ${skillName} ${import_picocolors3.default.dim("(copied)")}`);
|
|
4302
3789
|
for (const r2 of skillResults) {
|
|
4303
3790
|
const shortPath = shortenPath(r2.path, cwd);
|
|
4304
|
-
resultLines.push(` ${
|
|
3791
|
+
resultLines.push(` ${import_picocolors3.default.dim("\u2192")} ${shortPath}`);
|
|
4305
3792
|
}
|
|
4306
3793
|
} else {
|
|
4307
3794
|
if (firstResult.canonicalPath) {
|
|
4308
3795
|
const shortPath = shortenPath(firstResult.canonicalPath, cwd);
|
|
4309
|
-
resultLines.push(`${
|
|
3796
|
+
resultLines.push(`${import_picocolors3.default.green("\u2713")} ${shortPath}`);
|
|
4310
3797
|
} else {
|
|
4311
|
-
resultLines.push(`${
|
|
3798
|
+
resultLines.push(`${import_picocolors3.default.green("\u2713")} ${skillName}`);
|
|
4312
3799
|
}
|
|
4313
3800
|
resultLines.push(...buildResultLines(skillResults, targetAgents));
|
|
4314
3801
|
}
|
|
4315
3802
|
}
|
|
4316
|
-
const title =
|
|
3803
|
+
const title = import_picocolors3.default.green(`Installed ${skillCount} skill${skillCount !== 1 ? "s" : ""}`);
|
|
4317
3804
|
Me(resultLines.join("\n"), title);
|
|
4318
3805
|
if (symlinkFailures.length > 0) {
|
|
4319
|
-
M2.warn(
|
|
3806
|
+
M2.warn(import_picocolors3.default.yellow(`Symlinks failed for: ${formatList(copiedAgents)}`));
|
|
4320
3807
|
M2.message(
|
|
4321
|
-
|
|
3808
|
+
import_picocolors3.default.dim(
|
|
4322
3809
|
" Files were copied instead. On Windows, enable Developer Mode for symlink support."
|
|
4323
3810
|
)
|
|
4324
3811
|
);
|
|
@@ -4326,249 +3813,14 @@ async function handleWellKnownSkills(source, url, options, spinner) {
|
|
|
4326
3813
|
}
|
|
4327
3814
|
if (failed.length > 0) {
|
|
4328
3815
|
console.log();
|
|
4329
|
-
M2.error(
|
|
3816
|
+
M2.error(import_picocolors3.default.red(`Failed to install ${failed.length}`));
|
|
4330
3817
|
for (const r2 of failed) {
|
|
4331
|
-
M2.message(` ${
|
|
3818
|
+
M2.message(` ${import_picocolors3.default.red("\u2717")} ${r2.skill} \u2192 ${r2.agent}: ${import_picocolors3.default.dim(r2.error)}`);
|
|
4332
3819
|
}
|
|
4333
3820
|
}
|
|
4334
3821
|
console.log();
|
|
4335
3822
|
Se(
|
|
4336
|
-
|
|
4337
|
-
);
|
|
4338
|
-
await promptForFindSkills(options, targetAgents);
|
|
4339
|
-
}
|
|
4340
|
-
async function handleDirectUrlSkillLegacy(source, url, options, spinner) {
|
|
4341
|
-
spinner.start("Fetching skill.md...");
|
|
4342
|
-
const mintlifySkill = await fetchMintlifySkill(url);
|
|
4343
|
-
if (!mintlifySkill) {
|
|
4344
|
-
spinner.stop(import_picocolors4.default.red("Invalid skill"));
|
|
4345
|
-
Se(
|
|
4346
|
-
import_picocolors4.default.red(
|
|
4347
|
-
"Could not fetch skill.md or missing required frontmatter (name, description, mintlify-proj)."
|
|
4348
|
-
)
|
|
4349
|
-
);
|
|
4350
|
-
process.exit(1);
|
|
4351
|
-
}
|
|
4352
|
-
const remoteSkill = {
|
|
4353
|
-
name: mintlifySkill.name,
|
|
4354
|
-
description: mintlifySkill.description,
|
|
4355
|
-
content: mintlifySkill.content,
|
|
4356
|
-
installName: mintlifySkill.mintlifySite,
|
|
4357
|
-
sourceUrl: mintlifySkill.sourceUrl,
|
|
4358
|
-
providerId: "mintlify",
|
|
4359
|
-
sourceIdentifier: "mintlify/com"
|
|
4360
|
-
};
|
|
4361
|
-
spinner.stop(`Found skill: ${import_picocolors4.default.cyan(remoteSkill.installName)}`);
|
|
4362
|
-
M2.info(`Skill: ${import_picocolors4.default.cyan(remoteSkill.name)}`);
|
|
4363
|
-
M2.message(import_picocolors4.default.dim(remoteSkill.description));
|
|
4364
|
-
if (options.list) {
|
|
4365
|
-
console.log();
|
|
4366
|
-
M2.step(import_picocolors4.default.bold("Skill Details"));
|
|
4367
|
-
M2.message(` ${import_picocolors4.default.cyan("Name:")} ${remoteSkill.name}`);
|
|
4368
|
-
M2.message(` ${import_picocolors4.default.cyan("Site:")} ${remoteSkill.installName}`);
|
|
4369
|
-
M2.message(` ${import_picocolors4.default.cyan("Description:")} ${remoteSkill.description}`);
|
|
4370
|
-
console.log();
|
|
4371
|
-
Se("Run without --list to install");
|
|
4372
|
-
process.exit(0);
|
|
4373
|
-
}
|
|
4374
|
-
let targetAgents;
|
|
4375
|
-
const validAgents = Object.keys(agents);
|
|
4376
|
-
if (options.agent?.includes("*")) {
|
|
4377
|
-
targetAgents = validAgents;
|
|
4378
|
-
M2.info(`Installing to all ${targetAgents.length} agents`);
|
|
4379
|
-
} else if (options.agent && options.agent.length > 0) {
|
|
4380
|
-
const invalidAgents = options.agent.filter((a) => !validAgents.includes(a));
|
|
4381
|
-
if (invalidAgents.length > 0) {
|
|
4382
|
-
M2.error(`Invalid agents: ${invalidAgents.join(", ")}`);
|
|
4383
|
-
M2.info(`Valid agents: ${validAgents.join(", ")}`);
|
|
4384
|
-
process.exit(1);
|
|
4385
|
-
}
|
|
4386
|
-
targetAgents = options.agent;
|
|
4387
|
-
} else {
|
|
4388
|
-
spinner.start("Loading agents...");
|
|
4389
|
-
const installedAgents = await detectInstalledAgents();
|
|
4390
|
-
const totalAgents = Object.keys(agents).length;
|
|
4391
|
-
spinner.stop(`${totalAgents} agents`);
|
|
4392
|
-
if (installedAgents.length === 0) {
|
|
4393
|
-
if (options.yes) {
|
|
4394
|
-
targetAgents = validAgents;
|
|
4395
|
-
M2.info("Installing to all agents");
|
|
4396
|
-
} else {
|
|
4397
|
-
M2.info("Select agents to install skills to");
|
|
4398
|
-
const allAgentChoices = Object.entries(agents).map(([key, config]) => ({
|
|
4399
|
-
value: key,
|
|
4400
|
-
label: config.displayName
|
|
4401
|
-
}));
|
|
4402
|
-
const selected = await promptForAgents(
|
|
4403
|
-
"Which agents do you want to install to?",
|
|
4404
|
-
allAgentChoices
|
|
4405
|
-
);
|
|
4406
|
-
if (pD(selected)) {
|
|
4407
|
-
xe("Installation cancelled");
|
|
4408
|
-
process.exit(0);
|
|
4409
|
-
}
|
|
4410
|
-
targetAgents = selected;
|
|
4411
|
-
}
|
|
4412
|
-
} else if (installedAgents.length === 1 || options.yes) {
|
|
4413
|
-
targetAgents = ensureUniversalAgents(installedAgents);
|
|
4414
|
-
if (installedAgents.length === 1) {
|
|
4415
|
-
const firstAgent = installedAgents[0];
|
|
4416
|
-
M2.info(`Installing to: ${import_picocolors4.default.cyan(agents[firstAgent].displayName)}`);
|
|
4417
|
-
} else {
|
|
4418
|
-
M2.info(
|
|
4419
|
-
`Installing to: ${installedAgents.map((a) => import_picocolors4.default.cyan(agents[a].displayName)).join(", ")}`
|
|
4420
|
-
);
|
|
4421
|
-
}
|
|
4422
|
-
} else {
|
|
4423
|
-
const selected = await selectAgentsInteractive({ global: options.global });
|
|
4424
|
-
if (pD(selected)) {
|
|
4425
|
-
xe("Installation cancelled");
|
|
4426
|
-
process.exit(0);
|
|
4427
|
-
}
|
|
4428
|
-
targetAgents = selected;
|
|
4429
|
-
}
|
|
4430
|
-
}
|
|
4431
|
-
let installGlobally = options.global ?? false;
|
|
4432
|
-
const supportsGlobal = targetAgents.some((a) => agents[a].globalSkillsDir !== void 0);
|
|
4433
|
-
if (options.global === void 0 && !options.yes && supportsGlobal) {
|
|
4434
|
-
const scope = await ve({
|
|
4435
|
-
message: "Installation scope",
|
|
4436
|
-
options: [
|
|
4437
|
-
{
|
|
4438
|
-
value: false,
|
|
4439
|
-
label: "Project",
|
|
4440
|
-
hint: "Install in current directory (committed with your project)"
|
|
4441
|
-
},
|
|
4442
|
-
{
|
|
4443
|
-
value: true,
|
|
4444
|
-
label: "Global",
|
|
4445
|
-
hint: "Install in home directory (available across all projects)"
|
|
4446
|
-
}
|
|
4447
|
-
]
|
|
4448
|
-
});
|
|
4449
|
-
if (pD(scope)) {
|
|
4450
|
-
xe("Installation cancelled");
|
|
4451
|
-
process.exit(0);
|
|
4452
|
-
}
|
|
4453
|
-
installGlobally = scope;
|
|
4454
|
-
}
|
|
4455
|
-
const installMode = "symlink";
|
|
4456
|
-
const cwd = process.cwd();
|
|
4457
|
-
const overwriteChecks = await Promise.all(
|
|
4458
|
-
targetAgents.map(async (agent) => ({
|
|
4459
|
-
agent,
|
|
4460
|
-
installed: await isSkillInstalled(remoteSkill.installName, agent, {
|
|
4461
|
-
global: installGlobally
|
|
4462
|
-
})
|
|
4463
|
-
}))
|
|
4464
|
-
);
|
|
4465
|
-
const overwriteStatus = new Map(
|
|
4466
|
-
overwriteChecks.map(({ agent, installed }) => [agent, installed])
|
|
4467
|
-
);
|
|
4468
|
-
const summaryLines = [];
|
|
4469
|
-
const agentNames = targetAgents.map((a) => agents[a].displayName);
|
|
4470
|
-
const canonicalPath = getCanonicalPath(remoteSkill.installName, { global: installGlobally });
|
|
4471
|
-
const shortCanonical = shortenPath(canonicalPath, cwd);
|
|
4472
|
-
summaryLines.push(`${import_picocolors4.default.cyan(shortCanonical)}`);
|
|
4473
|
-
summaryLines.push(...buildAgentSummaryLines(targetAgents, installMode));
|
|
4474
|
-
const overwriteAgents = targetAgents.filter((a) => overwriteStatus.get(a)).map((a) => agents[a].displayName);
|
|
4475
|
-
if (overwriteAgents.length > 0) {
|
|
4476
|
-
summaryLines.push(` ${import_picocolors4.default.yellow("overwrites:")} ${formatList(overwriteAgents)}`);
|
|
4477
|
-
}
|
|
4478
|
-
console.log();
|
|
4479
|
-
Me(summaryLines.join("\n"), "Installation Summary");
|
|
4480
|
-
if (!options.yes) {
|
|
4481
|
-
const confirmed = await ye({
|
|
4482
|
-
message: "Proceed with installation?"
|
|
4483
|
-
});
|
|
4484
|
-
if (pD(confirmed) || !confirmed) {
|
|
4485
|
-
xe("Installation cancelled");
|
|
4486
|
-
process.exit(0);
|
|
4487
|
-
}
|
|
4488
|
-
}
|
|
4489
|
-
spinner.start("Installing skill...");
|
|
4490
|
-
const results = [];
|
|
4491
|
-
if (installMode === "mcp-server") {
|
|
4492
|
-
const result = await installRemoteSkillForAgent(remoteSkill, "universal", {
|
|
4493
|
-
global: installGlobally,
|
|
4494
|
-
mode: installMode
|
|
4495
|
-
});
|
|
4496
|
-
results.push({
|
|
4497
|
-
skill: remoteSkill.installName,
|
|
4498
|
-
agent: "MCP Server",
|
|
4499
|
-
...result
|
|
4500
|
-
});
|
|
4501
|
-
} else {
|
|
4502
|
-
for (const agent of targetAgents) {
|
|
4503
|
-
const result = await installRemoteSkillForAgent(remoteSkill, agent, {
|
|
4504
|
-
global: installGlobally,
|
|
4505
|
-
mode: installMode
|
|
4506
|
-
});
|
|
4507
|
-
results.push({
|
|
4508
|
-
skill: remoteSkill.installName,
|
|
4509
|
-
agent: agents[agent].displayName,
|
|
4510
|
-
...result
|
|
4511
|
-
});
|
|
4512
|
-
}
|
|
4513
|
-
}
|
|
4514
|
-
spinner.stop("Installation complete");
|
|
4515
|
-
console.log();
|
|
4516
|
-
const successful = results.filter((r2) => r2.success);
|
|
4517
|
-
const failed = results.filter((r2) => !r2.success);
|
|
4518
|
-
track({
|
|
4519
|
-
event: "install",
|
|
4520
|
-
source: "mintlify/com",
|
|
4521
|
-
skills: remoteSkill.installName,
|
|
4522
|
-
agents: targetAgents.join(","),
|
|
4523
|
-
...installGlobally && { global: "1" },
|
|
4524
|
-
skillFiles: JSON.stringify({ [remoteSkill.installName]: url }),
|
|
4525
|
-
sourceType: "mintlify"
|
|
4526
|
-
});
|
|
4527
|
-
if (successful.length > 0 && installGlobally) {
|
|
4528
|
-
try {
|
|
4529
|
-
await addSkillToLock(remoteSkill.installName, {
|
|
4530
|
-
source: `mintlify/${remoteSkill.installName}`,
|
|
4531
|
-
sourceType: "mintlify",
|
|
4532
|
-
sourceUrl: url,
|
|
4533
|
-
skillFolderHash: ""
|
|
4534
|
-
// Populated by server
|
|
4535
|
-
});
|
|
4536
|
-
} catch {
|
|
4537
|
-
}
|
|
4538
|
-
}
|
|
4539
|
-
if (successful.length > 0) {
|
|
4540
|
-
const resultLines = [];
|
|
4541
|
-
const firstResult = successful[0];
|
|
4542
|
-
if (firstResult.canonicalPath) {
|
|
4543
|
-
const shortPath = shortenPath(firstResult.canonicalPath, cwd);
|
|
4544
|
-
resultLines.push(`${import_picocolors4.default.green("\u2713")} ${shortPath}`);
|
|
4545
|
-
} else {
|
|
4546
|
-
resultLines.push(`${import_picocolors4.default.green("\u2713")} ${remoteSkill.installName}`);
|
|
4547
|
-
}
|
|
4548
|
-
resultLines.push(...buildResultLines(successful, targetAgents));
|
|
4549
|
-
const title = import_picocolors4.default.green("Installed 1 skill");
|
|
4550
|
-
Me(resultLines.join("\n"), title);
|
|
4551
|
-
const symlinkFailures = successful.filter((r2) => r2.mode === "symlink" && r2.symlinkFailed);
|
|
4552
|
-
if (symlinkFailures.length > 0) {
|
|
4553
|
-
const copiedAgentNames = symlinkFailures.map((r2) => r2.agent);
|
|
4554
|
-
M2.warn(import_picocolors4.default.yellow(`Symlinks failed for: ${formatList(copiedAgentNames)}`));
|
|
4555
|
-
M2.message(
|
|
4556
|
-
import_picocolors4.default.dim(
|
|
4557
|
-
" Files were copied instead. On Windows, enable Developer Mode for symlink support."
|
|
4558
|
-
)
|
|
4559
|
-
);
|
|
4560
|
-
}
|
|
4561
|
-
}
|
|
4562
|
-
if (failed.length > 0) {
|
|
4563
|
-
console.log();
|
|
4564
|
-
M2.error(import_picocolors4.default.red(`Failed to install ${failed.length}`));
|
|
4565
|
-
for (const r2 of failed) {
|
|
4566
|
-
M2.message(` ${import_picocolors4.default.red("\u2717")} ${r2.skill} \u2192 ${r2.agent}: ${import_picocolors4.default.dim(r2.error)}`);
|
|
4567
|
-
}
|
|
4568
|
-
}
|
|
4569
|
-
console.log();
|
|
4570
|
-
Se(
|
|
4571
|
-
import_picocolors4.default.green("Done!") + import_picocolors4.default.dim(" Review skills before use; they run with full agent permissions.")
|
|
3823
|
+
import_picocolors3.default.green("Done!") + import_picocolors3.default.dim(" Review skills before use; they run with full agent permissions.")
|
|
4572
3824
|
);
|
|
4573
3825
|
await promptForFindSkills(options, targetAgents);
|
|
4574
3826
|
}
|
|
@@ -4578,24 +3830,24 @@ async function runAdd(args, options = {}) {
|
|
|
4578
3830
|
const showInstallTip = () => {
|
|
4579
3831
|
if (installTipShown) return;
|
|
4580
3832
|
M2.message(
|
|
4581
|
-
|
|
3833
|
+
import_picocolors3.default.dim("Tip: use the --yes (-y) and --global (-g) flags to install without prompts.")
|
|
4582
3834
|
);
|
|
4583
3835
|
installTipShown = true;
|
|
4584
3836
|
};
|
|
4585
3837
|
if (!source) {
|
|
4586
3838
|
console.log();
|
|
4587
3839
|
console.log(
|
|
4588
|
-
|
|
3840
|
+
import_picocolors3.default.bgRed(import_picocolors3.default.white(import_picocolors3.default.bold(" ERROR "))) + " " + import_picocolors3.default.red("Missing required argument: source")
|
|
4589
3841
|
);
|
|
4590
3842
|
console.log();
|
|
4591
|
-
console.log(
|
|
3843
|
+
console.log(import_picocolors3.default.dim(" Usage:"));
|
|
4592
3844
|
console.log(
|
|
4593
|
-
` ${
|
|
3845
|
+
` ${import_picocolors3.default.cyan("npx @codemcp/skills add")} ${import_picocolors3.default.yellow("<source>")} ${import_picocolors3.default.dim("[options]")}`
|
|
4594
3846
|
);
|
|
4595
3847
|
console.log();
|
|
4596
|
-
console.log(
|
|
3848
|
+
console.log(import_picocolors3.default.dim(" Example:"));
|
|
4597
3849
|
console.log(
|
|
4598
|
-
` ${
|
|
3850
|
+
` ${import_picocolors3.default.cyan("npx @codemcp/skills add")} ${import_picocolors3.default.yellow("vercel-labs/agent-skills")}`
|
|
4599
3851
|
);
|
|
4600
3852
|
console.log();
|
|
4601
3853
|
process.exit(1);
|
|
@@ -4606,7 +3858,7 @@ async function runAdd(args, options = {}) {
|
|
|
4606
3858
|
options.yes = true;
|
|
4607
3859
|
}
|
|
4608
3860
|
console.log();
|
|
4609
|
-
Ie(
|
|
3861
|
+
Ie(import_picocolors3.default.bgCyan(import_picocolors3.default.black(" skills ")));
|
|
4610
3862
|
if (!process.stdin.isTTY) {
|
|
4611
3863
|
showInstallTip();
|
|
4612
3864
|
}
|
|
@@ -4616,12 +3868,8 @@ async function runAdd(args, options = {}) {
|
|
|
4616
3868
|
spinner.start("Parsing source...");
|
|
4617
3869
|
const parsed = parseSource(source);
|
|
4618
3870
|
spinner.stop(
|
|
4619
|
-
`Source: ${parsed.type === "local" ? parsed.localPath : parsed.url}${parsed.ref ? ` @ ${
|
|
3871
|
+
`Source: ${parsed.type === "local" ? parsed.localPath : parsed.url}${parsed.ref ? ` @ ${import_picocolors3.default.yellow(parsed.ref)}` : ""}${parsed.subpath ? ` (${parsed.subpath})` : ""}${parsed.skillFilter ? ` ${import_picocolors3.default.dim("@")}${import_picocolors3.default.cyan(parsed.skillFilter)}` : ""}`
|
|
4620
3872
|
);
|
|
4621
|
-
if (parsed.type === "direct-url") {
|
|
4622
|
-
await handleRemoteSkill(source, parsed.url, options, spinner);
|
|
4623
|
-
return;
|
|
4624
|
-
}
|
|
4625
3873
|
if (parsed.type === "well-known") {
|
|
4626
3874
|
await handleWellKnownSkills(source, parsed.url, options, spinner);
|
|
4627
3875
|
return;
|
|
@@ -4630,8 +3878,8 @@ async function runAdd(args, options = {}) {
|
|
|
4630
3878
|
if (parsed.type === "local") {
|
|
4631
3879
|
spinner.start("Validating local path...");
|
|
4632
3880
|
if (!existsSync2(parsed.localPath)) {
|
|
4633
|
-
spinner.stop(
|
|
4634
|
-
Se(
|
|
3881
|
+
spinner.stop(import_picocolors3.default.red("Path not found"));
|
|
3882
|
+
Se(import_picocolors3.default.red(`Local path does not exist: ${parsed.localPath}`));
|
|
4635
3883
|
process.exit(1);
|
|
4636
3884
|
}
|
|
4637
3885
|
skillsDir = parsed.localPath;
|
|
@@ -4655,17 +3903,17 @@ async function runAdd(args, options = {}) {
|
|
|
4655
3903
|
fullDepth: options.fullDepth
|
|
4656
3904
|
});
|
|
4657
3905
|
if (skills.length === 0) {
|
|
4658
|
-
spinner.stop(
|
|
3906
|
+
spinner.stop(import_picocolors3.default.red("No skills found"));
|
|
4659
3907
|
Se(
|
|
4660
|
-
|
|
3908
|
+
import_picocolors3.default.red("No valid skills found. Skills require a SKILL.md with name and description.")
|
|
4661
3909
|
);
|
|
4662
3910
|
await cleanup(tempDir);
|
|
4663
3911
|
process.exit(1);
|
|
4664
3912
|
}
|
|
4665
|
-
spinner.stop(`Found ${
|
|
3913
|
+
spinner.stop(`Found ${import_picocolors3.default.green(skills.length)} skill${skills.length > 1 ? "s" : ""}`);
|
|
4666
3914
|
if (options.list) {
|
|
4667
3915
|
console.log();
|
|
4668
|
-
M2.step(
|
|
3916
|
+
M2.step(import_picocolors3.default.bold("Available Skills"));
|
|
4669
3917
|
const groupedSkills = {};
|
|
4670
3918
|
const ungroupedSkills = [];
|
|
4671
3919
|
for (const skill of skills) {
|
|
@@ -4680,18 +3928,18 @@ async function runAdd(args, options = {}) {
|
|
|
4680
3928
|
const sortedGroups2 = Object.keys(groupedSkills).sort();
|
|
4681
3929
|
for (const group of sortedGroups2) {
|
|
4682
3930
|
const title = group.split("-").map((w2) => w2.charAt(0).toUpperCase() + w2.slice(1)).join(" ");
|
|
4683
|
-
console.log(
|
|
3931
|
+
console.log(import_picocolors3.default.bold(title));
|
|
4684
3932
|
for (const skill of groupedSkills[group]) {
|
|
4685
|
-
M2.message(` ${
|
|
4686
|
-
M2.message(` ${
|
|
3933
|
+
M2.message(` ${import_picocolors3.default.cyan(getSkillDisplayName(skill))}`);
|
|
3934
|
+
M2.message(` ${import_picocolors3.default.dim(skill.description)}`);
|
|
4687
3935
|
}
|
|
4688
3936
|
console.log();
|
|
4689
3937
|
}
|
|
4690
3938
|
if (ungroupedSkills.length > 0) {
|
|
4691
|
-
if (sortedGroups2.length > 0) console.log(
|
|
3939
|
+
if (sortedGroups2.length > 0) console.log(import_picocolors3.default.bold("General"));
|
|
4692
3940
|
for (const skill of ungroupedSkills) {
|
|
4693
|
-
M2.message(` ${
|
|
4694
|
-
M2.message(` ${
|
|
3941
|
+
M2.message(` ${import_picocolors3.default.cyan(getSkillDisplayName(skill))}`);
|
|
3942
|
+
M2.message(` ${import_picocolors3.default.dim(skill.description)}`);
|
|
4695
3943
|
}
|
|
4696
3944
|
}
|
|
4697
3945
|
console.log();
|
|
@@ -4715,13 +3963,13 @@ async function runAdd(args, options = {}) {
|
|
|
4715
3963
|
process.exit(1);
|
|
4716
3964
|
}
|
|
4717
3965
|
M2.info(
|
|
4718
|
-
`Selected ${selectedSkills.length} skill${selectedSkills.length !== 1 ? "s" : ""}: ${selectedSkills.map((s) =>
|
|
3966
|
+
`Selected ${selectedSkills.length} skill${selectedSkills.length !== 1 ? "s" : ""}: ${selectedSkills.map((s) => import_picocolors3.default.cyan(getSkillDisplayName(s))).join(", ")}`
|
|
4719
3967
|
);
|
|
4720
3968
|
} else if (skills.length === 1) {
|
|
4721
3969
|
selectedSkills = skills;
|
|
4722
3970
|
const firstSkill = skills[0];
|
|
4723
|
-
M2.info(`Skill: ${
|
|
4724
|
-
M2.message(
|
|
3971
|
+
M2.info(`Skill: ${import_picocolors3.default.cyan(getSkillDisplayName(firstSkill))}`);
|
|
3972
|
+
M2.message(import_picocolors3.default.dim(firstSkill.description));
|
|
4725
3973
|
} else if (options.yes) {
|
|
4726
3974
|
selectedSkills = skills;
|
|
4727
3975
|
M2.info(`Installing all ${skills.length} skills`);
|
|
@@ -4749,7 +3997,7 @@ async function runAdd(args, options = {}) {
|
|
|
4749
3997
|
});
|
|
4750
3998
|
}
|
|
4751
3999
|
selected = await be({
|
|
4752
|
-
message: `Select skills to install ${
|
|
4000
|
+
message: `Select skills to install ${import_picocolors3.default.dim("(space to toggle)")}`,
|
|
4753
4001
|
options: grouped,
|
|
4754
4002
|
required: true
|
|
4755
4003
|
});
|
|
@@ -4839,12 +4087,12 @@ async function runAdd(args, options = {}) {
|
|
|
4839
4087
|
if (summaryLines.length > 0) summaryLines.push("");
|
|
4840
4088
|
const canonicalPath = getCanonicalPath(skill.name, { global: installGlobally });
|
|
4841
4089
|
const shortCanonical = shortenPath(canonicalPath, cwd);
|
|
4842
|
-
summaryLines.push(`${
|
|
4090
|
+
summaryLines.push(`${import_picocolors3.default.cyan(shortCanonical)}`);
|
|
4843
4091
|
summaryLines.push(...buildAgentSummaryLines(targetAgents, installMode));
|
|
4844
4092
|
const skillOverwrites = overwriteStatus.get(skill.name);
|
|
4845
4093
|
const overwriteAgents = targetAgents.filter((a) => skillOverwrites?.get(a)).map((a) => agents[a].displayName);
|
|
4846
4094
|
if (overwriteAgents.length > 0) {
|
|
4847
|
-
summaryLines.push(` ${
|
|
4095
|
+
summaryLines.push(` ${import_picocolors3.default.yellow("overwrites:")} ${formatList(overwriteAgents)}`);
|
|
4848
4096
|
}
|
|
4849
4097
|
}
|
|
4850
4098
|
};
|
|
@@ -4852,13 +4100,13 @@ async function runAdd(args, options = {}) {
|
|
|
4852
4100
|
for (const group of sortedGroups) {
|
|
4853
4101
|
const title = group.split("-").map((w2) => w2.charAt(0).toUpperCase() + w2.slice(1)).join(" ");
|
|
4854
4102
|
summaryLines.push("");
|
|
4855
|
-
summaryLines.push(
|
|
4103
|
+
summaryLines.push(import_picocolors3.default.bold(title));
|
|
4856
4104
|
printSkillSummary(groupedSummary[group]);
|
|
4857
4105
|
}
|
|
4858
4106
|
if (ungroupedSummary.length > 0) {
|
|
4859
4107
|
if (sortedGroups.length > 0) {
|
|
4860
4108
|
summaryLines.push("");
|
|
4861
|
-
summaryLines.push(
|
|
4109
|
+
summaryLines.push(import_picocolors3.default.bold("General"));
|
|
4862
4110
|
}
|
|
4863
4111
|
printSkillSummary(ungroupedSummary);
|
|
4864
4112
|
}
|
|
@@ -4914,14 +4162,16 @@ async function runAdd(args, options = {}) {
|
|
|
4914
4162
|
let relativePath;
|
|
4915
4163
|
if (tempDir && skill.path === tempDir) {
|
|
4916
4164
|
relativePath = "SKILL.md";
|
|
4917
|
-
} else if (tempDir && skill.path.startsWith(tempDir +
|
|
4918
|
-
relativePath = skill.path.slice(tempDir.length + 1).split(
|
|
4165
|
+
} else if (tempDir && skill.path.startsWith(tempDir + sep5)) {
|
|
4166
|
+
relativePath = skill.path.slice(tempDir.length + 1).split(sep5).join("/") + "/SKILL.md";
|
|
4919
4167
|
} else {
|
|
4920
4168
|
continue;
|
|
4921
4169
|
}
|
|
4922
4170
|
skillFiles[skill.name] = relativePath;
|
|
4923
4171
|
}
|
|
4924
4172
|
const normalizedSource = getOwnerRepo(parsed);
|
|
4173
|
+
const isSSH = parsed.url.startsWith("git@");
|
|
4174
|
+
const lockSource = isSSH ? parsed.url : normalizedSource;
|
|
4925
4175
|
if (normalizedSource) {
|
|
4926
4176
|
const ownerRepo = parseOwnerRepo(normalizedSource);
|
|
4927
4177
|
if (ownerRepo) {
|
|
@@ -4956,11 +4206,12 @@ async function runAdd(args, options = {}) {
|
|
|
4956
4206
|
let skillFolderHash = "";
|
|
4957
4207
|
const skillPathValue = skillFiles[skill.name];
|
|
4958
4208
|
if (parsed.type === "github" && skillPathValue) {
|
|
4959
|
-
const
|
|
4209
|
+
const token = getGitHubToken();
|
|
4210
|
+
const hash = await fetchSkillFolderHash(normalizedSource, skillPathValue, token);
|
|
4960
4211
|
if (hash) skillFolderHash = hash;
|
|
4961
4212
|
}
|
|
4962
4213
|
await addSkillToLock(skill.name, {
|
|
4963
|
-
source: normalizedSource,
|
|
4214
|
+
source: lockSource || normalizedSource,
|
|
4964
4215
|
sourceType: parsed.type,
|
|
4965
4216
|
sourceUrl: parsed.url,
|
|
4966
4217
|
skillPath: skillPathValue,
|
|
@@ -4982,7 +4233,7 @@ async function runAdd(args, options = {}) {
|
|
|
4982
4233
|
await addSkillToLocalLock(
|
|
4983
4234
|
skill.name,
|
|
4984
4235
|
{
|
|
4985
|
-
source:
|
|
4236
|
+
source: lockSource || parsed.url,
|
|
4986
4237
|
sourceType: parsed.type,
|
|
4987
4238
|
computedHash
|
|
4988
4239
|
},
|
|
@@ -5020,17 +4271,17 @@ async function runAdd(args, options = {}) {
|
|
|
5020
4271
|
const skillResults = bySkill.get(entry.skill) || [];
|
|
5021
4272
|
const firstResult = skillResults[0];
|
|
5022
4273
|
if (firstResult.mode === "copy") {
|
|
5023
|
-
resultLines.push(`${
|
|
4274
|
+
resultLines.push(`${import_picocolors3.default.green("\u2713")} ${entry.skill} ${import_picocolors3.default.dim("(copied)")}`);
|
|
5024
4275
|
for (const r2 of skillResults) {
|
|
5025
4276
|
const shortPath = shortenPath(r2.path, cwd);
|
|
5026
|
-
resultLines.push(` ${
|
|
4277
|
+
resultLines.push(` ${import_picocolors3.default.dim("\u2192")} ${shortPath}`);
|
|
5027
4278
|
}
|
|
5028
4279
|
} else {
|
|
5029
4280
|
if (firstResult.canonicalPath) {
|
|
5030
4281
|
const shortPath = shortenPath(firstResult.canonicalPath, cwd);
|
|
5031
|
-
resultLines.push(`${
|
|
4282
|
+
resultLines.push(`${import_picocolors3.default.green("\u2713")} ${shortPath}`);
|
|
5032
4283
|
} else {
|
|
5033
|
-
resultLines.push(`${
|
|
4284
|
+
resultLines.push(`${import_picocolors3.default.green("\u2713")} ${entry.skill}`);
|
|
5034
4285
|
}
|
|
5035
4286
|
resultLines.push(...buildResultLines(skillResults, targetAgents));
|
|
5036
4287
|
}
|
|
@@ -5040,22 +4291,22 @@ async function runAdd(args, options = {}) {
|
|
|
5040
4291
|
for (const group of sortedResultGroups) {
|
|
5041
4292
|
const title2 = group.split("-").map((w2) => w2.charAt(0).toUpperCase() + w2.slice(1)).join(" ");
|
|
5042
4293
|
resultLines.push("");
|
|
5043
|
-
resultLines.push(
|
|
4294
|
+
resultLines.push(import_picocolors3.default.bold(title2));
|
|
5044
4295
|
printSkillResults(groupedResults[group]);
|
|
5045
4296
|
}
|
|
5046
4297
|
if (ungroupedResults.length > 0) {
|
|
5047
4298
|
if (sortedResultGroups.length > 0) {
|
|
5048
4299
|
resultLines.push("");
|
|
5049
|
-
resultLines.push(
|
|
4300
|
+
resultLines.push(import_picocolors3.default.bold("General"));
|
|
5050
4301
|
}
|
|
5051
4302
|
printSkillResults(ungroupedResults);
|
|
5052
4303
|
}
|
|
5053
|
-
const title =
|
|
4304
|
+
const title = import_picocolors3.default.green(`Installed ${skillCount} skill${skillCount !== 1 ? "s" : ""}`);
|
|
5054
4305
|
Me(resultLines.join("\n"), title);
|
|
5055
4306
|
if (symlinkFailures.length > 0) {
|
|
5056
|
-
M2.warn(
|
|
4307
|
+
M2.warn(import_picocolors3.default.yellow(`Symlinks failed for: ${formatList(copiedAgents)}`));
|
|
5057
4308
|
M2.message(
|
|
5058
|
-
|
|
4309
|
+
import_picocolors3.default.dim(
|
|
5059
4310
|
" Files were copied instead. On Windows, enable Developer Mode for symlink support."
|
|
5060
4311
|
)
|
|
5061
4312
|
);
|
|
@@ -5063,27 +4314,27 @@ async function runAdd(args, options = {}) {
|
|
|
5063
4314
|
}
|
|
5064
4315
|
if (failed.length > 0) {
|
|
5065
4316
|
console.log();
|
|
5066
|
-
M2.error(
|
|
4317
|
+
M2.error(import_picocolors3.default.red(`Failed to install ${failed.length}`));
|
|
5067
4318
|
for (const r2 of failed) {
|
|
5068
|
-
M2.message(` ${
|
|
4319
|
+
M2.message(` ${import_picocolors3.default.red("\u2717")} ${r2.skill} \u2192 ${r2.agent}: ${import_picocolors3.default.dim(r2.error)}`);
|
|
5069
4320
|
}
|
|
5070
4321
|
}
|
|
5071
4322
|
console.log();
|
|
5072
4323
|
Se(
|
|
5073
|
-
|
|
4324
|
+
import_picocolors3.default.green("Done!") + import_picocolors3.default.dim(" Review skills before use; they run with full agent permissions.")
|
|
5074
4325
|
);
|
|
5075
4326
|
await promptForFindSkills(options, targetAgents);
|
|
5076
4327
|
} catch (error) {
|
|
5077
4328
|
if (error instanceof GitCloneError) {
|
|
5078
|
-
M2.error(
|
|
4329
|
+
M2.error(import_picocolors3.default.red("Failed to clone repository"));
|
|
5079
4330
|
for (const line of error.message.split("\n")) {
|
|
5080
|
-
M2.message(
|
|
4331
|
+
M2.message(import_picocolors3.default.dim(line));
|
|
5081
4332
|
}
|
|
5082
4333
|
} else {
|
|
5083
4334
|
M2.error(error instanceof Error ? error.message : "Unknown error occurred");
|
|
5084
4335
|
}
|
|
5085
4336
|
showInstallTip();
|
|
5086
|
-
Se(
|
|
4337
|
+
Se(import_picocolors3.default.red("Installation failed"));
|
|
5087
4338
|
process.exit(1);
|
|
5088
4339
|
} finally {
|
|
5089
4340
|
await cleanup(tempDir);
|
|
@@ -5111,9 +4362,9 @@ async function promptForFindSkills(options, targetAgents) {
|
|
|
5111
4362
|
return;
|
|
5112
4363
|
}
|
|
5113
4364
|
console.log();
|
|
5114
|
-
M2.message(
|
|
4365
|
+
M2.message(import_picocolors3.default.dim("One-time prompt - you won't be asked again if you dismiss."));
|
|
5115
4366
|
const install = await ye({
|
|
5116
|
-
message: `Install the ${
|
|
4367
|
+
message: `Install the ${import_picocolors3.default.cyan("find-skills")} skill? It helps your agent discover and suggest skills.`
|
|
5117
4368
|
});
|
|
5118
4369
|
if (pD(install)) {
|
|
5119
4370
|
await dismissPrompt("findSkillsPrompt");
|
|
@@ -5137,13 +4388,13 @@ async function promptForFindSkills(options, targetAgents) {
|
|
|
5137
4388
|
} catch {
|
|
5138
4389
|
M2.warn("Failed to install find-skills. You can try again with:");
|
|
5139
4390
|
M2.message(
|
|
5140
|
-
|
|
4391
|
+
import_picocolors3.default.dim(" npx @codemcp/skills add vercel-labs/skills@find-skills -g -y --all")
|
|
5141
4392
|
);
|
|
5142
4393
|
}
|
|
5143
4394
|
} else {
|
|
5144
4395
|
await dismissPrompt("findSkillsPrompt");
|
|
5145
4396
|
M2.message(
|
|
5146
|
-
|
|
4397
|
+
import_picocolors3.default.dim(
|
|
5147
4398
|
"You can install it later with: npx @codemcp/skills add vercel-labs/skills@find-skills"
|
|
5148
4399
|
)
|
|
5149
4400
|
);
|
|
@@ -5196,17 +4447,17 @@ function parseAddOptions(args) {
|
|
|
5196
4447
|
}
|
|
5197
4448
|
|
|
5198
4449
|
// src/sync.ts
|
|
5199
|
-
var
|
|
4450
|
+
var import_picocolors4 = __toESM(require_picocolors(), 1);
|
|
5200
4451
|
import { readdir as readdir4, stat as stat4 } from "fs/promises";
|
|
5201
|
-
import { join as join8, sep as
|
|
4452
|
+
import { join as join8, sep as sep6 } from "path";
|
|
5202
4453
|
import { homedir as homedir5 } from "os";
|
|
5203
4454
|
var isCancelled2 = (value) => typeof value === "symbol";
|
|
5204
4455
|
function shortenPath2(fullPath, cwd) {
|
|
5205
4456
|
const home2 = homedir5();
|
|
5206
|
-
if (fullPath === home2 || fullPath.startsWith(home2 +
|
|
4457
|
+
if (fullPath === home2 || fullPath.startsWith(home2 + sep6)) {
|
|
5207
4458
|
return "~" + fullPath.slice(home2.length);
|
|
5208
4459
|
}
|
|
5209
|
-
if (fullPath === cwd || fullPath.startsWith(cwd +
|
|
4460
|
+
if (fullPath === cwd || fullPath.startsWith(cwd + sep6)) {
|
|
5210
4461
|
return "." + fullPath.slice(cwd.length);
|
|
5211
4462
|
}
|
|
5212
4463
|
return fullPath;
|
|
@@ -5284,22 +4535,22 @@ async function discoverNodeModuleSkills(cwd) {
|
|
|
5284
4535
|
async function runSync(args, options = {}) {
|
|
5285
4536
|
const cwd = process.cwd();
|
|
5286
4537
|
console.log();
|
|
5287
|
-
Ie(
|
|
4538
|
+
Ie(import_picocolors4.default.bgCyan(import_picocolors4.default.black(" skills experimental_sync ")));
|
|
5288
4539
|
const spinner = Y2();
|
|
5289
4540
|
spinner.start("Scanning node_modules for skills...");
|
|
5290
4541
|
const discoveredSkills = await discoverNodeModuleSkills(cwd);
|
|
5291
4542
|
if (discoveredSkills.length === 0) {
|
|
5292
|
-
spinner.stop(
|
|
5293
|
-
Se(
|
|
4543
|
+
spinner.stop(import_picocolors4.default.yellow("No skills found"));
|
|
4544
|
+
Se(import_picocolors4.default.dim("No SKILL.md files found in node_modules."));
|
|
5294
4545
|
return;
|
|
5295
4546
|
}
|
|
5296
4547
|
spinner.stop(
|
|
5297
|
-
`Found ${
|
|
4548
|
+
`Found ${import_picocolors4.default.green(String(discoveredSkills.length))} skill${discoveredSkills.length > 1 ? "s" : ""} in node_modules`
|
|
5298
4549
|
);
|
|
5299
4550
|
for (const skill of discoveredSkills) {
|
|
5300
|
-
M2.info(`${
|
|
4551
|
+
M2.info(`${import_picocolors4.default.cyan(skill.name)} ${import_picocolors4.default.dim(`from ${skill.packageName}`)}`);
|
|
5301
4552
|
if (skill.description) {
|
|
5302
|
-
M2.message(
|
|
4553
|
+
M2.message(import_picocolors4.default.dim(` ${skill.description}`));
|
|
5303
4554
|
}
|
|
5304
4555
|
}
|
|
5305
4556
|
const localLock = await readLocalLock(cwd);
|
|
@@ -5307,7 +4558,7 @@ async function runSync(args, options = {}) {
|
|
|
5307
4558
|
const upToDate = [];
|
|
5308
4559
|
if (options.force) {
|
|
5309
4560
|
toInstall.push(...discoveredSkills);
|
|
5310
|
-
M2.info(
|
|
4561
|
+
M2.info(import_picocolors4.default.dim("Force mode: reinstalling all skills"));
|
|
5311
4562
|
} else {
|
|
5312
4563
|
for (const skill of discoveredSkills) {
|
|
5313
4564
|
const existingEntry = localLock.skills[skill.name];
|
|
@@ -5322,12 +4573,12 @@ async function runSync(args, options = {}) {
|
|
|
5322
4573
|
}
|
|
5323
4574
|
if (upToDate.length > 0) {
|
|
5324
4575
|
M2.info(
|
|
5325
|
-
|
|
4576
|
+
import_picocolors4.default.dim(`${upToDate.length} skill${upToDate.length !== 1 ? "s" : ""} already up to date`)
|
|
5326
4577
|
);
|
|
5327
4578
|
}
|
|
5328
4579
|
if (toInstall.length === 0) {
|
|
5329
4580
|
console.log();
|
|
5330
|
-
Se(
|
|
4581
|
+
Se(import_picocolors4.default.green("All skills are up to date."));
|
|
5331
4582
|
return;
|
|
5332
4583
|
}
|
|
5333
4584
|
}
|
|
@@ -5417,8 +4668,8 @@ async function runSync(args, options = {}) {
|
|
|
5417
4668
|
for (const skill of toInstall) {
|
|
5418
4669
|
const canonicalPath = getCanonicalPath(skill.name, { global: false });
|
|
5419
4670
|
const shortCanonical = shortenPath2(canonicalPath, cwd);
|
|
5420
|
-
summaryLines.push(`${
|
|
5421
|
-
summaryLines.push(` ${
|
|
4671
|
+
summaryLines.push(`${import_picocolors4.default.cyan(skill.name)} ${import_picocolors4.default.dim(`\u2190 ${skill.packageName}`)}`);
|
|
4672
|
+
summaryLines.push(` ${import_picocolors4.default.dim(shortCanonical)}`);
|
|
5422
4673
|
}
|
|
5423
4674
|
console.log();
|
|
5424
4675
|
Me(summaryLines.join("\n"), "Sync Summary");
|
|
@@ -5484,21 +4735,21 @@ async function runSync(args, options = {}) {
|
|
|
5484
4735
|
const pkg = toInstall.find((s) => s.name === skillName)?.packageName;
|
|
5485
4736
|
if (firstResult.canonicalPath) {
|
|
5486
4737
|
const shortPath = shortenPath2(firstResult.canonicalPath, cwd);
|
|
5487
|
-
resultLines.push(`${
|
|
5488
|
-
resultLines.push(` ${
|
|
4738
|
+
resultLines.push(`${import_picocolors4.default.green("\u2713")} ${skillName} ${import_picocolors4.default.dim(`\u2190 ${pkg}`)}`);
|
|
4739
|
+
resultLines.push(` ${import_picocolors4.default.dim(shortPath)}`);
|
|
5489
4740
|
} else {
|
|
5490
|
-
resultLines.push(`${
|
|
4741
|
+
resultLines.push(`${import_picocolors4.default.green("\u2713")} ${skillName} ${import_picocolors4.default.dim(`\u2190 ${pkg}`)}`);
|
|
5491
4742
|
}
|
|
5492
4743
|
}
|
|
5493
4744
|
const skillCount = bySkill.size;
|
|
5494
|
-
const title =
|
|
4745
|
+
const title = import_picocolors4.default.green(`Synced ${skillCount} skill${skillCount !== 1 ? "s" : ""}`);
|
|
5495
4746
|
Me(resultLines.join("\n"), title);
|
|
5496
4747
|
}
|
|
5497
4748
|
if (failed.length > 0) {
|
|
5498
4749
|
console.log();
|
|
5499
|
-
M2.error(
|
|
4750
|
+
M2.error(import_picocolors4.default.red(`Failed to install ${failed.length}`));
|
|
5500
4751
|
for (const r2 of failed) {
|
|
5501
|
-
M2.message(` ${
|
|
4752
|
+
M2.message(` ${import_picocolors4.default.red("\u2717")} ${r2.skill} \u2192 ${r2.agent}: ${import_picocolors4.default.dim(r2.error)}`);
|
|
5502
4753
|
}
|
|
5503
4754
|
}
|
|
5504
4755
|
track({
|
|
@@ -5509,7 +4760,7 @@ async function runSync(args, options = {}) {
|
|
|
5509
4760
|
});
|
|
5510
4761
|
console.log();
|
|
5511
4762
|
Se(
|
|
5512
|
-
|
|
4763
|
+
import_picocolors4.default.green("Done!") + import_picocolors4.default.dim(" Review skills before use; they run with full agent permissions.")
|
|
5513
4764
|
);
|
|
5514
4765
|
}
|
|
5515
4766
|
function parseSyncOptions(args) {
|
|
@@ -5536,7 +4787,7 @@ function parseSyncOptions(args) {
|
|
|
5536
4787
|
}
|
|
5537
4788
|
|
|
5538
4789
|
// src/install.ts
|
|
5539
|
-
var
|
|
4790
|
+
var import_picocolors5 = __toESM(require_picocolors(), 1);
|
|
5540
4791
|
async function runInstallFromLock(args) {
|
|
5541
4792
|
const cwd = process.cwd();
|
|
5542
4793
|
const lock = await readLocalLock(cwd);
|
|
@@ -5544,7 +4795,7 @@ async function runInstallFromLock(args) {
|
|
|
5544
4795
|
if (skillEntries.length === 0) {
|
|
5545
4796
|
M2.warn("No project skills found in skills-lock.json");
|
|
5546
4797
|
M2.info(
|
|
5547
|
-
`Add project-level skills with ${
|
|
4798
|
+
`Add project-level skills with ${import_picocolors5.default.cyan("npx @codemcp/skills add <package>")} (without ${import_picocolors5.default.cyan("-g")})`
|
|
5548
4799
|
);
|
|
5549
4800
|
return;
|
|
5550
4801
|
}
|
|
@@ -5569,7 +4820,7 @@ async function runInstallFromLock(args) {
|
|
|
5569
4820
|
const remoteCount = skillEntries.length - nodeModuleSkills.length;
|
|
5570
4821
|
if (remoteCount > 0) {
|
|
5571
4822
|
M2.info(
|
|
5572
|
-
`Restoring ${
|
|
4823
|
+
`Restoring ${import_picocolors5.default.cyan(String(remoteCount))} skill${remoteCount !== 1 ? "s" : ""} from skills-lock.json into ${import_picocolors5.default.dim(".agents/skills/")}`
|
|
5573
4824
|
);
|
|
5574
4825
|
}
|
|
5575
4826
|
for (const [source, { skills }] of bySource) {
|
|
@@ -5581,13 +4832,13 @@ async function runInstallFromLock(args) {
|
|
|
5581
4832
|
});
|
|
5582
4833
|
} catch (error) {
|
|
5583
4834
|
M2.error(
|
|
5584
|
-
`Failed to install from ${
|
|
4835
|
+
`Failed to install from ${import_picocolors5.default.cyan(source)}: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
5585
4836
|
);
|
|
5586
4837
|
}
|
|
5587
4838
|
}
|
|
5588
4839
|
if (nodeModuleSkills.length > 0) {
|
|
5589
4840
|
M2.info(
|
|
5590
|
-
`${
|
|
4841
|
+
`${import_picocolors5.default.cyan(String(nodeModuleSkills.length))} skill${nodeModuleSkills.length !== 1 ? "s" : ""} from node_modules`
|
|
5591
4842
|
);
|
|
5592
4843
|
try {
|
|
5593
4844
|
const { options: syncOptions } = parseSyncOptions(args);
|
|
@@ -5601,23 +4852,20 @@ async function runInstallFromLock(args) {
|
|
|
5601
4852
|
}
|
|
5602
4853
|
|
|
5603
4854
|
export {
|
|
4855
|
+
__toESM,
|
|
5604
4856
|
require_picocolors,
|
|
5605
4857
|
pD,
|
|
5606
|
-
he,
|
|
5607
4858
|
ye,
|
|
5608
|
-
ve,
|
|
5609
4859
|
fe,
|
|
5610
4860
|
xe,
|
|
5611
4861
|
Se,
|
|
5612
4862
|
M2 as M,
|
|
5613
4863
|
Y2 as Y,
|
|
5614
4864
|
isRepoPrivate,
|
|
5615
|
-
discoverSkills,
|
|
5616
4865
|
agents,
|
|
5617
4866
|
detectInstalledAgents,
|
|
5618
4867
|
sanitizeName,
|
|
5619
4868
|
getCanonicalSkillsDir,
|
|
5620
|
-
getMCPCanonicalSkillsDir,
|
|
5621
4869
|
getInstallPath,
|
|
5622
4870
|
getCanonicalPath,
|
|
5623
4871
|
listInstalledSkills,
|