@codemcp/skills 2.1.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,28 @@
1
- import {
2
- __commonJS,
3
- __toESM
4
- } from "./chunk-JSBRDJBE.js";
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 import_picocolors2 = __toESM(require_picocolors(), 1);
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 import_picocolors2.default.cyan(le);
946
+ return import_picocolors.default.cyan(le);
939
947
  case "cancel":
940
- return import_picocolors2.default.red(L2);
948
+ return import_picocolors.default.red(L2);
941
949
  case "error":
942
- return import_picocolors2.default.yellow(W2);
950
+ return import_picocolors.default.yellow(W2);
943
951
  case "submit":
944
- return import_picocolors2.default.green(C);
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, v2, f) => {
953
- const j2 = v2 === 0 && $2, E = v2 === f.length - 1 && g2;
954
- return j2 || E ? import_picocolors2.default.dim("...") : i(p2, v2 + l2 === n);
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 = `${import_picocolors2.default.gray(o)}
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}${import_picocolors2.default.gray(o)} ${import_picocolors2.default.dim(s)}`;
973
+ return `${i}${import_picocolors.default.gray(o)} ${import_picocolors.default.dim(s)}`;
987
974
  case "cancel":
988
- return `${i}${import_picocolors2.default.gray(o)} ${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(s))}
989
- ${import_picocolors2.default.gray(o)}`;
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}${import_picocolors2.default.cyan(o)} ${this.value ? `${import_picocolors2.default.green(k2)} ${n}` : `${import_picocolors2.default.dim(P2)} ${import_picocolors2.default.dim(n)}`} ${import_picocolors2.default.dim("/")} ${this.value ? `${import_picocolors2.default.dim(P2)} ${import_picocolors2.default.dim(r2)}` : `${import_picocolors2.default.green(k2)} ${r2}`}
992
- ${import_picocolors2.default.cyan(d2)}
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 `${import_picocolors2.default.dim(s)}`;
989
+ return `${import_picocolors.default.dim(s)}`;
1003
990
  case "active":
1004
- return `${import_picocolors2.default.green(k2)} ${s} ${r2.hint ? import_picocolors2.default.dim(`(${r2.hint})`) : ""}`;
991
+ return `${import_picocolors.default.green(k2)} ${s} ${r2.hint ? import_picocolors.default.dim(`(${r2.hint})`) : ""}`;
1005
992
  case "cancelled":
1006
- return `${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(s))}`;
993
+ return `${import_picocolors.default.strikethrough(import_picocolors.default.dim(s))}`;
1007
994
  default:
1008
- return `${import_picocolors2.default.dim(P2)} ${import_picocolors2.default.dim(s)}`;
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 = `${import_picocolors2.default.gray(o)}
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}${import_picocolors2.default.gray(o)} ${n(this.options[this.cursor], "selected")}`;
1004
+ return `${r2}${import_picocolors.default.gray(o)} ${n(this.options[this.cursor], "selected")}`;
1018
1005
  case "cancel":
1019
- return `${r2}${import_picocolors2.default.gray(o)} ${n(this.options[this.cursor], "cancelled")}
1020
- ${import_picocolors2.default.gray(o)}`;
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}${import_picocolors2.default.cyan(o)} ${G2({ cursor: this.cursor, options: this.options, maxItems: t.maxItems, style: (i, s) => n(i, s ? "active" : "inactive") }).join(`
1023
- ${import_picocolors2.default.cyan(o)} `)}
1024
- ${import_picocolors2.default.cyan(d2)}
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" ? `${import_picocolors2.default.cyan(A2)} ${s} ${r2.hint ? import_picocolors2.default.dim(`(${r2.hint})`) : ""}` : i === "selected" ? `${import_picocolors2.default.green(T2)} ${import_picocolors2.default.dim(s)} ${r2.hint ? import_picocolors2.default.dim(`(${r2.hint})`) : ""}` : i === "cancelled" ? `${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(s))}` : i === "active-selected" ? `${import_picocolors2.default.green(T2)} ${s} ${r2.hint ? import_picocolors2.default.dim(`(${r2.hint})`) : ""}` : i === "submitted" ? `${import_picocolors2.default.dim(s)}` : `${import_picocolors2.default.dim(F)} ${import_picocolors2.default.dim(s)}`;
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
- ${import_picocolors2.default.reset(import_picocolors2.default.dim(`Press ${import_picocolors2.default.gray(import_picocolors2.default.bgWhite(import_picocolors2.default.inverse(" space ")))} to select, ${import_picocolors2.default.gray(import_picocolors2.default.bgWhite(import_picocolors2.default.inverse(" enter ")))} to submit`))}`;
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 = `${import_picocolors2.default.gray(o)}
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}${import_picocolors2.default.gray(o)} ${this.options.filter(({ value: s }) => this.value.includes(s)).map((s) => n(s, "submitted")).join(import_picocolors2.default.dim(", ")) || import_picocolors2.default.dim("none")}`;
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(import_picocolors2.default.dim(", "));
1049
- return `${r2}${import_picocolors2.default.gray(o)} ${s.trim() ? `${s}
1050
- ${import_picocolors2.default.gray(o)}` : ""}`;
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 ? `${import_picocolors2.default.yellow(d2)} ${import_picocolors2.default.yellow(c)}` : ` ${c}`).join(`
1041
+ `).map((c, a) => a === 0 ? `${import_picocolors.default.yellow(d2)} ${import_picocolors.default.yellow(c)}` : ` ${c}`).join(`
1055
1042
  `);
1056
- return `${r2 + import_picocolors2.default.yellow(o)} ${G2({ options: this.options, cursor: this.cursor, maxItems: t.maxItems, style: i }).join(`
1057
- ${import_picocolors2.default.yellow(o)} `)}
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}${import_picocolors2.default.cyan(o)} ${G2({ options: this.options, cursor: this.cursor, maxItems: t.maxItems, style: i }).join(`
1063
- ${import_picocolors2.default.cyan(o)} `)}
1064
- ${import_picocolors2.default.cyan(d2)}
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 `${import_picocolors2.default.dim(p2)}${import_picocolors2.default.cyan(A2)} ${a} ${i.hint ? import_picocolors2.default.dim(`(${i.hint})`) : ""}`;
1073
- if (s === "group-active") return `${p2}${import_picocolors2.default.cyan(A2)} ${import_picocolors2.default.dim(a)}`;
1074
- if (s === "group-active-selected") return `${p2}${import_picocolors2.default.green(T2)} ${import_picocolors2.default.dim(a)}`;
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 ? import_picocolors2.default.green(T2) : "";
1077
- return `${import_picocolors2.default.dim(p2)}${f} ${import_picocolors2.default.dim(a)} ${i.hint ? import_picocolors2.default.dim(`(${i.hint})`) : ""}`;
1078
- }
1079
- if (s === "cancelled") return `${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(a))}`;
1080
- if (s === "active-selected") return `${import_picocolors2.default.dim(p2)}${import_picocolors2.default.green(T2)} ${a} ${i.hint ? import_picocolors2.default.dim(`(${i.hint})`) : ""}`;
1081
- if (s === "submitted") return `${import_picocolors2.default.dim(a)}`;
1082
- const v2 = l2 || n ? import_picocolors2.default.dim(F) : "";
1083
- return `${import_picocolors2.default.dim(p2)}${v2} ${import_picocolors2.default.dim(a)}`;
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
- ${import_picocolors2.default.reset(import_picocolors2.default.dim(`Press ${import_picocolors2.default.gray(import_picocolors2.default.bgWhite(import_picocolors2.default.inverse(" space ")))} to select, ${import_picocolors2.default.gray(import_picocolors2.default.bgWhite(import_picocolors2.default.inverse(" enter ")))} to submit`))}`;
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 = `${import_picocolors2.default.gray(o)}
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}${import_picocolors2.default.gray(o)} ${this.options.filter(({ value: s }) => this.value.includes(s)).map((s) => r2(s, "submitted")).join(import_picocolors2.default.dim(", "))}`;
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(import_picocolors2.default.dim(", "));
1097
- return `${i}${import_picocolors2.default.gray(o)} ${s.trim() ? `${s}
1098
- ${import_picocolors2.default.gray(o)}` : ""}`;
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 ? `${import_picocolors2.default.yellow(d2)} ${import_picocolors2.default.yellow(c)}` : ` ${c}`).join(`
1089
+ `).map((c, a) => a === 0 ? `${import_picocolors.default.yellow(d2)} ${import_picocolors.default.yellow(c)}` : ` ${c}`).join(`
1103
1090
  `);
1104
- return `${i}${import_picocolors2.default.yellow(o)} ${this.options.map((c, a, l2) => {
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
- ${import_picocolors2.default.yellow(o)} `)}
1095
+ ${import_picocolors.default.yellow(o)} `)}
1109
1096
  ${s}
1110
1097
  `;
1111
1098
  }
1112
1099
  default:
1113
- return `${i}${import_picocolors2.default.cyan(o)} ${this.options.map((s, c, a) => {
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
- ${import_picocolors2.default.cyan(o)} `)}
1118
- ${import_picocolors2.default.cyan(d2)}
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) => `${import_picocolors2.default.gray(o)} ${import_picocolors2.default.dim(a)}${" ".repeat(s - S2(a).length)}${import_picocolors2.default.gray(o)}`).join(`
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(`${import_picocolors2.default.gray(o)}
1133
- ${import_picocolors2.default.green(C)} ${import_picocolors2.default.reset(n)} ${import_picocolors2.default.gray(_2.repeat(Math.max(s - i - 1, 1)) + me)}
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
- ${import_picocolors2.default.gray(de + _2.repeat(s + 2) + pe)}
1122
+ ${import_picocolors.default.gray(de + _2.repeat(s + 2) + pe)}
1136
1123
  `);
1137
1124
  };
1138
1125
  var xe = (t = "") => {
1139
- process.stdout.write(`${import_picocolors2.default.gray(d2)} ${import_picocolors2.default.red(t)}
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(`${import_picocolors2.default.gray(ue)} ${t}
1131
+ process.stdout.write(`${import_picocolors.default.gray(ue)} ${t}
1145
1132
  `);
1146
1133
  };
1147
1134
  var Se = (t = "") => {
1148
- process.stdout.write(`${import_picocolors2.default.gray(o)}
1149
- ${import_picocolors2.default.gray(d2)} ${t}
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 = import_picocolors2.default.gray(o) } = {}) => {
1154
- const r2 = [`${import_picocolors2.default.gray(o)}`];
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) => `${import_picocolors2.default.gray(o)} ${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: import_picocolors2.default.blue(q2) });
1151
+ M2.message(t, { symbol: import_picocolors.default.blue(q2) });
1165
1152
  }, success: (t) => {
1166
- M2.message(t, { symbol: import_picocolors2.default.green(D) });
1153
+ M2.message(t, { symbol: import_picocolors.default.green(D) });
1167
1154
  }, step: (t) => {
1168
- M2.message(t, { symbol: import_picocolors2.default.green(C) });
1155
+ M2.message(t, { symbol: import_picocolors.default.green(C) });
1169
1156
  }, warn: (t) => {
1170
- M2.message(t, { symbol: import_picocolors2.default.yellow(U) });
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: import_picocolors2.default.red(K2) });
1161
+ M2.message(t, { symbol: import_picocolors.default.red(K2) });
1175
1162
  } };
1176
- var J2 = `${import_picocolors2.default.gray(o)} `;
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
- }, v2 = () => p2(2), f = () => p2(1), j2 = () => {
1184
- process.on("uncaughtExceptionMonitor", v2), process.on("unhandledRejection", v2), process.on("SIGINT", f), process.on("SIGTERM", f), process.on("exit", p2);
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", v2), process.removeListener("unhandledRejection", v2), process.removeListener("SIGINT", f), process.removeListener("SIGTERM", f), process.removeListener("exit", p2);
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(`${import_picocolors2.default.gray(o)}
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 = import_picocolors2.default.magenta(n[h2]);
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 ? import_picocolors2.default.green(C) : h2 === 1 ? import_picocolors2.default.red(L2) : import_picocolors2.default.red(W2);
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 import_picocolors4 = __toESM(require_picocolors(), 1);
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 sep4 } from "path";
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 import_picocolors3 = __toESM(require_picocolors(), 1);
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 = import_picocolors3.default.green("\u25C6");
1443
- var S_STEP_CANCEL = import_picocolors3.default.red("\u25A0");
1444
- var S_STEP_SUBMIT = import_picocolors3.default.green("\u25C7");
1445
- var S_RADIO_ACTIVE = import_picocolors3.default.green("\u25CF");
1446
- var S_RADIO_INACTIVE = import_picocolors3.default.dim("\u25CB");
1447
- var S_CHECKBOX_LOCKED = import_picocolors3.default.green("\u2713");
1448
- var S_BULLET = import_picocolors3.default.green("\u2022");
1449
- var S_BAR = import_picocolors3.default.dim("\u2502");
1450
- var S_BAR_H = import_picocolors3.default.dim("\u2500");
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} ${import_picocolors3.default.bold(message)}`);
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 = `${import_picocolors3.default.bold(lockedSection.title)} ${import_picocolors3.default.dim("\u2500\u2500 always included")}`;
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} ${import_picocolors3.default.bold(item.label)}`);
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} ${import_picocolors3.default.bold("Additional agents")} ${S_BAR_H.repeat(29)}`
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} ${import_picocolors3.default.dim("Search:")} ${query}${import_picocolors3.default.inverse(" ")}`;
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} ${import_picocolors3.default.dim("\u2191\u2193 move, space select, enter confirm")}`);
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} ${import_picocolors3.default.dim("No matches found")}`);
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 ? import_picocolors3.default.underline(item.label) : item.label;
1532
- const hint = item.hint ? import_picocolors3.default.dim(` (${item.hint})`) : "";
1533
- const prefix = isCursor ? import_picocolors3.default.cyan("\u276F") : " ";
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} ${import_picocolors3.default.dim(parts.join(" "))}`);
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} ${import_picocolors3.default.dim("Selected: (none)")}`);
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} ${import_picocolors3.default.green("Selected:")} ${summary}`);
1539
+ lines.push(`${S_BAR} ${import_picocolors2.default.green("Selected:")} ${summary}`);
1555
1540
  }
1556
- lines.push(`${import_picocolors3.default.dim("\u2514")}`);
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} ${import_picocolors3.default.dim(allSelectedLabels.join(", "))}`);
1547
+ lines.push(`${S_BAR} ${import_picocolors2.default.dim(allSelectedLabels.join(", "))}`);
1563
1548
  } else if (state === "cancel") {
1564
- lines.push(`${S_BAR} ${import_picocolors3.default.strikethrough(import_picocolors3.default.dim("Cancelled"))}`);
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 normalize3, resolve as resolve5, sep as sep3, relative as relative2, dirname as dirname4 } from "path";
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: ".cline/skills",
2077
- globalSkillsDir: join6(home, ".cline/skills"),
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 = normalize3(resolve5(basePath));
2442
- const normalizedTarget = normalize3(resolve5(targetPath));
2443
- return normalizedTarget.startsWith(normalizedBase + sep3) || normalizedTarget === 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("_")) return true;
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
- await cp(srcPath, destPath, {
2645
- // If the file is a symlink to elsewhere in a remote skill, it may not
2646
- // resolve correctly once it has been copied to the local location.
2647
- // `dereference: true` tells Node to copy the file instead of copying
2648
- // the symlink. `recursive: true` handles symlinks pointing to directories.
2649
- dereference: true,
2650
- recursive: true
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 matter4 from "gray-matter";
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 } = matter4(content);
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 domain in owner/repo format: second-level-domain/top-level-domain.
3428
- * e.g., "mintlify.com" → "mintlify/com", "lovable.dev" → "lovable/dev"
3429
- * This matches the owner/repo pattern used by GitHub sources for consistency in the leaderboard.
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
- const hostParts = parsed.hostname.split(".");
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/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.0",
3208
+ version: "2.2.0",
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 import_picocolors4.default.red(import_picocolors4.default.bold("Critical Risk"));
3291
+ return import_picocolors3.default.red(import_picocolors3.default.bold("Critical Risk"));
3576
3292
  case "high":
3577
- return import_picocolors4.default.red("High Risk");
3293
+ return import_picocolors3.default.red("High Risk");
3578
3294
  case "medium":
3579
- return import_picocolors4.default.yellow("Med Risk");
3295
+ return import_picocolors3.default.yellow("Med Risk");
3580
3296
  case "low":
3581
- return import_picocolors4.default.green("Low Risk");
3297
+ return import_picocolors3.default.green("Low Risk");
3582
3298
  case "safe":
3583
- return import_picocolors4.default.green("Safe");
3299
+ return import_picocolors3.default.green("Safe");
3584
3300
  default:
3585
- return import_picocolors4.default.dim("--");
3301
+ return import_picocolors3.default.dim("--");
3586
3302
  }
3587
3303
  }
3588
3304
  function socketLabel(audit) {
3589
- if (!audit) return import_picocolors4.default.dim("--");
3305
+ if (!audit) return import_picocolors3.default.dim("--");
3590
3306
  const count = audit.alerts ?? 0;
3591
- return count > 0 ? import_picocolors4.default.red(`${count} alert${count !== 1 ? "s" : ""}`) : import_picocolors4.default.green("0 alerts");
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(import_picocolors4.default.dim("Gen"), 18) + padEnd(import_picocolors4.default.dim("Socket"), 18) + import_picocolors4.default.dim("Snyk");
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) : import_picocolors4.default.dim("--");
3613
- const socket = data?.socket ? socketLabel(data.socket) : import_picocolors4.default.dim("--");
3614
- const snyk = data?.snyk ? riskLabel(data.snyk.risk) : import_picocolors4.default.dim("--");
3615
- lines.push(padEnd(import_picocolors4.default.cyan(name), nameWidth + 2) + padEnd(ath, 18) + padEnd(socket, 18) + snyk);
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(`${import_picocolors4.default.dim("Details:")} ${import_picocolors4.default.dim(`https://skills.sh/${source}`)}`);
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 + sep4)) {
3339
+ if (fullPath === home2 || fullPath.startsWith(home2 + sep5)) {
3624
3340
  return "~" + fullPath.slice(home2.length);
3625
3341
  }
3626
- if (fullPath === cwd || fullPath.startsWith(cwd + sep4)) {
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(` ${import_picocolors4.default.dim("mcp-server \u2192")} @codemcp/skills-server`);
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(` ${import_picocolors4.default.green("universal:")} ${formatList(universal)}`);
3374
+ lines.push(` ${import_picocolors3.default.green("universal:")} ${formatList(universal)}`);
3659
3375
  }
3660
3376
  if (symlinked.length > 0) {
3661
- lines.push(` ${import_picocolors4.default.dim("symlink \u2192")} ${formatList(symlinked)}`);
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(` ${import_picocolors4.default.dim("copy \u2192")} ${formatList(allNames)}`);
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(` ${import_picocolors4.default.dim("Important:")} Make sure your agent has configured`);
3684
- lines.push(` ${import_picocolors4.default.cyan("@codemcp/skills-server")} as MCP server.`);
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(` ${import_picocolors4.default.green("universal:")} ${formatList(universal)}`);
3407
+ lines.push(` ${import_picocolors3.default.green("universal:")} ${formatList(universal)}`);
3692
3408
  }
3693
3409
  if (successfulSymlinks.length > 0) {
3694
- lines.push(` ${import_picocolors4.default.dim("symlinked:")} ${formatList(successfulSymlinks)}`);
3410
+ lines.push(` ${import_picocolors3.default.dim("symlinked:")} ${formatList(successfulSymlinks)}`);
3695
3411
  }
3696
3412
  if (failedSymlinks.length > 0) {
3697
- lines.push(` ${import_picocolors4.default.yellow("copied:")} ${formatList(failedSymlinks)}`);
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} ${import_picocolors4.default.dim("(space to toggle)")}`
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(import_picocolors4.default.red("No skills found"));
3500
+ spinner.stop(import_picocolors3.default.red("No skills found"));
4014
3501
  Se(
4015
- import_picocolors4.default.red(
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 ${import_picocolors4.default.green(skills.length)} skill${skills.length > 1 ? "s" : ""}`);
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: ${import_picocolors4.default.cyan(skill.installName)}`);
4024
- M2.message(import_picocolors4.default.dim(skill.description));
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(import_picocolors4.default.dim(` Files: ${Array.from(skill.files.keys()).join(", ")}`));
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(import_picocolors4.default.bold("Available Skills"));
3518
+ M2.step(import_picocolors3.default.bold("Available Skills"));
4032
3519
  for (const skill of skills) {
4033
- M2.message(` ${import_picocolors4.default.cyan(skill.installName)}`);
4034
- M2.message(` ${import_picocolors4.default.dim(skill.description)}`);
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(` ${import_picocolors4.default.dim(`Files: ${skill.files.size}`)}`);
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: ${import_picocolors4.default.cyan(firstSkill.installName)}`);
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: ${import_picocolors4.default.cyan(agents[firstAgent].displayName)}`);
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) => import_picocolors4.default.cyan(agents[a].displayName)).join(", ")}`
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(`${import_picocolors4.default.cyan(shortCanonical)}`);
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(` ${import_picocolors4.default.dim("files:")} ${skill.files.size}`);
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(` ${import_picocolors4.default.yellow("overwrites:")} ${formatList(overwriteAgents)}`);
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(`${import_picocolors4.default.green("\u2713")} ${skillName} ${import_picocolors4.default.dim("(copied)")}`);
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(` ${import_picocolors4.default.dim("\u2192")} ${shortPath}`);
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(`${import_picocolors4.default.green("\u2713")} ${shortPath}`);
3796
+ resultLines.push(`${import_picocolors3.default.green("\u2713")} ${shortPath}`);
4310
3797
  } else {
4311
- resultLines.push(`${import_picocolors4.default.green("\u2713")} ${skillName}`);
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 = import_picocolors4.default.green(`Installed ${skillCount} skill${skillCount !== 1 ? "s" : ""}`);
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(import_picocolors4.default.yellow(`Symlinks failed for: ${formatList(copiedAgents)}`));
3806
+ M2.warn(import_picocolors3.default.yellow(`Symlinks failed for: ${formatList(copiedAgents)}`));
4320
3807
  M2.message(
4321
- import_picocolors4.default.dim(
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(import_picocolors4.default.red(`Failed to install ${failed.length}`));
3816
+ M2.error(import_picocolors3.default.red(`Failed to install ${failed.length}`));
4330
3817
  for (const r2 of failed) {
4331
- M2.message(` ${import_picocolors4.default.red("\u2717")} ${r2.skill} \u2192 ${r2.agent}: ${import_picocolors4.default.dim(r2.error)}`);
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
- import_picocolors4.default.green("Done!") + import_picocolors4.default.dim(" Review skills before use; they run with full agent permissions.")
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
- import_picocolors4.default.dim("Tip: use the --yes (-y) and --global (-g) flags to install without prompts.")
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
- import_picocolors4.default.bgRed(import_picocolors4.default.white(import_picocolors4.default.bold(" ERROR "))) + " " + import_picocolors4.default.red("Missing required argument: source")
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(import_picocolors4.default.dim(" Usage:"));
3843
+ console.log(import_picocolors3.default.dim(" Usage:"));
4592
3844
  console.log(
4593
- ` ${import_picocolors4.default.cyan("npx @codemcp/skills add")} ${import_picocolors4.default.yellow("<source>")} ${import_picocolors4.default.dim("[options]")}`
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(import_picocolors4.default.dim(" Example:"));
3848
+ console.log(import_picocolors3.default.dim(" Example:"));
4597
3849
  console.log(
4598
- ` ${import_picocolors4.default.cyan("npx @codemcp/skills add")} ${import_picocolors4.default.yellow("vercel-labs/agent-skills")}`
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(import_picocolors4.default.bgCyan(import_picocolors4.default.black(" skills ")));
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 ? ` @ ${import_picocolors4.default.yellow(parsed.ref)}` : ""}${parsed.subpath ? ` (${parsed.subpath})` : ""}${parsed.skillFilter ? ` ${import_picocolors4.default.dim("@")}${import_picocolors4.default.cyan(parsed.skillFilter)}` : ""}`
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(import_picocolors4.default.red("Path not found"));
4634
- Se(import_picocolors4.default.red(`Local path does not exist: ${parsed.localPath}`));
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(import_picocolors4.default.red("No skills found"));
3906
+ spinner.stop(import_picocolors3.default.red("No skills found"));
4659
3907
  Se(
4660
- import_picocolors4.default.red("No valid skills found. Skills require a SKILL.md with name and description.")
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 ${import_picocolors4.default.green(skills.length)} skill${skills.length > 1 ? "s" : ""}`);
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(import_picocolors4.default.bold("Available Skills"));
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(import_picocolors4.default.bold(title));
3931
+ console.log(import_picocolors3.default.bold(title));
4684
3932
  for (const skill of groupedSkills[group]) {
4685
- M2.message(` ${import_picocolors4.default.cyan(getSkillDisplayName(skill))}`);
4686
- M2.message(` ${import_picocolors4.default.dim(skill.description)}`);
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(import_picocolors4.default.bold("General"));
3939
+ if (sortedGroups2.length > 0) console.log(import_picocolors3.default.bold("General"));
4692
3940
  for (const skill of ungroupedSkills) {
4693
- M2.message(` ${import_picocolors4.default.cyan(getSkillDisplayName(skill))}`);
4694
- M2.message(` ${import_picocolors4.default.dim(skill.description)}`);
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) => import_picocolors4.default.cyan(getSkillDisplayName(s))).join(", ")}`
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: ${import_picocolors4.default.cyan(getSkillDisplayName(firstSkill))}`);
4724
- M2.message(import_picocolors4.default.dim(firstSkill.description));
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 ${import_picocolors4.default.dim("(space to toggle)")}`,
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(`${import_picocolors4.default.cyan(shortCanonical)}`);
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(` ${import_picocolors4.default.yellow("overwrites:")} ${formatList(overwriteAgents)}`);
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(import_picocolors4.default.bold(title));
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(import_picocolors4.default.bold("General"));
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 + sep4)) {
4918
- relativePath = skill.path.slice(tempDir.length + 1).split(sep4).join("/") + "/SKILL.md";
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 hash = await fetchSkillFolderHash(normalizedSource, skillPathValue);
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: normalizedSource || parsed.url,
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(`${import_picocolors4.default.green("\u2713")} ${entry.skill} ${import_picocolors4.default.dim("(copied)")}`);
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(` ${import_picocolors4.default.dim("\u2192")} ${shortPath}`);
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(`${import_picocolors4.default.green("\u2713")} ${shortPath}`);
4282
+ resultLines.push(`${import_picocolors3.default.green("\u2713")} ${shortPath}`);
5032
4283
  } else {
5033
- resultLines.push(`${import_picocolors4.default.green("\u2713")} ${entry.skill}`);
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(import_picocolors4.default.bold(title2));
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(import_picocolors4.default.bold("General"));
4300
+ resultLines.push(import_picocolors3.default.bold("General"));
5050
4301
  }
5051
4302
  printSkillResults(ungroupedResults);
5052
4303
  }
5053
- const title = import_picocolors4.default.green(`Installed ${skillCount} skill${skillCount !== 1 ? "s" : ""}`);
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(import_picocolors4.default.yellow(`Symlinks failed for: ${formatList(copiedAgents)}`));
4307
+ M2.warn(import_picocolors3.default.yellow(`Symlinks failed for: ${formatList(copiedAgents)}`));
5057
4308
  M2.message(
5058
- import_picocolors4.default.dim(
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(import_picocolors4.default.red(`Failed to install ${failed.length}`));
4317
+ M2.error(import_picocolors3.default.red(`Failed to install ${failed.length}`));
5067
4318
  for (const r2 of failed) {
5068
- M2.message(` ${import_picocolors4.default.red("\u2717")} ${r2.skill} \u2192 ${r2.agent}: ${import_picocolors4.default.dim(r2.error)}`);
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
- import_picocolors4.default.green("Done!") + import_picocolors4.default.dim(" Review skills before use; they run with full agent permissions.")
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(import_picocolors4.default.red("Failed to clone repository"));
4329
+ M2.error(import_picocolors3.default.red("Failed to clone repository"));
5079
4330
  for (const line of error.message.split("\n")) {
5080
- M2.message(import_picocolors4.default.dim(line));
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(import_picocolors4.default.red("Installation failed"));
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(import_picocolors4.default.dim("One-time prompt - you won't be asked again if you dismiss."));
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 ${import_picocolors4.default.cyan("find-skills")} skill? It helps your agent discover and suggest skills.`
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
- import_picocolors4.default.dim(" npx @codemcp/skills add vercel-labs/skills@find-skills -g -y --all")
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
- import_picocolors4.default.dim(
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 import_picocolors5 = __toESM(require_picocolors(), 1);
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 sep5 } from "path";
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 + sep5)) {
4457
+ if (fullPath === home2 || fullPath.startsWith(home2 + sep6)) {
5207
4458
  return "~" + fullPath.slice(home2.length);
5208
4459
  }
5209
- if (fullPath === cwd || fullPath.startsWith(cwd + sep5)) {
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(import_picocolors5.default.bgCyan(import_picocolors5.default.black(" skills experimental_sync ")));
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(import_picocolors5.default.yellow("No skills found"));
5293
- Se(import_picocolors5.default.dim("No SKILL.md files found in node_modules."));
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 ${import_picocolors5.default.green(String(discoveredSkills.length))} skill${discoveredSkills.length > 1 ? "s" : ""} in node_modules`
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(`${import_picocolors5.default.cyan(skill.name)} ${import_picocolors5.default.dim(`from ${skill.packageName}`)}`);
4551
+ M2.info(`${import_picocolors4.default.cyan(skill.name)} ${import_picocolors4.default.dim(`from ${skill.packageName}`)}`);
5301
4552
  if (skill.description) {
5302
- M2.message(import_picocolors5.default.dim(` ${skill.description}`));
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(import_picocolors5.default.dim("Force mode: reinstalling all skills"));
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
- import_picocolors5.default.dim(`${upToDate.length} skill${upToDate.length !== 1 ? "s" : ""} already up to date`)
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(import_picocolors5.default.green("All skills are up to date."));
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(`${import_picocolors5.default.cyan(skill.name)} ${import_picocolors5.default.dim(`\u2190 ${skill.packageName}`)}`);
5421
- summaryLines.push(` ${import_picocolors5.default.dim(shortCanonical)}`);
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(`${import_picocolors5.default.green("\u2713")} ${skillName} ${import_picocolors5.default.dim(`\u2190 ${pkg}`)}`);
5488
- resultLines.push(` ${import_picocolors5.default.dim(shortPath)}`);
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(`${import_picocolors5.default.green("\u2713")} ${skillName} ${import_picocolors5.default.dim(`\u2190 ${pkg}`)}`);
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 = import_picocolors5.default.green(`Synced ${skillCount} skill${skillCount !== 1 ? "s" : ""}`);
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(import_picocolors5.default.red(`Failed to install ${failed.length}`));
4750
+ M2.error(import_picocolors4.default.red(`Failed to install ${failed.length}`));
5500
4751
  for (const r2 of failed) {
5501
- M2.message(` ${import_picocolors5.default.red("\u2717")} ${r2.skill} \u2192 ${r2.agent}: ${import_picocolors5.default.dim(r2.error)}`);
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
- import_picocolors5.default.green("Done!") + import_picocolors5.default.dim(" Review skills before use; they run with full agent permissions.")
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 import_picocolors6 = __toESM(require_picocolors(), 1);
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 ${import_picocolors6.default.cyan("npx @codemcp/skills add <package>")} (without ${import_picocolors6.default.cyan("-g")})`
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 ${import_picocolors6.default.cyan(String(remoteCount))} skill${remoteCount !== 1 ? "s" : ""} from skills-lock.json into ${import_picocolors6.default.dim(".agents/skills/")}`
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 ${import_picocolors6.default.cyan(source)}: ${error instanceof Error ? error.message : "Unknown error"}`
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
- `${import_picocolors6.default.cyan(String(nodeModuleSkills.length))} skill${nodeModuleSkills.length !== 1 ? "s" : ""} from node_modules`
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,