skill-master 0.1.5 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -111,6 +111,12 @@ var SkillParseError = class extends SkillManagerError {
111
111
  this.name = "SkillParseError";
112
112
  }
113
113
  };
114
+ var SourceParseError = class extends SkillManagerError {
115
+ constructor(source, detail) {
116
+ super(`Failed to parse source "${source}"${detail ? ": " + detail : ""}`);
117
+ this.name = "SourceParseError";
118
+ }
119
+ };
114
120
 
115
121
  // src/utils/logger.ts
116
122
  import chalk from "chalk";
@@ -152,20 +158,89 @@ function tableRow(...cols) {
152
158
 
153
159
  // src/core/git-source.ts
154
160
  var execFileAsync = promisify(execFile);
161
+ function parseSource(source) {
162
+ if (source.startsWith("git@") || source.startsWith("git://")) {
163
+ return { type: "git", url: source };
164
+ }
165
+ if (source.startsWith("https://") || source.startsWith("http://")) {
166
+ const ghTree = source.match(/github\.com\/([^/]+)\/([^/]+)\/tree\/([^/]+)(?:\/(.+))?/);
167
+ if (ghTree) {
168
+ const url = `https://github.com/${ghTree[1]}/${ghTree[2]}.git`;
169
+ return { type: "git", url, ref: ghTree[3], subpath: ghTree[4] };
170
+ }
171
+ const ghBlob = source.match(/github\.com\/([^/]+)\/([^/]+)\/blob\/([^/]+)\/(.+)/);
172
+ if (ghBlob) {
173
+ const url = `https://github.com/${ghBlob[1]}/${ghBlob[2]}.git`;
174
+ const filePath = ghBlob[4];
175
+ const subpath = filePath.includes("/") ? filePath.slice(0, filePath.lastIndexOf("/")) : void 0;
176
+ return { type: "git", url, ref: ghBlob[3], subpath };
177
+ }
178
+ const glTree = source.match(/gitlab\.com\/([^/]+)\/([^/]+)\/-\/tree\/([^/]+)(?:\/(.+))?/);
179
+ if (glTree) {
180
+ const url = `https://gitlab.com/${glTree[1]}/${glTree[2]}.git`;
181
+ return { type: "git", url, ref: glTree[3], subpath: glTree[4] };
182
+ }
183
+ if (source.includes("github.com/") || source.includes("gitlab.com/")) {
184
+ return { type: "git", url: source };
185
+ }
186
+ return { type: "git", url: source };
187
+ }
188
+ if (source.includes("github.com/") || source.includes("gitlab.com/")) {
189
+ return parseSource("https://" + source);
190
+ }
191
+ if (existsSync2(source) || source.startsWith("/") || source.startsWith("./") || source.startsWith("../")) {
192
+ return { type: "local", path: source };
193
+ }
194
+ let skillFilter;
195
+ let shorthand = source;
196
+ const atIdx = shorthand.indexOf("@");
197
+ if (atIdx > 0 && !shorthand.includes("/") === false) {
198
+ const lastAt = shorthand.lastIndexOf("@");
199
+ if (lastAt > 0) {
200
+ const afterAt = shorthand.slice(lastAt + 1);
201
+ const beforeAt = shorthand.slice(0, lastAt);
202
+ if (afterAt && !afterAt.includes("/")) {
203
+ skillFilter = afterAt;
204
+ shorthand = beforeAt;
205
+ }
206
+ }
207
+ }
208
+ if (/^[a-zA-Z0-9_.-]+\/[a-zA-Z0-9_.-]+$/.test(shorthand)) {
209
+ return {
210
+ type: "git",
211
+ url: `https://github.com/${shorthand}.git`,
212
+ skillFilter
213
+ };
214
+ }
215
+ const segments = shorthand.split("/");
216
+ if (segments.length >= 3 && /^[a-zA-Z0-9_.-]+$/.test(segments[0]) && /^[a-zA-Z0-9_.-]+$/.test(segments[1])) {
217
+ const owner = segments[0];
218
+ const repo = segments[1];
219
+ const subpath = segments.slice(2).join("/");
220
+ return {
221
+ type: "git",
222
+ url: `https://github.com/${owner}/${repo}.git`,
223
+ subpath,
224
+ skillFilter
225
+ };
226
+ }
227
+ throw new SourceParseError(source, "Unable to determine source type");
228
+ }
155
229
  function isGitUrl(source) {
156
- return source.startsWith("https://") || source.startsWith("http://") || source.startsWith("git@") || source.startsWith("git://") || source.includes("github.com/") || source.includes("gitlab.com/") || /^[a-zA-Z0-9_.-]+\/[a-zA-Z0-9_.-]+$/.test(source);
230
+ try {
231
+ return parseSource(source).type === "git";
232
+ } catch {
233
+ return false;
234
+ }
157
235
  }
158
236
  function normalizeGitUrl(source) {
159
- if (source.startsWith("https://") || source.startsWith("http://") || source.startsWith("git@") || source.startsWith("git://")) {
160
- if (source.startsWith("https://") && !source.endsWith(".git")) {
161
- return source + ".git";
162
- }
163
- return source;
164
- }
165
- if (/^[a-zA-Z0-9_.-]+\/[a-zA-Z0-9_.-]+$/.test(source)) {
166
- return `https://github.com/${source}.git`;
237
+ const parsed = parseSource(source);
238
+ if (parsed.type !== "git" || !parsed.url) return source;
239
+ let url = parsed.url;
240
+ if (url.startsWith("https://") && !url.endsWith(".git")) {
241
+ url += ".git";
167
242
  }
168
- return source;
243
+ return url;
169
244
  }
170
245
  function parseGitUrl(url) {
171
246
  const treeMatch = url.match(/github\.com\/([^/]+)\/([^/]+)\/tree\/(.+)/);
@@ -264,7 +339,13 @@ async function findSkillDirectory(dir) {
264
339
  const dirs = await findAllSkillDirectories(dir);
265
340
  return dirs.length > 0 ? dirs[0] : null;
266
341
  }
267
- async function findAllSkillDirectories(dir) {
342
+ var SKIP_DIRS = /* @__PURE__ */ new Set(["node_modules", ".git", "dist", "build"]);
343
+ async function findAllSkillDirectories(dir, fullDepth = false) {
344
+ if (fullDepth) {
345
+ const results2 = /* @__PURE__ */ new Set();
346
+ await walkForSkills(dir, 0, 5, results2);
347
+ return [...results2];
348
+ }
268
349
  const results = [];
269
350
  if (existsSync3(join2(dir, "SKILL.md"))) {
270
351
  results.push(dir);
@@ -299,6 +380,21 @@ async function findAllSkillDirectories(dir) {
299
380
  }
300
381
  return results;
301
382
  }
383
+ async function walkForSkills(dir, depth, maxDepth, results) {
384
+ if (depth > maxDepth) return;
385
+ if (existsSync3(join2(dir, "SKILL.md"))) {
386
+ results.add(dir);
387
+ }
388
+ try {
389
+ const entries = await readdir(dir, { withFileTypes: true });
390
+ for (const entry of entries) {
391
+ if (entry.isDirectory() && !entry.name.startsWith(".") && !SKIP_DIRS.has(entry.name)) {
392
+ await walkForSkills(join2(dir, entry.name), depth + 1, maxDepth, results);
393
+ }
394
+ }
395
+ } catch {
396
+ }
397
+ }
302
398
  async function readSkillMd(dir) {
303
399
  const content = await readTextSafe(join2(dir, "SKILL.md"));
304
400
  if (!content) return null;
@@ -612,6 +708,9 @@ function detectPlatform(cwd) {
612
708
  function getAgentSkillPath(cwd, agent, name) {
613
709
  return join3(cwd, AGENTS[agent].skillsDir, name);
614
710
  }
711
+ function getAgentGlobalSkillPath(agent, name) {
712
+ return join3(AGENTS[agent].globalSkillsDir, name);
713
+ }
615
714
 
616
715
  // src/utils/paths.ts
617
716
  var AGENTS_HOME = join4(homedir2(), ".agents");
@@ -726,12 +825,38 @@ function getEnvEditPath(skillName) {
726
825
  // src/core/registry.ts
727
826
  import { existsSync as existsSync5 } from "fs";
728
827
  function createEmptyRegistry() {
729
- return { version: 1, skills: {} };
828
+ return { version: 2, skills: {} };
829
+ }
830
+ function migrateEntryV1(v1) {
831
+ return {
832
+ source: v1.source,
833
+ version: v1.version,
834
+ installed_at: v1.installed_at,
835
+ updated_at: v1.updated_at,
836
+ agents: [{
837
+ agent: v1.agent,
838
+ agent_path: v1.agent_path,
839
+ global: v1.agent_path.includes("/.agents/") || v1.agent_path.includes("\\.agents\\")
840
+ }],
841
+ env_keys: v1.env_keys,
842
+ capabilities: v1.capabilities,
843
+ canonical_path: v1.canonical_path
844
+ };
730
845
  }
731
- function validateRegistry(data) {
732
- if (!data || typeof data !== "object") return false;
846
+ function validateAndMigrate(data) {
847
+ if (!data || typeof data !== "object") return null;
733
848
  const reg = data;
734
- return reg.version === 1 && typeof reg.skills === "object" && reg.skills !== null;
849
+ if (typeof reg.skills !== "object" || reg.skills === null) return null;
850
+ if (reg.version === 2) return data;
851
+ if (reg.version === 1) {
852
+ const v1Skills = reg.skills;
853
+ const v2Skills = {};
854
+ for (const [name, entry] of Object.entries(v1Skills)) {
855
+ v2Skills[name] = migrateEntryV1(entry);
856
+ }
857
+ return { version: 2, skills: v2Skills };
858
+ }
859
+ return null;
735
860
  }
736
861
  async function readRegistry() {
737
862
  if (!existsSync5(REGISTRY_PATH)) {
@@ -741,14 +866,46 @@ async function readRegistry() {
741
866
  if (!data) {
742
867
  throw new RegistryCorruptError("Failed to parse registry.json");
743
868
  }
744
- if (!validateRegistry(data)) {
869
+ const registry = validateAndMigrate(data);
870
+ if (!registry) {
745
871
  throw new RegistryCorruptError("Invalid registry structure");
746
872
  }
747
- return data;
873
+ if (data.version !== registry.version) {
874
+ await atomicWriteJson(REGISTRY_PATH, registry);
875
+ }
876
+ return registry;
748
877
  }
749
878
  async function updateRegistry(skillName, entry) {
750
879
  const registry = await readRegistry();
751
- registry.skills[skillName] = entry;
880
+ const existing = registry.skills[skillName];
881
+ if (existing) {
882
+ for (const newAgent of entry.agents) {
883
+ const idx = existing.agents.findIndex((a) => a.agent === newAgent.agent);
884
+ if (idx >= 0) {
885
+ existing.agents[idx] = newAgent;
886
+ } else {
887
+ existing.agents.push(newAgent);
888
+ }
889
+ }
890
+ existing.source = entry.source;
891
+ existing.version = entry.version;
892
+ existing.updated_at = entry.updated_at;
893
+ existing.env_keys = entry.env_keys;
894
+ existing.capabilities = entry.capabilities;
895
+ existing.canonical_path = entry.canonical_path;
896
+ } else {
897
+ registry.skills[skillName] = entry;
898
+ }
899
+ await atomicWriteJson(REGISTRY_PATH, registry);
900
+ }
901
+ async function removeAgentFromRegistry(skillName, agent) {
902
+ const registry = await readRegistry();
903
+ const entry = registry.skills[skillName];
904
+ if (!entry) return;
905
+ entry.agents = entry.agents.filter((a) => a.agent !== agent);
906
+ if (entry.agents.length === 0) {
907
+ delete registry.skills[skillName];
908
+ }
752
909
  await atomicWriteJson(REGISTRY_PATH, registry);
753
910
  }
754
911
  async function removeFromRegistry(skillName) {
@@ -768,7 +925,7 @@ async function getRegistryEntry(skillName) {
768
925
  // src/core/installer.ts
769
926
  var TOTAL_STEPS = 9;
770
927
  async function installSkill(options) {
771
- const { source, cwd, copy = false, force = false } = options;
928
+ const { source, cwd, copy = false, force = false, global: isGlobal = false } = options;
772
929
  step(1, TOTAL_STEPS, "Fetching skill source...");
773
930
  let sourceDir;
774
931
  if (source.type === "git") {
@@ -797,7 +954,7 @@ async function installSkill(options) {
797
954
  const agent = options.agent ?? detectPlatform(cwd);
798
955
  info(`Target platform: ${agent}`);
799
956
  step(5, TOTAL_STEPS, "Backing up .env...");
800
- const agentSkillDir = getAgentSkillPath(cwd, agent, skillName);
957
+ const agentSkillDir = isGlobal ? getAgentGlobalSkillPath(agent, skillName) : getAgentSkillPath(cwd, agent, skillName);
801
958
  const envBackup = await backupEnv(skillName, agentSkillDir);
802
959
  if (envBackup) {
803
960
  success(`Backed up ${Object.keys(envBackup).length} env key(s)`);
@@ -823,7 +980,7 @@ async function installSkill(options) {
823
980
  }
824
981
  }
825
982
  step(8, TOTAL_STEPS, `Linking to ${agent} skills directory...`);
826
- const agentPath = getAgentSkillPath(cwd, agent, skillName);
983
+ const agentPath = isGlobal ? getAgentGlobalSkillPath(agent, skillName) : getAgentSkillPath(cwd, agent, skillName);
827
984
  const linkType = await symlinkOrCopy(canonicalPath, agentPath, copy);
828
985
  success(`${linkType === "symlink" ? "Symlinked" : "Copied"} to ${agentPath}`);
829
986
  step(9, TOTAL_STEPS, "Updating registry...");
@@ -831,16 +988,20 @@ async function installSkill(options) {
831
988
  const envExampleContent = await readTextSafe(join6(canonicalPath, ".env.example"));
832
989
  const envKeys = envExampleContent ? extractEnvKeys(envExampleContent) : [];
833
990
  const now = (/* @__PURE__ */ new Date()).toISOString();
991
+ const agentInstall = {
992
+ agent,
993
+ agent_path: agentPath,
994
+ global: isGlobal
995
+ };
834
996
  const entry = {
835
997
  source: source.type === "git" ? source.url : source.path,
836
998
  version: parsed.frontmatter.version,
837
999
  installed_at: now,
838
1000
  updated_at: now,
839
- agent,
1001
+ agents: [agentInstall],
840
1002
  env_keys: envKeys,
841
1003
  capabilities,
842
- canonical_path: canonicalPath,
843
- agent_path: agentPath
1004
+ canonical_path: canonicalPath
844
1005
  };
845
1006
  await updateRegistry(skillName, entry);
846
1007
  blank();
@@ -849,7 +1010,7 @@ async function installSkill(options) {
849
1010
 
850
1011
  // src/commands/add.ts
851
1012
  import { existsSync as existsSync7 } from "fs";
852
- import { basename as basename2 } from "path";
1013
+ import { basename as basename2, join as join7 } from "path";
853
1014
  function parseAddFlags(args) {
854
1015
  const flags = {
855
1016
  global: false,
@@ -860,7 +1021,8 @@ function parseAddFlags(args) {
860
1021
  all: false,
861
1022
  fullDepth: false,
862
1023
  copy: false,
863
- force: false
1024
+ force: false,
1025
+ help: false
864
1026
  };
865
1027
  let source = null;
866
1028
  let i = 0;
@@ -884,6 +1046,11 @@ function parseAddFlags(args) {
884
1046
  continue;
885
1047
  }
886
1048
  switch (arg) {
1049
+ case "-h":
1050
+ case "--help":
1051
+ flags.help = true;
1052
+ i++;
1053
+ break;
887
1054
  case "-g":
888
1055
  case "--global":
889
1056
  flags.global = true;
@@ -948,51 +1115,84 @@ function parseAddFlags(args) {
948
1115
  }
949
1116
  return { source, flags };
950
1117
  }
1118
+ function printAddHelp() {
1119
+ console.log("Usage: skill-master add <source> [options]");
1120
+ console.log("");
1121
+ console.log("Options:");
1122
+ console.log(" -h, --help Show this help message");
1123
+ console.log(" -g, --global Install globally (~/.agents/)");
1124
+ console.log(" -a, --agent <agents> Target agents (space-separated)");
1125
+ console.log(" -s, --skill <skills> Select skills (space-separated)");
1126
+ console.log(" -y, --yes Skip confirmations");
1127
+ console.log(" -l, --list List available skills without installing");
1128
+ console.log(" --all Install all skills to all agents");
1129
+ console.log(" --full-depth Search all subdirectories");
1130
+ console.log(" --copy Copy instead of symlink");
1131
+ console.log(" --force Force reinstall");
1132
+ }
951
1133
  async function add(args) {
952
1134
  if (args.length === 0) {
953
- error("Usage: skill-master add <source> [options]");
954
- console.log("");
955
- console.log("Options:");
956
- console.log(" -g, --global Install globally (~/.agents/)");
957
- console.log(" -a, --agent <agents> Target agents (space-separated)");
958
- console.log(" -s, --skill <skills> Select skills (space-separated)");
959
- console.log(" -y, --yes Skip confirmations");
960
- console.log(" -l, --list List available skills without installing");
961
- console.log(" --all Install all skills to all agents");
962
- console.log(" --full-depth Search all subdirectories");
963
- console.log(" --copy Copy instead of symlink");
964
- console.log(" --force Force reinstall");
1135
+ printAddHelp();
965
1136
  process.exit(1);
966
1137
  }
967
1138
  const { source, flags } = parseAddFlags(args);
1139
+ if (flags.help) {
1140
+ printAddHelp();
1141
+ process.exit(0);
1142
+ }
968
1143
  if (!source) {
969
1144
  error("No source specified. Provide a GitHub URL, owner/repo, or local path.");
970
1145
  process.exit(1);
971
1146
  }
972
1147
  const cwd = process.cwd();
1148
+ const parsed = parseSource(source);
1149
+ if (parsed.skillFilter && !flags.skill.includes(parsed.skillFilter)) {
1150
+ flags.skill.push(parsed.skillFilter);
1151
+ }
973
1152
  let sourceDir;
974
- const isGit = isGitUrl(source);
975
- if (isGit) {
1153
+ if (parsed.type === "git") {
976
1154
  step(1, 9, "Fetching skill source...");
977
- sourceDir = await cloneRepo(source);
1155
+ sourceDir = await cloneRepo(parsed.url, parsed.ref);
1156
+ if (parsed.subpath) {
1157
+ const sub = join7(sourceDir, parsed.subpath);
1158
+ if (existsSync7(sub)) {
1159
+ sourceDir = sub;
1160
+ }
1161
+ }
978
1162
  } else {
979
- sourceDir = source;
1163
+ sourceDir = parsed.path;
980
1164
  if (!existsSync7(sourceDir)) {
981
1165
  throw new SkillNotFoundError(sourceDir);
982
1166
  }
983
1167
  }
984
- const allSkillDirs = await findAllSkillDirectories(sourceDir);
1168
+ const allSkillDirs = await findAllSkillDirectories(sourceDir, flags.fullDepth);
985
1169
  if (allSkillDirs.length === 0) {
986
1170
  throw new SkillNotFoundError(`No SKILL.md found in ${sourceDir}`);
987
1171
  }
1172
+ if (flags.list) {
1173
+ blank();
1174
+ tableHeader("Skill", "Version", "Description");
1175
+ for (const dir of allSkillDirs) {
1176
+ const sk = await readSkillMd(dir);
1177
+ if (sk) {
1178
+ tableRow(
1179
+ sk.frontmatter.name,
1180
+ sk.frontmatter.version ?? "-",
1181
+ sk.frontmatter.description ?? "-"
1182
+ );
1183
+ }
1184
+ }
1185
+ blank();
1186
+ return;
1187
+ }
988
1188
  let targetDirs = allSkillDirs;
989
1189
  if (flags.skill.length > 0 && !flags.skill.includes("*")) {
990
1190
  const requested = new Set(flags.skill.map((s) => s.toLowerCase()));
991
1191
  const filtered = [];
992
1192
  for (const dir of allSkillDirs) {
993
- const parsed = await readSkillMd(dir);
994
- if (!parsed) continue;
995
- const name = parsed.frontmatter.name.toLowerCase();
1193
+ const sk = await readSkillMd(dir);
1194
+ if (!sk) continue;
1195
+ const name = sk.frontmatter.name.toLowerCase();
996
1196
  const dirName = basename2(dir).toLowerCase();
997
1197
  if (requested.has(name) || requested.has(dirName)) {
998
1198
  filtered.push(dir);
@@ -1001,8 +1201,8 @@ async function add(args) {
1001
1201
  if (filtered.length === 0) {
1002
1202
  const available = [];
1003
1203
  for (const dir of allSkillDirs) {
1004
- const parsed = await readSkillMd(dir);
1005
- if (parsed) available.push(parsed.frontmatter.name);
1204
+ const sk = await readSkillMd(dir);
1205
+ if (sk) available.push(sk.frontmatter.name);
1006
1206
  }
1007
1207
  error(
1008
1208
  `No matching skills found for: ${flags.skill.join(", ")}
@@ -1020,6 +1220,7 @@ async function add(args) {
1020
1220
  source: { type: "local", path: dir },
1021
1221
  agent,
1022
1222
  cwd,
1223
+ global: flags.global,
1023
1224
  copy: flags.copy,
1024
1225
  force: flags.force,
1025
1226
  yes: flags.yes
@@ -1048,12 +1249,15 @@ async function update(args) {
1048
1249
  info(`Updating skill: ${skillName}`);
1049
1250
  info(`Source: ${entry.source}`);
1050
1251
  const source = isGitUrl(entry.source) ? { type: "git", url: entry.source } : { type: "local", path: entry.source };
1051
- await installSkill({
1052
- source,
1053
- agent: entry.agent,
1054
- cwd: process.cwd(),
1055
- force: true
1056
- });
1252
+ for (const agentRecord of entry.agents) {
1253
+ await installSkill({
1254
+ source,
1255
+ agent: agentRecord.agent,
1256
+ cwd: process.cwd(),
1257
+ global: agentRecord.global,
1258
+ force: true
1259
+ });
1260
+ }
1057
1261
  success(`Skill "${skillName}" updated successfully!`);
1058
1262
  } catch (err) {
1059
1263
  error(err.message);
@@ -1069,7 +1273,8 @@ function parseRemoveFlags(args) {
1069
1273
  skill: [],
1070
1274
  yes: false,
1071
1275
  all: false,
1072
- purge: false
1276
+ purge: false,
1277
+ help: false
1073
1278
  };
1074
1279
  const names = [];
1075
1280
  let i = 0;
@@ -1093,6 +1298,11 @@ function parseRemoveFlags(args) {
1093
1298
  continue;
1094
1299
  }
1095
1300
  switch (arg) {
1301
+ case "-h":
1302
+ case "--help":
1303
+ flags.help = true;
1304
+ i++;
1305
+ break;
1096
1306
  case "-g":
1097
1307
  case "--global":
1098
1308
  flags.global = true;
@@ -1142,20 +1352,28 @@ function parseRemoveFlags(args) {
1142
1352
  }
1143
1353
  return { names, flags };
1144
1354
  }
1355
+ function printRemoveHelp() {
1356
+ console.log("Usage: skill-master remove [skills...] [options]");
1357
+ console.log("");
1358
+ console.log("Options:");
1359
+ console.log(" -h, --help Show this help message");
1360
+ console.log(" -g, --global Remove from global (~/.agents/)");
1361
+ console.log(" -a, --agent <agents> Target agents (space-separated)");
1362
+ console.log(" -s, --skill <skills> Select skills (space-separated)");
1363
+ console.log(" -y, --yes Skip confirmations");
1364
+ console.log(" --all Remove all skills");
1365
+ console.log(" --purge Also remove config data");
1366
+ }
1145
1367
  async function remove(args) {
1146
1368
  if (args.length === 0) {
1147
- error("Usage: skill-master remove [skills...] [options]");
1148
- console.log("");
1149
- console.log("Options:");
1150
- console.log(" -g, --global Remove from global (~/.agents/)");
1151
- console.log(" -a, --agent <agents> Target agents (space-separated)");
1152
- console.log(" -s, --skill <skills> Select skills (space-separated)");
1153
- console.log(" -y, --yes Skip confirmations");
1154
- console.log(" --all Remove all skills");
1155
- console.log(" --purge Also remove config data");
1369
+ printRemoveHelp();
1156
1370
  process.exit(1);
1157
1371
  }
1158
1372
  const { names, flags } = parseRemoveFlags(args);
1373
+ if (flags.help) {
1374
+ printRemoveHelp();
1375
+ process.exit(0);
1376
+ }
1159
1377
  let skillNames;
1160
1378
  if (flags.all) {
1161
1379
  const registry = await listRegistry();
@@ -1176,15 +1394,39 @@ async function remove(args) {
1176
1394
  throw new SkillNotFoundError(skillName);
1177
1395
  }
1178
1396
  info(`Removing skill: ${skillName}`);
1179
- await removePath(entry.agent_path);
1180
- success(`Removed from ${entry.agent_path}`);
1181
- await removePath(entry.canonical_path);
1182
- success(`Removed from ${entry.canonical_path}`);
1183
- if (flags.purge) {
1184
- await removePath(getSkillConfigPath(skillName));
1185
- success("Purged config directory");
1397
+ if (flags.agent.length > 0) {
1398
+ for (const agentName of flags.agent) {
1399
+ const agentRecord = entry.agents.find((a) => a.agent === agentName);
1400
+ if (!agentRecord) {
1401
+ warn(`Agent "${agentName}" not found for skill "${skillName}"`);
1402
+ continue;
1403
+ }
1404
+ await removePath(agentRecord.agent_path);
1405
+ success(`Removed ${agentName} path: ${agentRecord.agent_path}`);
1406
+ await removeAgentFromRegistry(skillName, agentName);
1407
+ }
1408
+ const updated = await getRegistryEntry(skillName);
1409
+ if (!updated) {
1410
+ await removePath(entry.canonical_path);
1411
+ success(`Removed canonical path: ${entry.canonical_path}`);
1412
+ if (flags.purge) {
1413
+ await removePath(getSkillConfigPath(skillName));
1414
+ success("Purged config directory");
1415
+ }
1416
+ }
1417
+ } else {
1418
+ for (const agentRecord of entry.agents) {
1419
+ await removePath(agentRecord.agent_path);
1420
+ success(`Removed ${agentRecord.agent} path: ${agentRecord.agent_path}`);
1421
+ }
1422
+ await removePath(entry.canonical_path);
1423
+ success(`Removed canonical path: ${entry.canonical_path}`);
1424
+ if (flags.purge) {
1425
+ await removePath(getSkillConfigPath(skillName));
1426
+ success("Purged config directory");
1427
+ }
1428
+ await removeFromRegistry(skillName);
1186
1429
  }
1187
- await removeFromRegistry(skillName);
1188
1430
  success(`Skill "${skillName}" removed successfully!`);
1189
1431
  }
1190
1432
  } catch (err) {
@@ -1310,17 +1552,20 @@ async function list(args = []) {
1310
1552
  const skills = await listRegistry();
1311
1553
  let entries = Object.entries(skills);
1312
1554
  if (flags.agent.length > 0) {
1313
- entries = entries.filter(([, entry]) => flags.agent.includes(entry.agent));
1555
+ entries = entries.filter(
1556
+ ([, entry]) => entry.agents.some((a) => flags.agent.includes(a.agent))
1557
+ );
1314
1558
  }
1315
1559
  if (entries.length === 0) {
1316
1560
  info("No skills installed");
1317
1561
  return;
1318
1562
  }
1319
1563
  blank();
1320
- tableHeader("Skill", "Version", "Platform", "Installed");
1564
+ tableHeader("Skill", "Version", "Platform(s)", "Installed");
1321
1565
  for (const [name, entry] of entries) {
1322
1566
  const date = new Date(entry.installed_at).toLocaleDateString();
1323
- tableRow(name, entry.version ?? "-", entry.agent, date);
1567
+ const platforms = entry.agents.map((a) => a.agent).join(", ");
1568
+ tableRow(name, entry.version ?? "-", platforms, date);
1324
1569
  }
1325
1570
  blank();
1326
1571
  }
@@ -1341,12 +1586,14 @@ async function info2(args) {
1341
1586
  blank();
1342
1587
  info(`Skill: ${skillName}`);
1343
1588
  kv("Version", entry.version ?? "-");
1344
- kv("Platform", entry.agent);
1589
+ kv("Platform(s)", entry.agents.map((a) => a.agent).join(", "));
1345
1590
  kv("Source", entry.source);
1346
1591
  kv("Installed", new Date(entry.installed_at).toLocaleString());
1347
1592
  kv("Updated", new Date(entry.updated_at).toLocaleString());
1348
1593
  kv("Canonical Path", entry.canonical_path);
1349
- kv("Agent Path", entry.agent_path);
1594
+ for (const a of entry.agents) {
1595
+ kv(` ${a.agent} Path`, `${a.agent_path}${a.global ? " (global)" : ""}`);
1596
+ }
1350
1597
  kv("Capabilities", entry.capabilities.join(", "));
1351
1598
  kv("Env Keys", entry.env_keys.join(", ") || "none");
1352
1599
  kv("Env Status", envStatus);
@@ -1400,12 +1647,14 @@ async function doctor() {
1400
1647
  error(` \u2717 Canonical path missing: ${entry.canonical_path}`);
1401
1648
  issues++;
1402
1649
  }
1403
- if (existsSync8(entry.agent_path)) {
1404
- const isLink = await isSymlink(entry.agent_path);
1405
- success(` \u2713 Agent path exists (${isLink ? "symlink" : "copy"})`);
1406
- } else {
1407
- error(` \u2717 Agent path missing: ${entry.agent_path}`);
1408
- issues++;
1650
+ for (const agentRecord of entry.agents) {
1651
+ if (existsSync8(agentRecord.agent_path)) {
1652
+ const isLink = await isSymlink(agentRecord.agent_path);
1653
+ success(` \u2713 ${agentRecord.agent} path exists (${isLink ? "symlink" : "copy"}${agentRecord.global ? ", global" : ""})`);
1654
+ } else {
1655
+ error(` \u2717 ${agentRecord.agent} path missing: ${agentRecord.agent_path}`);
1656
+ issues++;
1657
+ }
1409
1658
  }
1410
1659
  const envStatus = await getEnvStatus(name, entry.env_keys);
1411
1660
  if (envStatus === "configured") {
@@ -1480,7 +1729,7 @@ async function find(args) {
1480
1729
 
1481
1730
  // src/commands/init.ts
1482
1731
  import { existsSync as existsSync9 } from "fs";
1483
- import { join as join7, basename as basename3 } from "path";
1732
+ import { join as join8, basename as basename3 } from "path";
1484
1733
  var SKILL_MD_TEMPLATE = `---
1485
1734
  name: {{NAME}}
1486
1735
  version: 0.1.0
@@ -1506,13 +1755,13 @@ async function init(args) {
1506
1755
  let targetDir;
1507
1756
  let skillName;
1508
1757
  if (nameArg) {
1509
- targetDir = join7(cwd, nameArg);
1758
+ targetDir = join8(cwd, nameArg);
1510
1759
  skillName = nameArg;
1511
1760
  } else {
1512
1761
  targetDir = cwd;
1513
1762
  skillName = basename3(cwd);
1514
1763
  }
1515
- const skillMdPath = join7(targetDir, "SKILL.md");
1764
+ const skillMdPath = join8(targetDir, "SKILL.md");
1516
1765
  if (existsSync9(skillMdPath)) {
1517
1766
  error(`SKILL.md already exists at ${skillMdPath}`);
1518
1767
  process.exit(1);
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/installer.ts","../src/core/git-source.ts","../src/utils/fs-helpers.ts","../src/utils/errors.ts","../src/utils/logger.ts","../src/core/skill-parser.ts","../src/core/env-manager.ts","../src/utils/paths.ts","../src/platform/agents.ts","../src/core/registry.ts","../src/commands/add.ts","../src/commands/update.ts","../src/commands/remove.ts","../src/commands/env.ts","../src/commands/list.ts","../src/commands/info.ts","../src/commands/doctor.ts","../src/commands/find.ts","../src/commands/init.ts","../src/commands/check.ts","../src/cli.ts"],"sourcesContent":["import { join } from 'node:path';\nimport { existsSync } from 'node:fs';\nimport { cloneRepo, isGitUrl, isLocalPath } from './git-source.js';\nimport { findSkillDirectory, readSkillMd, inferCapabilities, extractEnvKeys } from './skill-parser.js';\nimport { backupEnv, restoreEnv } from './env-manager.js';\nimport { updateRegistry } from './registry.js';\nimport { detectPlatform, getAgentSkillsDir } from '../platform/detector.js';\nimport { copyDir, removePath, symlinkOrCopy, ensureDir, readTextSafe } from '../utils/fs-helpers.js';\nimport { getSkillCanonicalPath, getAgentSkillPath } from '../utils/paths.js';\nimport * as logger from '../utils/logger.js';\nimport { SkillNotFoundError, SkillParseError } from '../utils/errors.js';\nimport type { InstallOptions, RegistryEntry } from '../types/index.js';\n\nconst TOTAL_STEPS = 9;\n\n/**\n * Main installation engine — 9-step process:\n * 1. fetchSource → clone/copy to temp\n * 2. findSkillDir → locate SKILL.md\n * 3. parseSkillMd → parse frontmatter\n * 4. detectAgent → determine target platform\n * 5. backupEnv → preserve existing .env\n * 6. cleanAndInstall → rm old → copy new to canonical\n * 7. restoreEnv → restore .env to both locations\n * 8. linkOrCopy → symlink/copy to agent dir\n * 9. updateRegistry → update registry.json\n */\nexport async function installSkill(options: InstallOptions): Promise<void> {\n const { source, cwd, copy = false, force = false } = options;\n\n // Step 1: Fetch source\n logger.step(1, TOTAL_STEPS, 'Fetching skill source...');\n let sourceDir: string;\n\n if (source.type === 'git') {\n sourceDir = await cloneRepo(source.url!, source.branch);\n } else if (source.type === 'local') {\n sourceDir = source.path!;\n if (!existsSync(sourceDir)) {\n throw new SkillNotFoundError(sourceDir);\n }\n } else {\n throw new SkillParseError('Invalid source type');\n }\n\n // Step 2: Find skill directory\n logger.step(2, TOTAL_STEPS, 'Locating SKILL.md...');\n const skillDir = await findSkillDirectory(sourceDir);\n if (!skillDir) {\n throw new SkillNotFoundError(`No SKILL.md found in ${sourceDir}`);\n }\n\n // Step 3: Parse SKILL.md\n logger.step(3, TOTAL_STEPS, 'Parsing SKILL.md...');\n const parsed = await readSkillMd(skillDir);\n if (!parsed) {\n throw new SkillParseError('Failed to read SKILL.md');\n }\n const skillName = parsed.frontmatter.name;\n logger.info(`Found skill: ${skillName}${parsed.frontmatter.version ? ` v${parsed.frontmatter.version}` : ''}`);\n\n // Step 4: Detect agent platform\n logger.step(4, TOTAL_STEPS, 'Detecting agent platform...');\n const agent = options.agent ?? detectPlatform(cwd);\n logger.info(`Target platform: ${agent}`);\n\n // Step 5: Backup existing .env\n logger.step(5, TOTAL_STEPS, 'Backing up .env...');\n const agentSkillDir = getAgentSkillPath(cwd, agent, skillName);\n const envBackup = await backupEnv(skillName, agentSkillDir);\n if (envBackup) {\n logger.success(`Backed up ${Object.keys(envBackup).length} env key(s)`);\n } else {\n logger.info('No existing .env found');\n }\n\n // Step 6: Clean and install to canonical path\n logger.step(6, TOTAL_STEPS, 'Installing to canonical path...');\n const canonicalPath = getSkillCanonicalPath(skillName);\n\n if (existsSync(canonicalPath) && !force) {\n logger.info('Replacing existing installation');\n }\n await removePath(canonicalPath);\n await copyDir(skillDir, canonicalPath);\n logger.success(`Installed to ${canonicalPath}`);\n\n // Step 7: Restore .env\n logger.step(7, TOTAL_STEPS, 'Restoring .env...');\n if (envBackup) {\n await restoreEnv(skillName, envBackup, canonicalPath);\n logger.success('.env restored successfully');\n } else {\n // Check if there's a .env.example to hint about\n const examplePath = join(canonicalPath, '.env.example');\n if (existsSync(examplePath)) {\n logger.warn('Found .env.example — run `skill-master env edit ' + skillName + '` to configure');\n }\n }\n\n // Step 8: Link or copy to agent directory\n logger.step(8, TOTAL_STEPS, `Linking to ${agent} skills directory...`);\n const agentPath = getAgentSkillPath(cwd, agent, skillName);\n const linkType = await symlinkOrCopy(canonicalPath, agentPath, copy);\n logger.success(`${linkType === 'symlink' ? 'Symlinked' : 'Copied'} to ${agentPath}`);\n\n // Step 9: Update registry\n logger.step(9, TOTAL_STEPS, 'Updating registry...');\n const capabilities = parsed.frontmatter.capabilities ?? inferCapabilities(parsed.frontmatter['allowed-tools'] ?? []);\n\n // Extract env keys from .env.example\n const envExampleContent = await readTextSafe(join(canonicalPath, '.env.example'));\n const envKeys = envExampleContent ? extractEnvKeys(envExampleContent) : [];\n\n const now = new Date().toISOString();\n const entry: RegistryEntry = {\n source: source.type === 'git' ? source.url! : source.path!,\n version: parsed.frontmatter.version,\n installed_at: now,\n updated_at: now,\n agent,\n env_keys: envKeys,\n capabilities,\n canonical_path: canonicalPath,\n agent_path: agentPath,\n };\n\n await updateRegistry(skillName, entry);\n logger.blank();\n logger.success(`Skill \"${skillName}\" installed successfully!`);\n}\n","import { execFile } from 'node:child_process';\nimport { promisify } from 'node:util';\nimport { existsSync } from 'node:fs';\nimport { ensureDir, createTempDir } from '../utils/fs-helpers.js';\nimport { GitCloneError } from '../utils/errors.js';\nimport * as logger from '../utils/logger.js';\n\nconst execFileAsync = promisify(execFile);\n\n/** Check if a string looks like a git URL or GitHub shorthand (owner/repo) */\nexport function isGitUrl(source: string): boolean {\n return (\n source.startsWith('https://') ||\n source.startsWith('http://') ||\n source.startsWith('git@') ||\n source.startsWith('git://') ||\n source.includes('github.com/') ||\n source.includes('gitlab.com/') ||\n /^[a-zA-Z0-9_.-]+\\/[a-zA-Z0-9_.-]+$/.test(source)\n );\n}\n\n/** Normalize a GitHub shorthand or URL to a full clone URL */\nexport function normalizeGitUrl(source: string): string {\n // Already a full URL\n if (source.startsWith('https://') || source.startsWith('http://') ||\n source.startsWith('git@') || source.startsWith('git://')) {\n // Ensure .git suffix for HTTPS URLs\n if (source.startsWith('https://') && !source.endsWith('.git')) {\n return source + '.git';\n }\n return source;\n }\n\n // GitHub shorthand: owner/repo\n if (/^[a-zA-Z0-9_.-]+\\/[a-zA-Z0-9_.-]+$/.test(source)) {\n return `https://github.com/${source}.git`;\n }\n\n return source;\n}\n\n/** Parse a GitHub URL into owner and repo */\nexport function parseGitUrl(url: string): { owner: string; repo: string; branch?: string } {\n // Handle tree/branch in URL: github.com/owner/repo/tree/branch\n const treeMatch = url.match(/github\\.com\\/([^/]+)\\/([^/]+)\\/tree\\/(.+)/);\n if (treeMatch) {\n return {\n owner: treeMatch[1],\n repo: treeMatch[2].replace(/\\.git$/, ''),\n branch: treeMatch[3],\n };\n }\n\n // Standard URL: github.com/owner/repo\n const match = url.match(/github\\.com[/:]([^/]+)\\/([^/.]+)/);\n if (match) {\n return { owner: match[1], repo: match[2] };\n }\n\n throw new GitCloneError(url, 'Unable to parse GitHub URL');\n}\n\n/** Clone a git repository to a temporary directory */\nexport async function cloneRepo(\n url: string,\n branch?: string,\n): Promise<string> {\n const normalizedUrl = normalizeGitUrl(url);\n const tempDir = createTempDir();\n await ensureDir(tempDir);\n\n const args = ['clone', '--depth', '1'];\n if (branch) {\n args.push('--branch', branch);\n }\n args.push(normalizedUrl, tempDir);\n\n logger.debug(`Cloning ${normalizedUrl} to ${tempDir}`);\n\n try {\n await execFileAsync('git', args, { timeout: 60_000 });\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n throw new GitCloneError(url, msg);\n }\n\n return tempDir;\n}\n\n/** Check if a local path exists and contains a skill */\nexport function isLocalPath(source: string): boolean {\n return existsSync(source);\n}","import { mkdir, cp, readFile, writeFile, rename, symlink, lstat, rm } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { tmpdir } from 'node:os';\nimport { randomBytes } from 'node:crypto';\n\n/** Ensure a directory exists (recursive) */\nexport async function ensureDir(dir: string): Promise<void> {\n await mkdir(dir, { recursive: true });\n}\n\n/** Recursively copy a directory */\nexport async function copyDir(src: string, dest: string): Promise<void> {\n await ensureDir(dest);\n await cp(src, dest, { recursive: true, force: true });\n}\n\n/** Remove a directory or file recursively */\nexport async function removePath(target: string): Promise<void> {\n if (existsSync(target)) {\n await rm(target, { recursive: true, force: true });\n }\n}\n\n/** Atomic JSON write: write to .tmp then rename */\nexport async function atomicWriteJson(filePath: string, data: unknown): Promise<void> {\n await ensureDir(dirname(filePath));\n const tmpPath = filePath + '.tmp';\n await writeFile(tmpPath, JSON.stringify(data, null, 2) + '\\n', 'utf-8');\n await rename(tmpPath, filePath);\n}\n\n/** Safely read and parse a JSON file, return null on failure */\nexport async function readJsonSafe<T>(filePath: string): Promise<T | null> {\n try {\n const content = await readFile(filePath, 'utf-8');\n return JSON.parse(content) as T;\n } catch {\n return null;\n }\n}\n\n/** Read a text file, return null if not found */\nexport async function readTextSafe(filePath: string): Promise<string | null> {\n try {\n return await readFile(filePath, 'utf-8');\n } catch {\n return null;\n }\n}\n\n/** Write text to a file, ensuring parent directory exists */\nexport async function writeText(filePath: string, content: string): Promise<void> {\n await ensureDir(dirname(filePath));\n await writeFile(filePath, content, 'utf-8');\n}\n\n/** Create a symlink, or copy if symlink fails (Windows fallback) */\nexport async function symlinkOrCopy(target: string, linkPath: string, forceCopy = false): Promise<'symlink' | 'copy'> {\n await ensureDir(dirname(linkPath));\n\n // Remove existing link/dir\n await removePath(linkPath);\n\n if (forceCopy) {\n await copyDir(target, linkPath);\n return 'copy';\n }\n\n try {\n await symlink(target, linkPath, 'dir');\n return 'symlink';\n } catch {\n // Fallback to copy on platforms that don't support symlinks\n await copyDir(target, linkPath);\n return 'copy';\n }\n}\n\n/** Check if a path is a symlink */\nexport async function isSymlink(path: string): Promise<boolean> {\n try {\n const stat = await lstat(path);\n return stat.isSymbolicLink();\n } catch {\n return false;\n }\n}\n\n/** Create a temporary directory with a unique name */\nexport function createTempDir(): string {\n const id = randomBytes(8).toString('hex');\n return join(tmpdir(), `skill-master-${id}`);\n}\n","/** Base error class for skill-master */\nexport class SkillManagerError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'SkillManagerError';\n }\n}\n\n/** Skill not found in registry or filesystem */\nexport class SkillNotFoundError extends SkillManagerError {\n constructor(skillName: string) {\n super(`Skill \"${skillName}\" not found`);\n this.name = 'SkillNotFoundError';\n }\n}\n\n/** Required .env key is missing */\nexport class EnvMissingError extends SkillManagerError {\n constructor(skillName: string, keys: string[]) {\n super(`Skill \"${skillName}\" is missing env keys: ${keys.join(', ')}`);\n this.name = 'EnvMissingError';\n }\n}\n\n/** Registry file is corrupted or invalid */\nexport class RegistryCorruptError extends SkillManagerError {\n constructor(detail?: string) {\n super(`Registry is corrupted${detail ? ': ' + detail : ''}`);\n this.name = 'RegistryCorruptError';\n }\n}\n\n/** Git clone operation failed */\nexport class GitCloneError extends SkillManagerError {\n constructor(url: string, detail?: string) {\n super(`Failed to clone \"${url}\"${detail ? ': ' + detail : ''}`);\n this.name = 'GitCloneError';\n }\n}\n\n/** SKILL.md parsing or validation failed */\nexport class SkillParseError extends SkillManagerError {\n constructor(detail: string) {\n super(`Failed to parse SKILL.md: ${detail}`);\n this.name = 'SkillParseError';\n }\n}\n\n/** Platform detection failed or unsupported */\nexport class PlatformError extends SkillManagerError {\n constructor(detail: string) {\n super(`Platform error: ${detail}`);\n this.name = 'PlatformError';\n }\n}\n","import chalk from 'chalk';\n\nconst PREFIX = chalk.blue('skill-master');\n\n/** Informational message */\nexport function info(msg: string): void {\n console.log(`${PREFIX} ${chalk.cyan('info')} ${msg}`);\n}\n\n/** Success message */\nexport function success(msg: string): void {\n console.log(`${PREFIX} ${chalk.green('✔')} ${msg}`);\n}\n\n/** Warning message */\nexport function warn(msg: string): void {\n console.log(`${PREFIX} ${chalk.yellow('⚠')} ${msg}`);\n}\n\n/** Error message */\nexport function error(msg: string): void {\n console.error(`${PREFIX} ${chalk.red('✖')} ${msg}`);\n}\n\n/** Debug message (only when DEBUG env is set) */\nexport function debug(msg: string): void {\n if (process.env.DEBUG) {\n console.log(`${PREFIX} ${chalk.gray('debug')} ${msg}`);\n }\n}\n\n/** Step indicator with number */\nexport function step(num: number, total: number, msg: string): void {\n const counter = chalk.gray(`[${num}/${total}]`);\n console.log(`${PREFIX} ${counter} ${msg}`);\n}\n\n/** Print a blank line */\nexport function blank(): void {\n console.log();\n}\n\n/** Print a key-value pair */\nexport function kv(key: string, value: string): void {\n console.log(` ${chalk.gray(key + ':')} ${value}`);\n}\n\n/** Print a table header */\nexport function tableHeader(...cols: string[]): void {\n console.log(chalk.bold(cols.map(c => c.padEnd(20)).join('')));\n console.log(chalk.gray('─'.repeat(cols.length * 20)));\n}\n\n/** Print a table row */\nexport function tableRow(...cols: string[]): void {\n console.log(cols.map(c => c.padEnd(20)).join(''));\n}\n","import { parse as parseYaml, stringify as stringifyYaml } from 'yaml';\nimport { readdir } from 'node:fs/promises';\nimport { join, basename } from 'node:path';\nimport { existsSync } from 'node:fs';\nimport { readTextSafe } from '../utils/fs-helpers.js';\nimport { SkillParseError } from '../utils/errors.js';\nimport type { ParsedSkill, SkillFrontmatter, Capability } from '../types/index.js';\n\n/** Tool-to-capability reverse mapping for Claude Code tools */\nconst TOOL_CAPABILITY_MAP: Record<string, Capability> = {\n 'Bash': 'shell',\n 'Read': 'read_file',\n 'Write': 'write_file',\n 'Edit': 'edit_file',\n 'Glob': 'find_file',\n 'Grep': 'search_content',\n 'Task': 'sub_task',\n 'WebFetch': 'web_fetch',\n 'WebSearch': 'web_search',\n};\n\n/** Parse a SKILL.md file content into frontmatter + body */\nexport function parseSkillMd(content: string, dirName?: string): ParsedSkill {\n const match = content.match(/^---\\r?\\n([\\s\\S]*?)\\r?\\n---\\r?\\n?([\\s\\S]*)$/);\n if (!match) {\n throw new SkillParseError('No valid frontmatter block found');\n }\n\n const rawFrontmatter = match[1];\n const body = match[2];\n\n let frontmatter: SkillFrontmatter;\n try {\n frontmatter = parseYaml(rawFrontmatter) as SkillFrontmatter;\n } catch (err) {\n throw new SkillParseError(`YAML parse error: ${(err as Error).message}`);\n }\n\n validateFrontmatter(frontmatter);\n\n // Infer name from directory if not provided in frontmatter\n if (!frontmatter.name && dirName) {\n frontmatter.name = dirName;\n }\n\n if (!frontmatter.name) {\n throw new SkillParseError('Missing \"name\" field and unable to infer from directory');\n }\n\n return { frontmatter, body, rawFrontmatter };\n}\n\n/** Validate required frontmatter fields */\nexport function validateFrontmatter(fm: SkillFrontmatter): void {\n if (fm.name !== undefined && typeof fm.name !== 'string') {\n throw new SkillParseError('Invalid \"name\" field — must be a string');\n }\n if (fm.version !== undefined && typeof fm.version !== 'string') {\n throw new SkillParseError('Invalid \"version\" field — must be a string');\n }\n if (fm['allowed-tools'] !== undefined && !Array.isArray(fm['allowed-tools'])) {\n throw new SkillParseError('Invalid \"allowed-tools\" field — must be an array');\n }\n}\n\n/** Infer abstract capabilities from allowed-tools list */\nexport function inferCapabilities(allowedTools: string[]): Capability[] {\n const caps = new Set<Capability>();\n for (const tool of allowedTools) {\n const cap = TOOL_CAPABILITY_MAP[tool];\n if (cap) {\n caps.add(cap);\n }\n }\n return [...caps];\n}\n\n/** Serialize a ParsedSkill back to SKILL.md format */\nexport function serializeSkillMd(parsed: ParsedSkill): string {\n const yamlStr = stringifyYaml(parsed.frontmatter, { lineWidth: 0 }).trimEnd();\n return `---\\n${yamlStr}\\n---\\n${parsed.body}`;\n}\n\n/** Search for SKILL.md files within a directory (looks in .claude/skills/*) */\nexport async function findSkillDirectory(dir: string): Promise<string | null> {\n const dirs = await findAllSkillDirectories(dir);\n return dirs.length > 0 ? dirs[0] : null;\n}\n\n/** Discover all directories containing SKILL.md within a source */\nexport async function findAllSkillDirectories(dir: string): Promise<string[]> {\n const results: string[] = [];\n\n // Direct SKILL.md in root\n if (existsSync(join(dir, 'SKILL.md'))) {\n results.push(dir);\n return results;\n }\n\n // Search in .claude/skills/*/SKILL.md\n const skillsRoot = join(dir, '.claude', 'skills');\n if (existsSync(skillsRoot)) {\n try {\n const entries = await readdir(skillsRoot, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isDirectory()) {\n const skillMdPath = join(skillsRoot, entry.name, 'SKILL.md');\n if (existsSync(skillMdPath)) {\n results.push(join(skillsRoot, entry.name));\n }\n }\n }\n } catch {\n // continue to next search strategy\n }\n }\n\n // Search one-level subdirectories for SKILL.md (skip hidden dirs)\n try {\n const topEntries = await readdir(dir, { withFileTypes: true });\n for (const entry of topEntries) {\n if (entry.isDirectory() && !entry.name.startsWith('.')) {\n const skillMdPath = join(dir, entry.name, 'SKILL.md');\n if (existsSync(skillMdPath)) {\n results.push(join(dir, entry.name));\n }\n }\n }\n } catch {\n // ignore\n }\n\n return results;\n}\n\n/** Read and parse a SKILL.md from a directory */\nexport async function readSkillMd(dir: string): Promise<ParsedSkill | null> {\n const content = await readTextSafe(join(dir, 'SKILL.md'));\n if (!content) return null;\n return parseSkillMd(content, basename(dir));\n}\n\n/** Extract env keys from a .env.example file */\nexport function extractEnvKeys(envExampleContent: string): string[] {\n const keys: string[] = [];\n for (const line of envExampleContent.split('\\n')) {\n const trimmed = line.trim();\n if (trimmed && !trimmed.startsWith('#')) {\n const match = trimmed.match(/^([A-Z_][A-Z0-9_]*)=/);\n if (match) {\n keys.push(match[1]);\n }\n }\n }\n return keys;\n}\n","import { join } from 'node:path';\nimport { existsSync } from 'node:fs';\nimport { readTextSafe, writeText, ensureDir } from '../utils/fs-helpers.js';\nimport { getSkillConfigPath, getSkillCanonicalPath } from '../utils/paths.js';\nimport * as logger from '../utils/logger.js';\nimport type { EnvStatus } from '../types/index.js';\n\n/** Parse a .env file content into key-value pairs */\nexport function parseEnvFile(content: string): Record<string, string> {\n const result: Record<string, string> = {};\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) continue;\n const eqIndex = trimmed.indexOf('=');\n if (eqIndex === -1) continue;\n const key = trimmed.slice(0, eqIndex).trim();\n let value = trimmed.slice(eqIndex + 1).trim();\n // Strip surrounding quotes\n if ((value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))) {\n value = value.slice(1, -1);\n }\n result[key] = value;\n }\n return result;\n}\n\n/** Serialize key-value pairs back to .env format */\nexport function serializeEnv(data: Record<string, string>): string {\n return Object.entries(data)\n .map(([key, value]) => `${key}=${value}`)\n .join('\\n') + '\\n';\n}\n\n/**\n * Backup .env for a skill, searching multiple locations by priority:\n * 1. ~/.agents/config/<skill>/.env (persistent)\n * 2. agentSkillDir/.env (current agent dir, e.g. .claude/skills/<skill>)\n * 3. ~/.agents/skills/<skill>/.env (canonical)\n */\nexport async function backupEnv(\n skillName: string,\n agentSkillDir?: string,\n): Promise<Record<string, string> | null> {\n const locations = [\n join(getSkillConfigPath(skillName), '.env'),\n ...(agentSkillDir ? [join(agentSkillDir, '.env')] : []),\n join(getSkillCanonicalPath(skillName), '.env'),\n ];\n\n for (const loc of locations) {\n const content = await readTextSafe(loc);\n if (content) {\n const data = parseEnvFile(content);\n if (Object.keys(data).length > 0) {\n logger.debug(`Backed up .env from ${loc}`);\n return data;\n }\n }\n }\n\n return null;\n}\n\n/**\n * Restore .env to both persistent and skill directory locations.\n * Merges with .env.example if present.\n */\nexport async function restoreEnv(\n skillName: string,\n envData: Record<string, string>,\n skillDir: string,\n): Promise<void> {\n // Read .env.example from skill dir if exists\n const exampleContent = await readTextSafe(join(skillDir, '.env.example'));\n let finalContent: string;\n\n if (exampleContent) {\n finalContent = mergeEnv(envData, exampleContent);\n } else {\n finalContent = serializeEnv(envData);\n }\n\n // Write to persistent config location\n const configEnvPath = join(getSkillConfigPath(skillName), '.env');\n await writeText(configEnvPath, finalContent);\n\n // Write to skill directory (for compatibility with loadApiKey)\n const skillEnvPath = join(skillDir, '.env');\n await writeText(skillEnvPath, finalContent);\n\n logger.debug(`Restored .env to ${configEnvPath} and ${skillEnvPath}`);\n}\n\n/**\n * Merge existing env data with .env.example template.\n * - Existing keys are NEVER overwritten\n * - New keys from example are appended with empty values and comments\n */\nexport function mergeEnv(\n existing: Record<string, string>,\n exampleContent: string,\n): string {\n const lines: string[] = [];\n const usedKeys = new Set<string>();\n\n // First, write all existing keys\n for (const [key, value] of Object.entries(existing)) {\n lines.push(`${key}=${value}`);\n usedKeys.add(key);\n }\n\n // Then, append new keys from example\n const exampleKeys = parseEnvFile(exampleContent);\n const newKeys = Object.keys(exampleKeys).filter(k => !usedKeys.has(k));\n\n if (newKeys.length > 0) {\n lines.push('');\n lines.push('# New keys added by skill update (please configure):');\n for (const key of newKeys) {\n lines.push(`# ${key}=`);\n }\n }\n\n return lines.join('\\n') + '\\n';\n}\n\n/** Check the .env configuration status for a skill */\nexport async function getEnvStatus(\n skillName: string,\n requiredKeys: string[],\n): Promise<EnvStatus> {\n if (requiredKeys.length === 0) return 'configured';\n\n const configEnvPath = join(getSkillConfigPath(skillName), '.env');\n const content = await readTextSafe(configEnvPath);\n\n if (!content) return 'missing';\n\n const data = parseEnvFile(content);\n const configuredKeys = Object.entries(data)\n .filter(([, v]) => v && !v.includes('your_') && !v.includes('_here'))\n .map(([k]) => k);\n\n const allConfigured = requiredKeys.every(k => configuredKeys.includes(k));\n const someConfigured = requiredKeys.some(k => configuredKeys.includes(k));\n\n if (allConfigured) return 'configured';\n if (someConfigured) return 'partial';\n return 'missing';\n}\n\n/** Set a single env value for a skill */\nexport async function setEnvValue(\n skillName: string,\n key: string,\n value: string,\n skillDir?: string,\n): Promise<void> {\n const configEnvPath = join(getSkillConfigPath(skillName), '.env');\n const content = await readTextSafe(configEnvPath);\n const data = content ? parseEnvFile(content) : {};\n\n data[key] = value;\n const newContent = serializeEnv(data);\n\n // Write to persistent location\n await writeText(configEnvPath, newContent);\n\n // Sync to skill directory if provided\n if (skillDir) {\n await writeText(join(skillDir, '.env'), newContent);\n }\n}\n\n/** Get the .env file path for editing */\nexport function getEnvEditPath(skillName: string): string {\n return join(getSkillConfigPath(skillName), '.env');\n}\n","import { homedir } from 'node:os';\nimport { join } from 'node:path';\n\n/** Root directory for all skill-master data */\nexport const AGENTS_HOME = join(homedir(), '.agents');\n\n/** Persistent user config (API keys etc.) */\nexport const CONFIG_DIR = join(AGENTS_HOME, 'config');\n\n/** Canonical skill code storage */\nexport const SKILLS_DIR = join(AGENTS_HOME, 'skills');\n\n/** Registry file path */\nexport const REGISTRY_PATH = join(AGENTS_HOME, 'registry.json');\n\n/** Get canonical path for a skill's code */\nexport function getSkillCanonicalPath(name: string): string {\n return join(SKILLS_DIR, name);\n}\n\n/** Get persistent config path for a skill (holds .env) */\nexport function getSkillConfigPath(name: string): string {\n return join(CONFIG_DIR, name);\n}\n\n// Re-export from agents.ts — eliminates duplicate AGENT_SKILL_DIRS mapping\nexport { getAgentSkillPath, getAgentSkillsRoot } from '../platform/agents.js';\n","import { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { homedir } from 'node:os';\n\nconst home = homedir();\nconst configHome = process.env.XDG_CONFIG_HOME?.trim() || join(home, '.config');\nconst codexHome = process.env.CODEX_HOME?.trim() || join(home, '.codex');\nconst claudeHome = process.env.CLAUDE_CONFIG_DIR?.trim() || join(home, '.claude');\n\nexport interface AgentConfig {\n name: string;\n displayName: string;\n skillsDir: string;\n globalSkillsDir: string;\n detectMarker?: string;\n}\n\nexport const AGENTS = {\n amp: {\n name: 'amp',\n displayName: 'Amp',\n skillsDir: '.agents/skills',\n globalSkillsDir: join(configHome, 'agents/skills'),\n },\n antigravity: {\n name: 'antigravity',\n displayName: 'Antigravity',\n skillsDir: '.agent/skills',\n globalSkillsDir: join(home, '.gemini/antigravity/skills'),\n detectMarker: '.agent',\n },\n augment: {\n name: 'augment',\n displayName: 'Augment',\n skillsDir: '.augment/skills',\n globalSkillsDir: join(home, '.augment/skills'),\n detectMarker: '.augment',\n },\n 'claude-code': {\n name: 'claude-code',\n displayName: 'Claude Code',\n skillsDir: '.claude/skills',\n globalSkillsDir: join(claudeHome, 'skills'),\n detectMarker: '.claude',\n },\n openclaw: {\n name: 'openclaw',\n displayName: 'OpenClaw',\n skillsDir: 'skills',\n globalSkillsDir: join(home, '.openclaw/skills'),\n },\n cline: {\n name: 'cline',\n displayName: 'Cline',\n skillsDir: '.cline/skills',\n globalSkillsDir: join(home, '.cline/skills'),\n detectMarker: '.cline',\n },\n codebuddy: {\n name: 'codebuddy',\n displayName: 'CodeBuddy',\n skillsDir: '.codebuddy/skills',\n globalSkillsDir: join(home, '.codebuddy/skills'),\n detectMarker: '.codebuddy',\n },\n codex: {\n name: 'codex',\n displayName: 'Codex',\n skillsDir: '.agents/skills',\n globalSkillsDir: join(codexHome, 'skills'),\n },\n 'command-code': {\n name: 'command-code',\n displayName: 'Command Code',\n skillsDir: '.commandcode/skills',\n globalSkillsDir: join(home, '.commandcode/skills'),\n detectMarker: '.commandcode',\n },\n continue: {\n name: 'continue',\n displayName: 'Continue',\n skillsDir: '.continue/skills',\n globalSkillsDir: join(home, '.continue/skills'),\n detectMarker: '.continue',\n },\n crush: {\n name: 'crush',\n displayName: 'Crush',\n skillsDir: '.crush/skills',\n globalSkillsDir: join(home, '.config/crush/skills'),\n },\n cursor: {\n name: 'cursor',\n displayName: 'Cursor',\n skillsDir: '.cursor/skills',\n globalSkillsDir: join(home, '.cursor/skills'),\n detectMarker: '.cursor',\n },\n droid: {\n name: 'droid',\n displayName: 'Droid',\n skillsDir: '.factory/skills',\n globalSkillsDir: join(home, '.factory/skills'),\n detectMarker: '.factory',\n },\n 'gemini-cli': {\n name: 'gemini-cli',\n displayName: 'Gemini CLI',\n skillsDir: '.agents/skills',\n globalSkillsDir: join(home, '.gemini/skills'),\n },\n 'github-copilot': {\n name: 'github-copilot',\n displayName: 'GitHub Copilot',\n skillsDir: '.agents/skills',\n globalSkillsDir: join(home, '.copilot/skills'),\n },\n goose: {\n name: 'goose',\n displayName: 'Goose',\n skillsDir: '.goose/skills',\n globalSkillsDir: join(configHome, 'goose/skills'),\n detectMarker: '.goose',\n },\n junie: {\n name: 'junie',\n displayName: 'Junie',\n skillsDir: '.junie/skills',\n globalSkillsDir: join(home, '.junie/skills'),\n detectMarker: '.junie',\n },\n 'iflow-cli': {\n name: 'iflow-cli',\n displayName: 'iFlow CLI',\n skillsDir: '.iflow/skills',\n globalSkillsDir: join(home, '.iflow/skills'),\n detectMarker: '.iflow',\n },\n kilo: {\n name: 'kilo',\n displayName: 'Kilo Code',\n skillsDir: '.kilocode/skills',\n globalSkillsDir: join(home, '.kilocode/skills'),\n detectMarker: '.kilocode',\n },\n 'kimi-cli': {\n name: 'kimi-cli',\n displayName: 'Kimi Code CLI',\n skillsDir: '.agents/skills',\n globalSkillsDir: join(home, '.config/agents/skills'),\n },\n 'kiro-cli': {\n name: 'kiro-cli',\n displayName: 'Kiro CLI',\n skillsDir: '.kiro/skills',\n globalSkillsDir: join(home, '.kiro/skills'),\n detectMarker: '.kiro',\n },\n kode: {\n name: 'kode',\n displayName: 'Kode',\n skillsDir: '.kode/skills',\n globalSkillsDir: join(home, '.kode/skills'),\n detectMarker: '.kode',\n },\n mcpjam: {\n name: 'mcpjam',\n displayName: 'MCPJam',\n skillsDir: '.mcpjam/skills',\n globalSkillsDir: join(home, '.mcpjam/skills'),\n detectMarker: '.mcpjam',\n },\n 'mistral-vibe': {\n name: 'mistral-vibe',\n displayName: 'Mistral Vibe',\n skillsDir: '.vibe/skills',\n globalSkillsDir: join(home, '.vibe/skills'),\n detectMarker: '.vibe',\n },\n mux: {\n name: 'mux',\n displayName: 'Mux',\n skillsDir: '.mux/skills',\n globalSkillsDir: join(home, '.mux/skills'),\n detectMarker: '.mux',\n },\n opencode: {\n name: 'opencode',\n displayName: 'OpenCode',\n skillsDir: '.opencode/skills',\n globalSkillsDir: join(configHome, 'opencode/skills'),\n },\n openhands: {\n name: 'openhands',\n displayName: 'OpenHands',\n skillsDir: '.openhands/skills',\n globalSkillsDir: join(home, '.openhands/skills'),\n detectMarker: '.openhands',\n },\n pi: {\n name: 'pi',\n displayName: 'Pi',\n skillsDir: '.pi/skills',\n globalSkillsDir: join(home, '.pi/agent/skills'),\n detectMarker: '.pi',\n },\n qoder: {\n name: 'qoder',\n displayName: 'Qoder',\n skillsDir: '.qoder/skills',\n globalSkillsDir: join(home, '.qoder/skills'),\n detectMarker: '.qoder',\n },\n 'qwen-code': {\n name: 'qwen-code',\n displayName: 'Qwen Code',\n skillsDir: '.qwen/skills',\n globalSkillsDir: join(home, '.qwen/skills'),\n detectMarker: '.qwen',\n },\n replit: {\n name: 'replit',\n displayName: 'Replit',\n skillsDir: '.agents/skills',\n globalSkillsDir: join(configHome, 'agents/skills'),\n },\n roo: {\n name: 'roo',\n displayName: 'Roo Code',\n skillsDir: '.roo/skills',\n globalSkillsDir: join(home, '.roo/skills'),\n detectMarker: '.roo',\n },\n trae: {\n name: 'trae',\n displayName: 'Trae',\n skillsDir: '.trae/skills',\n globalSkillsDir: join(home, '.trae/skills'),\n detectMarker: '.trae',\n },\n 'trae-cn': {\n name: 'trae-cn',\n displayName: 'Trae CN',\n skillsDir: '.trae/skills',\n globalSkillsDir: join(home, '.trae-cn/skills'),\n },\n windsurf: {\n name: 'windsurf',\n displayName: 'Windsurf',\n skillsDir: '.windsurf/skills',\n globalSkillsDir: join(home, '.codeium/windsurf/skills'),\n detectMarker: '.windsurf',\n },\n zencoder: {\n name: 'zencoder',\n displayName: 'Zencoder',\n skillsDir: '.zencoder/skills',\n globalSkillsDir: join(home, '.zencoder/skills'),\n detectMarker: '.zencoder',\n },\n neovate: {\n name: 'neovate',\n displayName: 'Neovate',\n skillsDir: '.neovate/skills',\n globalSkillsDir: join(home, '.neovate/skills'),\n detectMarker: '.neovate',\n },\n pochi: {\n name: 'pochi',\n displayName: 'Pochi',\n skillsDir: '.pochi/skills',\n globalSkillsDir: join(home, '.pochi/skills'),\n detectMarker: '.pochi',\n },\n adal: {\n name: 'adal',\n displayName: 'AdaL',\n skillsDir: '.adal/skills',\n globalSkillsDir: join(home, '.adal/skills'),\n detectMarker: '.adal',\n },\n} as const satisfies Record<string, AgentConfig>;\n\nexport type AgentPlatform = keyof typeof AGENTS;\n\n/** Get config for a specific agent */\nexport function getAgentConfig(type: AgentPlatform): AgentConfig {\n return AGENTS[type];\n}\n\n/** List all supported platform keys */\nexport function getSupportedPlatforms(): AgentPlatform[] {\n return Object.keys(AGENTS) as AgentPlatform[];\n}\n\n/** Detect current platform by checking cwd for directory markers */\nexport function detectPlatform(cwd: string): AgentPlatform {\n for (const [key, config] of Object.entries(AGENTS) as Array<[AgentPlatform, AgentConfig]>) {\n if (config.detectMarker && existsSync(join(cwd, config.detectMarker))) {\n return key;\n }\n }\n\n // Fallback: check opencode via global config\n if (existsSync(join(configHome, 'opencode'))) {\n return 'opencode';\n }\n\n return 'claude-code';\n}\n\n/** Get the project-level skills directory name for an agent */\nexport function getAgentSkillsDir(platform: AgentPlatform): string {\n return AGENTS[platform].skillsDir;\n}\n\n/** Get full skill installation path: cwd + skillsDir + skillName */\nexport function getAgentSkillPath(cwd: string, agent: AgentPlatform, name: string): string {\n return join(cwd, AGENTS[agent].skillsDir, name);\n}\n\n/** Get the agent skills root directory: cwd + skillsDir */\nexport function getAgentSkillsRoot(cwd: string, agent: AgentPlatform): string {\n return join(cwd, AGENTS[agent].skillsDir);\n}\n","import { existsSync } from 'node:fs';\nimport { REGISTRY_PATH } from '../utils/paths.js';\nimport { atomicWriteJson, readJsonSafe } from '../utils/fs-helpers.js';\nimport { RegistryCorruptError } from '../utils/errors.js';\nimport type { Registry, RegistryEntry } from '../types/index.js';\n\n/** Create an empty registry */\nfunction createEmptyRegistry(): Registry {\n return { version: 1, skills: {} };\n}\n\n/** Validate registry structure */\nfunction validateRegistry(data: unknown): data is Registry {\n if (!data || typeof data !== 'object') return false;\n const reg = data as Record<string, unknown>;\n return reg.version === 1 && typeof reg.skills === 'object' && reg.skills !== null;\n}\n\n/** Read the registry, creating a new one if it doesn't exist */\nexport async function readRegistry(): Promise<Registry> {\n if (!existsSync(REGISTRY_PATH)) {\n return createEmptyRegistry();\n }\n\n const data = await readJsonSafe<Registry>(REGISTRY_PATH);\n if (!data) {\n throw new RegistryCorruptError('Failed to parse registry.json');\n }\n\n if (!validateRegistry(data)) {\n throw new RegistryCorruptError('Invalid registry structure');\n }\n\n return data;\n}\n\n/** Update or add a skill entry in the registry (atomic write) */\nexport async function updateRegistry(\n skillName: string,\n entry: RegistryEntry,\n): Promise<void> {\n const registry = await readRegistry();\n registry.skills[skillName] = entry;\n await atomicWriteJson(REGISTRY_PATH, registry);\n}\n\n/** Remove a skill from the registry */\nexport async function removeFromRegistry(skillName: string): Promise<void> {\n const registry = await readRegistry();\n delete registry.skills[skillName];\n await atomicWriteJson(REGISTRY_PATH, registry);\n}\n\n/** List all registered skills */\nexport async function listRegistry(): Promise<Record<string, RegistryEntry>> {\n const registry = await readRegistry();\n return registry.skills;\n}\n\n/** Get a single registry entry */\nexport async function getRegistryEntry(skillName: string): Promise<RegistryEntry | null> {\n const registry = await readRegistry();\n return registry.skills[skillName] ?? null;\n}","import { installSkill } from '../core/installer.js';\nimport { cloneRepo, isGitUrl } from '../core/git-source.js';\nimport { findAllSkillDirectories, readSkillMd } from '../core/skill-parser.js';\nimport { SkillNotFoundError } from '../utils/errors.js';\nimport * as logger from '../utils/logger.js';\nimport type { SkillSource, AgentPlatform } from '../types/index.js';\nimport { existsSync } from 'node:fs';\nimport { basename } from 'node:path';\n\nexport interface AddFlags {\n global: boolean;\n agent: string[];\n skill: string[];\n yes: boolean;\n list: boolean;\n all: boolean;\n fullDepth: boolean;\n copy: boolean;\n force: boolean;\n}\n\n/**\n * Parse POSIX-style flags for the add command.\n * Supports: -g/--global, -a/--agent, -s/--skill, -y/--yes,\n * -l/--list, --all, --full-depth, --copy, --force\n */\nexport function parseAddFlags(args: string[]): { source: string | null; flags: AddFlags } {\n const flags: AddFlags = {\n global: false,\n agent: [],\n skill: [],\n yes: false,\n list: false,\n all: false,\n fullDepth: false,\n copy: false,\n force: false,\n };\n\n let source: string | null = null;\n let i = 0;\n\n while (i < args.length) {\n const arg = args[i];\n\n // Long flags with = syntax (backward compat: --agent=claude-code)\n if (arg.startsWith('--') && arg.includes('=')) {\n const eqIdx = arg.indexOf('=');\n const key = arg.slice(2, eqIdx);\n const val = arg.slice(eqIdx + 1);\n switch (key) {\n case 'agent': flags.agent.push(val); break;\n case 'skill': flags.skill.push(val); break;\n default:\n throw new Error(`Unknown option: --${key}`);\n }\n i++;\n continue;\n }\n\n switch (arg) {\n case '-g':\n case '--global':\n flags.global = true;\n i++;\n break;\n\n case '-a':\n case '--agent':\n // Consume following non-flag args as agent names\n i++;\n while (i < args.length && !args[i].startsWith('-')) {\n flags.agent.push(args[i]);\n i++;\n }\n break;\n\n case '-s':\n case '--skill':\n // Consume following non-flag args as skill names\n i++;\n while (i < args.length && !args[i].startsWith('-')) {\n flags.skill.push(args[i]);\n i++;\n }\n break;\n\n case '-y':\n case '--yes':\n flags.yes = true;\n i++;\n break;\n\n case '-l':\n case '--list':\n flags.list = true;\n i++;\n break;\n\n case '--all':\n flags.all = true;\n i++;\n break;\n\n case '--full-depth':\n flags.fullDepth = true;\n i++;\n break;\n\n case '--copy':\n flags.copy = true;\n i++;\n break;\n\n case '--force':\n flags.force = true;\n i++;\n break;\n\n default:\n // First non-flag argument is the source\n if (!arg.startsWith('-') && source === null) {\n source = arg;\n } else if (arg.startsWith('-')) {\n throw new Error(`Unknown option: ${arg}`);\n }\n i++;\n break;\n }\n }\n\n // --all implies --skill '*' --agent '*' -y\n if (flags.all) {\n if (flags.skill.length === 0) flags.skill.push('*');\n if (flags.agent.length === 0) flags.agent.push('*');\n flags.yes = true;\n }\n\n return { source, flags };\n}\n\n/** add command — install skills (compatible with `npx skills add`) */\nexport async function add(args: string[]): Promise<void> {\n if (args.length === 0) {\n logger.error('Usage: skill-master add <source> [options]');\n console.log('');\n console.log('Options:');\n console.log(' -g, --global Install globally (~/.agents/)');\n console.log(' -a, --agent <agents> Target agents (space-separated)');\n console.log(' -s, --skill <skills> Select skills (space-separated)');\n console.log(' -y, --yes Skip confirmations');\n console.log(' -l, --list List available skills without installing');\n console.log(' --all Install all skills to all agents');\n console.log(' --full-depth Search all subdirectories');\n console.log(' --copy Copy instead of symlink');\n console.log(' --force Force reinstall');\n process.exit(1);\n }\n\n const { source, flags } = parseAddFlags(args);\n\n if (!source) {\n logger.error('No source specified. Provide a GitHub URL, owner/repo, or local path.');\n process.exit(1);\n }\n\n const cwd = process.cwd();\n\n // Resolve source directory (clone once for git sources)\n let sourceDir: string;\n const isGit = isGitUrl(source);\n\n if (isGit) {\n logger.step(1, 9, 'Fetching skill source...');\n sourceDir = await cloneRepo(source);\n } else {\n sourceDir = source;\n if (!existsSync(sourceDir)) {\n throw new SkillNotFoundError(sourceDir);\n }\n }\n\n // Discover all skill directories in the source\n const allSkillDirs = await findAllSkillDirectories(sourceDir);\n if (allSkillDirs.length === 0) {\n throw new SkillNotFoundError(`No SKILL.md found in ${sourceDir}`);\n }\n\n // Filter by --skill if specified\n let targetDirs = allSkillDirs;\n if (flags.skill.length > 0 && !flags.skill.includes('*')) {\n const requested = new Set(flags.skill.map(s => s.toLowerCase()));\n const filtered: string[] = [];\n\n for (const dir of allSkillDirs) {\n const parsed = await readSkillMd(dir);\n if (!parsed) continue;\n const name = parsed.frontmatter.name.toLowerCase();\n const dirName = basename(dir).toLowerCase();\n if (requested.has(name) || requested.has(dirName)) {\n filtered.push(dir);\n }\n }\n\n if (filtered.length === 0) {\n const available = [];\n for (const dir of allSkillDirs) {\n const parsed = await readSkillMd(dir);\n if (parsed) available.push(parsed.frontmatter.name);\n }\n logger.error(\n `No matching skills found for: ${flags.skill.join(', ')}\\n` +\n ` Available skills: ${available.join(', ')}`\n );\n process.exit(1);\n }\n\n targetDirs = filtered;\n }\n\n // If multiple agents specified, install for each\n const agents = flags.agent.length > 0 ? flags.agent : [undefined];\n\n try {\n for (const dir of targetDirs) {\n for (const agent of agents) {\n await installSkill({\n source: { type: 'local', path: dir },\n agent: agent as AgentPlatform | undefined,\n cwd,\n copy: flags.copy,\n force: flags.force,\n yes: flags.yes,\n });\n }\n }\n } catch (err) {\n logger.error((err as Error).message);\n process.exit(1);\n }\n}\n","import { getRegistryEntry } from '../core/registry.js';\nimport { installSkill } from '../core/installer.js';\nimport { isGitUrl } from '../core/git-source.js';\nimport * as logger from '../utils/logger.js';\nimport { SkillNotFoundError } from '../utils/errors.js';\nimport type { SkillSource } from '../types/index.js';\n\nexport async function update(args: string[]): Promise<void> {\n if (args.length === 0) {\n logger.error('Usage: skill-master update <skill-name> [--force]');\n process.exit(1);\n }\n\n const skillName = args[0];\n const force = args.includes('--force');\n\n try {\n const entry = await getRegistryEntry(skillName);\n if (!entry) {\n throw new SkillNotFoundError(skillName);\n }\n\n logger.info(`Updating skill: ${skillName}`);\n logger.info(`Source: ${entry.source}`);\n\n const source: SkillSource = isGitUrl(entry.source)\n ? { type: 'git', url: entry.source }\n : { type: 'local', path: entry.source };\n\n await installSkill({\n source,\n agent: entry.agent,\n cwd: process.cwd(),\n force: true,\n });\n\n logger.success(`Skill \"${skillName}\" updated successfully!`);\n } catch (err) {\n logger.error((err as Error).message);\n process.exit(1);\n }\n}\n","import { getRegistryEntry, removeFromRegistry, listRegistry } from '../core/registry.js';\nimport { removePath } from '../utils/fs-helpers.js';\nimport { getSkillCanonicalPath, getSkillConfigPath } from '../utils/paths.js';\nimport * as logger from '../utils/logger.js';\nimport { SkillNotFoundError } from '../utils/errors.js';\n\nexport interface RemoveFlags {\n global: boolean;\n agent: string[];\n skill: string[];\n yes: boolean;\n all: boolean;\n purge: boolean;\n}\n\n/** Parse POSIX-style flags for the remove command */\nexport function parseRemoveFlags(args: string[]): { names: string[]; flags: RemoveFlags } {\n const flags: RemoveFlags = {\n global: false,\n agent: [],\n skill: [],\n yes: false,\n all: false,\n purge: false,\n };\n\n const names: string[] = [];\n let i = 0;\n\n while (i < args.length) {\n const arg = args[i];\n\n // Long flags with = syntax (backward compat: --agent=claude-code)\n if (arg.startsWith('--') && arg.includes('=')) {\n const eqIdx = arg.indexOf('=');\n const key = arg.slice(2, eqIdx);\n const val = arg.slice(eqIdx + 1);\n switch (key) {\n case 'agent': flags.agent.push(val); break;\n case 'skill': flags.skill.push(val); break;\n default:\n throw new Error(`Unknown option: --${key}`);\n }\n i++;\n continue;\n }\n\n switch (arg) {\n case '-g':\n case '--global':\n flags.global = true;\n i++;\n break;\n\n case '-a':\n case '--agent':\n i++;\n while (i < args.length && !args[i].startsWith('-')) {\n flags.agent.push(args[i]);\n i++;\n }\n break;\n\n case '-s':\n case '--skill':\n i++;\n while (i < args.length && !args[i].startsWith('-')) {\n flags.skill.push(args[i]);\n i++;\n }\n break;\n\n case '-y':\n case '--yes':\n flags.yes = true;\n i++;\n break;\n\n case '--all':\n flags.all = true;\n i++;\n break;\n\n case '--purge':\n flags.purge = true;\n i++;\n break;\n\n default:\n // Non-flag arguments are skill names (positional)\n if (!arg.startsWith('-')) {\n names.push(arg);\n } else {\n throw new Error(`Unknown option: ${arg}`);\n }\n i++;\n break;\n }\n }\n\n // --all implies removing all skills with -y\n if (flags.all) {\n flags.yes = true;\n }\n\n return { names, flags };\n}\n\n/** remove command — remove installed skills */\nexport async function remove(args: string[]): Promise<void> {\n if (args.length === 0) {\n logger.error('Usage: skill-master remove [skills...] [options]');\n console.log('');\n console.log('Options:');\n console.log(' -g, --global Remove from global (~/.agents/)');\n console.log(' -a, --agent <agents> Target agents (space-separated)');\n console.log(' -s, --skill <skills> Select skills (space-separated)');\n console.log(' -y, --yes Skip confirmations');\n console.log(' --all Remove all skills');\n console.log(' --purge Also remove config data');\n process.exit(1);\n }\n\n const { names, flags } = parseRemoveFlags(args);\n\n // Determine which skills to remove\n let skillNames: string[];\n if (flags.all) {\n const registry = await listRegistry();\n skillNames = Object.keys(registry);\n } else if (flags.skill.length > 0) {\n skillNames = flags.skill;\n } else {\n skillNames = names;\n }\n\n if (skillNames.length === 0) {\n logger.error('No skills specified. Provide skill names or use --all.');\n process.exit(1);\n }\n\n try {\n for (const skillName of skillNames) {\n const entry = await getRegistryEntry(skillName);\n if (!entry) {\n throw new SkillNotFoundError(skillName);\n }\n\n logger.info(`Removing skill: ${skillName}`);\n\n // Remove agent directory link/copy\n await removePath(entry.agent_path);\n logger.success(`Removed from ${entry.agent_path}`);\n\n // Remove canonical directory\n await removePath(entry.canonical_path);\n logger.success(`Removed from ${entry.canonical_path}`);\n\n // Optionally purge config\n if (flags.purge) {\n await removePath(getSkillConfigPath(skillName));\n logger.success('Purged config directory');\n }\n\n // Update registry\n await removeFromRegistry(skillName);\n logger.success(`Skill \"${skillName}\" removed successfully!`);\n }\n } catch (err) {\n logger.error((err as Error).message);\n process.exit(1);\n }\n}\n","import { listRegistry } from '../core/registry.js';\nimport { getEnvStatus, setEnvValue, getEnvEditPath } from '../core/env-manager.js';\nimport { getSkillCanonicalPath } from '../utils/paths.js';\nimport * as logger from '../utils/logger.js';\nimport { spawn } from 'node:child_process';\n\nexport async function env(args: string[]): Promise<void> {\n const subcommand = args[0];\n\n if (!subcommand || subcommand === 'list') {\n await envList();\n } else if (subcommand === 'set') {\n await envSet(args.slice(1));\n } else if (subcommand === 'edit') {\n await envEdit(args.slice(1));\n } else {\n logger.error('Usage: skill-master env <list|set|edit>');\n process.exit(1);\n }\n}\n\nasync function envList(): Promise<void> {\n const skills = await listRegistry();\n const entries = Object.entries(skills);\n\n if (entries.length === 0) {\n logger.info('No skills installed');\n return;\n }\n\n logger.blank();\n logger.tableHeader('Skill', 'Status', 'Keys');\n\n for (const [name, entry] of entries) {\n const status = await getEnvStatus(name, entry.env_keys);\n const statusIcon = status === 'configured' ? '✓' : status === 'partial' ? '⚠' : '✗';\n logger.tableRow(name, `${statusIcon} ${status}`, entry.env_keys.join(', '));\n }\n logger.blank();\n}\n\nasync function envSet(args: string[]): Promise<void> {\n if (args.length < 2) {\n logger.error('Usage: skill-master env set <skill> KEY=VALUE');\n process.exit(1);\n }\n\n const skillName = args[0];\n const [key, value] = args[1].split('=');\n\n if (!key || !value) {\n logger.error('Invalid format. Use: KEY=VALUE');\n process.exit(1);\n }\n\n try {\n const skillDir = getSkillCanonicalPath(skillName);\n await setEnvValue(skillName, key, value, skillDir);\n logger.success(`Set ${key} for ${skillName}`);\n } catch (err) {\n logger.error((err as Error).message);\n process.exit(1);\n }\n}\n\nasync function envEdit(args: string[]): Promise<void> {\n if (args.length === 0) {\n logger.error('Usage: skill-master env edit <skill>');\n process.exit(1);\n }\n\n const skillName = args[0];\n const envPath = getEnvEditPath(skillName);\n const editor = process.env.EDITOR || 'vi';\n\n logger.info(`Opening ${envPath} with ${editor}...`);\n\n const child = spawn(editor, [envPath], {\n stdio: 'inherit',\n shell: true,\n });\n\n child.on('exit', (code) => {\n if (code === 0) {\n logger.success('Saved');\n } else {\n logger.error('Editor exited with error');\n process.exit(1);\n }\n });\n}\n","import { listRegistry } from '../core/registry.js';\nimport * as logger from '../utils/logger.js';\n\nexport interface ListFlags {\n global: boolean;\n agent: string[];\n}\n\n/** Parse flags for the list command */\nexport function parseListFlags(args: string[]): ListFlags {\n const flags: ListFlags = {\n global: false,\n agent: [],\n };\n\n let i = 0;\n while (i < args.length) {\n const arg = args[i];\n\n if (arg.startsWith('--') && arg.includes('=')) {\n const eqIdx = arg.indexOf('=');\n const key = arg.slice(2, eqIdx);\n const val = arg.slice(eqIdx + 1);\n if (key === 'agent') flags.agent.push(val);\n i++;\n continue;\n }\n\n switch (arg) {\n case '-g':\n case '--global':\n flags.global = true;\n i++;\n break;\n case '-a':\n case '--agent':\n i++;\n while (i < args.length && !args[i].startsWith('-')) {\n flags.agent.push(args[i]);\n i++;\n }\n break;\n default:\n i++;\n break;\n }\n }\n\n return flags;\n}\n\n/** list command — list installed skills */\nexport async function list(args: string[] = []): Promise<void> {\n const flags = parseListFlags(args);\n const skills = await listRegistry();\n let entries = Object.entries(skills);\n\n // Filter by agent if specified\n if (flags.agent.length > 0) {\n entries = entries.filter(([, entry]) => flags.agent.includes(entry.agent));\n }\n\n if (entries.length === 0) {\n logger.info('No skills installed');\n return;\n }\n\n logger.blank();\n logger.tableHeader('Skill', 'Version', 'Platform', 'Installed');\n\n for (const [name, entry] of entries) {\n const date = new Date(entry.installed_at).toLocaleDateString();\n logger.tableRow(name, entry.version ?? '-', entry.agent, date);\n }\n logger.blank();\n}\n","import { getRegistryEntry } from '../core/registry.js';\nimport { getEnvStatus } from '../core/env-manager.js';\nimport * as logger from '../utils/logger.js';\nimport { SkillNotFoundError } from '../utils/errors.js';\n\nexport async function info(args: string[]): Promise<void> {\n if (args.length === 0) {\n logger.error('Usage: skill-master info <skill-name>');\n process.exit(1);\n }\n\n const skillName = args[0];\n\n try {\n const entry = await getRegistryEntry(skillName);\n if (!entry) {\n throw new SkillNotFoundError(skillName);\n }\n\n const envStatus = await getEnvStatus(skillName, entry.env_keys);\n\n logger.blank();\n logger.info(`Skill: ${skillName}`);\n logger.kv('Version', entry.version ?? '-');\n logger.kv('Platform', entry.agent);\n logger.kv('Source', entry.source);\n logger.kv('Installed', new Date(entry.installed_at).toLocaleString());\n logger.kv('Updated', new Date(entry.updated_at).toLocaleString());\n logger.kv('Canonical Path', entry.canonical_path);\n logger.kv('Agent Path', entry.agent_path);\n logger.kv('Capabilities', entry.capabilities.join(', '));\n logger.kv('Env Keys', entry.env_keys.join(', ') || 'none');\n logger.kv('Env Status', envStatus);\n logger.blank();\n } catch (err) {\n logger.error((err as Error).message);\n process.exit(1);\n }\n}\n","import { existsSync } from 'node:fs';\nimport { listRegistry } from '../core/registry.js';\nimport { getEnvStatus } from '../core/env-manager.js';\nimport { isSymlink } from '../utils/fs-helpers.js';\nimport { AGENTS_HOME, CONFIG_DIR, SKILLS_DIR, REGISTRY_PATH } from '../utils/paths.js';\nimport * as logger from '../utils/logger.js';\n\nexport async function doctor(): Promise<void> {\n logger.blank();\n logger.info('Running diagnostics...');\n logger.blank();\n\n let issues = 0;\n\n // Check directory structure\n logger.info('Checking directory structure...');\n const dirs = [AGENTS_HOME, CONFIG_DIR, SKILLS_DIR];\n for (const dir of dirs) {\n if (existsSync(dir)) {\n logger.success(`✓ ${dir}`);\n } else {\n logger.warn(`✗ ${dir} (missing)`);\n issues++;\n }\n }\n logger.blank();\n\n // Check registry\n logger.info('Checking registry...');\n if (existsSync(REGISTRY_PATH)) {\n logger.success(`✓ ${REGISTRY_PATH}`);\n try {\n const skills = await listRegistry();\n logger.info(` Found ${Object.keys(skills).length} skill(s)`);\n } catch (err) {\n logger.error(`✗ Registry corrupted: ${(err as Error).message}`);\n issues++;\n }\n } else {\n logger.info(` No registry found (will be created on first install)`);\n }\n logger.blank();\n\n // Check each skill\n logger.info('Checking installed skills...');\n try {\n const skills = await listRegistry();\n for (const [name, entry] of Object.entries(skills)) {\n logger.info(`Skill: ${name}`);\n\n // Check canonical path\n if (existsSync(entry.canonical_path)) {\n logger.success(` ✓ Canonical path exists`);\n } else {\n logger.error(` ✗ Canonical path missing: ${entry.canonical_path}`);\n issues++;\n }\n\n // Check agent path\n if (existsSync(entry.agent_path)) {\n const isLink = await isSymlink(entry.agent_path);\n logger.success(` ✓ Agent path exists (${isLink ? 'symlink' : 'copy'})`);\n } else {\n logger.error(` ✗ Agent path missing: ${entry.agent_path}`);\n issues++;\n }\n\n // Check env status\n const envStatus = await getEnvStatus(name, entry.env_keys);\n if (envStatus === 'configured') {\n logger.success(` ✓ Environment configured`);\n } else if (envStatus === 'partial') {\n logger.warn(` ⚠ Environment partially configured`);\n } else if (entry.env_keys.length > 0) {\n logger.warn(` ⚠ Environment not configured`);\n }\n }\n } catch (err) {\n logger.error(`Failed to check skills: ${(err as Error).message}`);\n issues++;\n }\n\n logger.blank();\n if (issues === 0) {\n logger.success('All checks passed!');\n } else {\n logger.warn(`Found ${issues} issue(s)`);\n }\n logger.blank();\n}\n","import * as logger from '../utils/logger.js';\n\n/** find command — search for skills from the registry */\nexport async function find(args: string[]): Promise<void> {\n const query = args.filter(a => !a.startsWith('-')).join(' ').trim();\n\n if (!query) {\n console.log('Usage: skill-master find <query>');\n console.log('');\n console.log('Search for skills in the online registry.');\n console.log('');\n console.log('Examples:');\n console.log(' skill-master find git');\n console.log(' skill-master find \"code review\"');\n process.exit(0);\n }\n\n logger.info(`Searching for \"${query}\"...`);\n\n try {\n const url = `https://skills.sh/api/search?q=${encodeURIComponent(query)}`;\n const response = await fetch(url, {\n headers: { 'Accept': 'application/json' },\n signal: AbortSignal.timeout(10_000),\n });\n\n if (!response.ok) {\n logger.error(`Search API returned ${response.status}: ${response.statusText}`);\n process.exit(1);\n }\n\n const data = await response.json() as SearchResult[];\n\n if (!Array.isArray(data) || data.length === 0) {\n logger.info('No skills found matching your query.');\n return;\n }\n\n logger.blank();\n logger.tableHeader('Name', 'Source', 'Installs');\n\n for (const item of data) {\n logger.tableRow(\n item.name ?? '—',\n item.source ?? '—',\n String(item.installs ?? 0),\n );\n }\n logger.blank();\n } catch (err) {\n if ((err as Error).name === 'TimeoutError') {\n logger.error('Search request timed out. Please try again.');\n } else {\n logger.error(`Search failed: ${(err as Error).message}`);\n }\n process.exit(1);\n }\n}\n\ninterface SearchResult {\n name?: string;\n source?: string;\n installs?: number;\n}\n","import { existsSync } from 'node:fs';\nimport { join, basename } from 'node:path';\nimport { ensureDir, writeText } from '../utils/fs-helpers.js';\nimport * as logger from '../utils/logger.js';\n\nconst SKILL_MD_TEMPLATE = `---\nname: {{NAME}}\nversion: 0.1.0\nauthor: \"\"\ndescription: \"\"\nallowed-tools:\n - Read\n - Edit\n - Write\n - Bash\n - Glob\n - Grep\nuser-invocable: true\n---\n\n# {{NAME}}\n\n<!-- Describe what this skill does -->\n`;\n\n/** init command — create a new skill template */\nexport async function init(args: string[]): Promise<void> {\n const nameArg = args.filter(a => !a.startsWith('-'))[0];\n const cwd = process.cwd();\n\n let targetDir: string;\n let skillName: string;\n\n if (nameArg) {\n targetDir = join(cwd, nameArg);\n skillName = nameArg;\n } else {\n targetDir = cwd;\n skillName = basename(cwd);\n }\n\n const skillMdPath = join(targetDir, 'SKILL.md');\n\n if (existsSync(skillMdPath)) {\n logger.error(`SKILL.md already exists at ${skillMdPath}`);\n process.exit(1);\n }\n\n await ensureDir(targetDir);\n\n const content = SKILL_MD_TEMPLATE\n .replace(/\\{\\{NAME\\}\\}/g, skillName);\n\n await writeText(skillMdPath, content);\n logger.success(`Created ${skillMdPath}`);\n logger.info(`Edit the file to configure your skill.`);\n}\n","import { execFile } from 'node:child_process';\nimport { promisify } from 'node:util';\nimport { listRegistry } from '../core/registry.js';\nimport { isGitUrl, parseGitUrl } from '../core/git-source.js';\nimport * as logger from '../utils/logger.js';\n\nconst execFileAsync = promisify(execFile);\n\n/** check command — check for skill updates */\nexport async function check(_args: string[]): Promise<void> {\n const skills = await listRegistry();\n const entries = Object.entries(skills);\n\n if (entries.length === 0) {\n logger.info('No skills installed');\n return;\n }\n\n logger.info('Checking for updates...');\n logger.blank();\n\n let updatable = 0;\n\n for (const [name, entry] of entries) {\n if (!isGitUrl(entry.source)) {\n logger.info(`${name}: local source — skipped`);\n continue;\n }\n\n // Skip version check for skills without version info\n if (!entry.version) {\n logger.info(`${name}: no version info — skipped`);\n continue;\n }\n\n try {\n const remoteHead = await getRemoteHead(entry.source);\n if (!remoteHead) {\n logger.warn(`${name}: unable to query remote`);\n continue;\n }\n\n // Compare with installed version (stored as git short hash or semver)\n // If version differs from remote HEAD, an update is available\n const isUpToDate = entry.version === remoteHead.slice(0, entry.version.length);\n if (isUpToDate) {\n logger.success(`${name}: up to date (${entry.version})`);\n } else {\n logger.warn(`${name}: update available (${entry.version} → ${remoteHead.slice(0, 7)})`);\n updatable++;\n }\n } catch {\n logger.warn(`${name}: failed to check remote`);\n }\n }\n\n logger.blank();\n if (updatable === 0) {\n logger.success('All skills are up to date!');\n } else {\n logger.info(`${updatable} skill(s) can be updated. Run \"skill-master update <name>\" to update.`);\n }\n}\n\n/** Get the latest commit hash from a remote git repo */\nasync function getRemoteHead(source: string): Promise<string | null> {\n try {\n const { owner, repo } = parseGitUrl(source);\n const url = `https://github.com/${owner}/${repo}.git`;\n const { stdout } = await execFileAsync('git', ['ls-remote', url, 'HEAD'], {\n timeout: 15_000,\n });\n const match = stdout.trim().split(/\\s+/)[0];\n return match || null;\n } catch {\n return null;\n }\n}\n","#!/usr/bin/env node\n\nimport { add } from './commands/add.js';\nimport { update } from './commands/update.js';\nimport { remove } from './commands/remove.js';\nimport { env } from './commands/env.js';\nimport { list } from './commands/list.js';\nimport { info } from './commands/info.js';\nimport { doctor } from './commands/doctor.js';\nimport { find } from './commands/find.js';\nimport { init } from './commands/init.js';\nimport { check } from './commands/check.js';\nimport * as logger from './utils/logger.js';\n\nconst VERSION = '0.1.0';\n\nconst HELP = `\nskill-master v${VERSION}\n\nUsage:\n skill-master add <source> [options] Install skills (aliases: install, a, i)\n skill-master remove [skills...] [opts] Remove skills (aliases: rm, r)\n skill-master list [options] List installed skills (alias: ls)\n skill-master find [query] Search for skills (aliases: search, f, s)\n skill-master update [skill] Update skills (alias: upgrade)\n skill-master init [name] Create a new skill template\n skill-master check Check for skill updates\n skill-master env <list|set|edit> Manage environment variables\n skill-master info <skill-name> Show skill details\n skill-master doctor Run diagnostics\n\nAdd Options:\n -g, --global Install globally (~/.agents/)\n -a, --agent <agents> Target agents (space-separated)\n -s, --skill <skills> Select skills (space-separated)\n -y, --yes Skip confirmations\n -l, --list List available skills without installing\n --all Install all skills to all agents\n --full-depth Search all subdirectories\n --copy Copy instead of symlink\n --force Force reinstall\n\nExamples:\n skill-master add owner/repo\n skill-master add https://github.com/user/skill -a claude-code cursor -y\n skill-master add ./local-skill --agent=cursor --copy\n skill-master remove my-skill --purge\n skill-master find \"code review\"\n skill-master init my-new-skill\n skill-master check\n`;\n\nasync function main() {\n const args = process.argv.slice(2);\n\n if (args.length === 0 || args[0] === '--help' || args[0] === '-h') {\n console.log(HELP);\n process.exit(0);\n }\n\n if (args[0] === '--version' || args[0] === '-v') {\n console.log(VERSION);\n process.exit(0);\n }\n\n const command = args[0];\n const commandArgs = args.slice(1);\n\n try {\n switch (command) {\n // add (primary) with aliases: install, a, i\n case 'add':\n case 'a':\n case 'install':\n case 'i':\n await add(commandArgs);\n break;\n\n // remove with aliases: rm, r\n case 'remove':\n case 'rm':\n case 'r':\n await remove(commandArgs);\n break;\n\n // list with alias: ls\n case 'list':\n case 'ls':\n await list(commandArgs);\n break;\n\n // find with aliases: search, f, s\n case 'find':\n case 'search':\n case 'f':\n case 's':\n await find(commandArgs);\n break;\n\n // update with alias: upgrade\n case 'update':\n case 'upgrade':\n await update(commandArgs);\n break;\n\n // init\n case 'init':\n await init(commandArgs);\n break;\n\n // check\n case 'check':\n await check(commandArgs);\n break;\n\n // env, info, doctor — skill-master extensions\n case 'env':\n await env(commandArgs);\n break;\n case 'info':\n await info(commandArgs);\n break;\n case 'doctor':\n await doctor();\n break;\n\n default:\n logger.error(`Unknown command: ${command}`);\n console.log(HELP);\n process.exit(1);\n }\n } catch (err) {\n logger.error((err as Error).message);\n if (process.env.DEBUG) {\n console.error(err);\n }\n process.exit(1);\n }\n}\n\nmain();\n"],"mappings":"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","names":["join","existsSync","existsSync","join","existsSync","existsSync","join","join","homedir","join","existsSync","join","existsSync","join","join","join","homedir","join","existsSync","existsSync","existsSync","join","existsSync","basename","info","existsSync","existsSync","existsSync","join","basename","join","basename","existsSync","execFile","promisify","execFileAsync","promisify","execFile","info"]}
1
+ {"version":3,"sources":["../src/core/installer.ts","../src/core/git-source.ts","../src/utils/fs-helpers.ts","../src/utils/errors.ts","../src/utils/logger.ts","../src/core/skill-parser.ts","../src/core/env-manager.ts","../src/utils/paths.ts","../src/platform/agents.ts","../src/core/registry.ts","../src/commands/add.ts","../src/commands/update.ts","../src/commands/remove.ts","../src/commands/env.ts","../src/commands/list.ts","../src/commands/info.ts","../src/commands/doctor.ts","../src/commands/find.ts","../src/commands/init.ts","../src/commands/check.ts","../src/cli.ts"],"sourcesContent":["import { join } from 'node:path';\nimport { existsSync } from 'node:fs';\nimport { cloneRepo, isGitUrl, isLocalPath } from './git-source.js';\nimport { findSkillDirectory, readSkillMd, inferCapabilities, extractEnvKeys } from './skill-parser.js';\nimport { backupEnv, restoreEnv } from './env-manager.js';\nimport { updateRegistry } from './registry.js';\nimport { detectPlatform, getAgentSkillsDir } from '../platform/detector.js';\nimport { copyDir, removePath, symlinkOrCopy, ensureDir, readTextSafe } from '../utils/fs-helpers.js';\nimport { getSkillCanonicalPath, getAgentSkillPath, getAgentGlobalSkillPath } from '../utils/paths.js';\nimport * as logger from '../utils/logger.js';\nimport { SkillNotFoundError, SkillParseError } from '../utils/errors.js';\nimport type { InstallOptions, RegistryEntry, AgentInstall } from '../types/index.js';\n\nconst TOTAL_STEPS = 9;\n\n/**\n * Main installation engine — 9-step process:\n * 1. fetchSource → clone/copy to temp\n * 2. findSkillDir → locate SKILL.md\n * 3. parseSkillMd → parse frontmatter\n * 4. detectAgent → determine target platform\n * 5. backupEnv → preserve existing .env\n * 6. cleanAndInstall → rm old → copy new to canonical\n * 7. restoreEnv → restore .env to both locations\n * 8. linkOrCopy → symlink/copy to agent dir\n * 9. updateRegistry → update registry.json\n */\nexport async function installSkill(options: InstallOptions): Promise<void> {\n const { source, cwd, copy = false, force = false, global: isGlobal = false } = options;\n\n // Step 1: Fetch source\n logger.step(1, TOTAL_STEPS, 'Fetching skill source...');\n let sourceDir: string;\n\n if (source.type === 'git') {\n sourceDir = await cloneRepo(source.url!, source.branch);\n } else if (source.type === 'local') {\n sourceDir = source.path!;\n if (!existsSync(sourceDir)) {\n throw new SkillNotFoundError(sourceDir);\n }\n } else {\n throw new SkillParseError('Invalid source type');\n }\n\n // Step 2: Find skill directory\n logger.step(2, TOTAL_STEPS, 'Locating SKILL.md...');\n const skillDir = await findSkillDirectory(sourceDir);\n if (!skillDir) {\n throw new SkillNotFoundError(`No SKILL.md found in ${sourceDir}`);\n }\n\n // Step 3: Parse SKILL.md\n logger.step(3, TOTAL_STEPS, 'Parsing SKILL.md...');\n const parsed = await readSkillMd(skillDir);\n if (!parsed) {\n throw new SkillParseError('Failed to read SKILL.md');\n }\n const skillName = parsed.frontmatter.name;\n logger.info(`Found skill: ${skillName}${parsed.frontmatter.version ? ` v${parsed.frontmatter.version}` : ''}`);\n\n // Step 4: Detect agent platform\n logger.step(4, TOTAL_STEPS, 'Detecting agent platform...');\n const agent = options.agent ?? detectPlatform(cwd);\n logger.info(`Target platform: ${agent}`);\n\n // Step 5: Backup existing .env\n logger.step(5, TOTAL_STEPS, 'Backing up .env...');\n const agentSkillDir = isGlobal\n ? getAgentGlobalSkillPath(agent, skillName)\n : getAgentSkillPath(cwd, agent, skillName);\n const envBackup = await backupEnv(skillName, agentSkillDir);\n if (envBackup) {\n logger.success(`Backed up ${Object.keys(envBackup).length} env key(s)`);\n } else {\n logger.info('No existing .env found');\n }\n\n // Step 6: Clean and install to canonical path\n logger.step(6, TOTAL_STEPS, 'Installing to canonical path...');\n const canonicalPath = getSkillCanonicalPath(skillName);\n\n if (existsSync(canonicalPath) && !force) {\n logger.info('Replacing existing installation');\n }\n await removePath(canonicalPath);\n await copyDir(skillDir, canonicalPath);\n logger.success(`Installed to ${canonicalPath}`);\n\n // Step 7: Restore .env\n logger.step(7, TOTAL_STEPS, 'Restoring .env...');\n if (envBackup) {\n await restoreEnv(skillName, envBackup, canonicalPath);\n logger.success('.env restored successfully');\n } else {\n // Check if there's a .env.example to hint about\n const examplePath = join(canonicalPath, '.env.example');\n if (existsSync(examplePath)) {\n logger.warn('Found .env.example — run `skill-master env edit ' + skillName + '` to configure');\n }\n }\n\n // Step 8: Link or copy to agent directory\n logger.step(8, TOTAL_STEPS, `Linking to ${agent} skills directory...`);\n const agentPath = isGlobal\n ? getAgentGlobalSkillPath(agent, skillName)\n : getAgentSkillPath(cwd, agent, skillName);\n const linkType = await symlinkOrCopy(canonicalPath, agentPath, copy);\n logger.success(`${linkType === 'symlink' ? 'Symlinked' : 'Copied'} to ${agentPath}`);\n\n // Step 9: Update registry\n logger.step(9, TOTAL_STEPS, 'Updating registry...');\n const capabilities = parsed.frontmatter.capabilities ?? inferCapabilities(parsed.frontmatter['allowed-tools'] ?? []);\n\n // Extract env keys from .env.example\n const envExampleContent = await readTextSafe(join(canonicalPath, '.env.example'));\n const envKeys = envExampleContent ? extractEnvKeys(envExampleContent) : [];\n\n const now = new Date().toISOString();\n const agentInstall: AgentInstall = {\n agent,\n agent_path: agentPath,\n global: isGlobal,\n };\n const entry: RegistryEntry = {\n source: source.type === 'git' ? source.url! : source.path!,\n version: parsed.frontmatter.version,\n installed_at: now,\n updated_at: now,\n agents: [agentInstall],\n env_keys: envKeys,\n capabilities,\n canonical_path: canonicalPath,\n };\n\n await updateRegistry(skillName, entry);\n logger.blank();\n logger.success(`Skill \"${skillName}\" installed successfully!`);\n}\n","import { execFile } from 'node:child_process';\nimport { promisify } from 'node:util';\nimport { existsSync } from 'node:fs';\nimport { ensureDir, createTempDir } from '../utils/fs-helpers.js';\nimport { GitCloneError, SourceParseError } from '../utils/errors.js';\nimport * as logger from '../utils/logger.js';\nimport type { ParsedSource } from '../types/index.js';\n\nconst execFileAsync = promisify(execFile);\n\n/**\n * Parse a source string into a structured ParsedSource.\n * Supports:\n * - owner/repo → git\n * - owner/repo@skill → git + skillFilter\n * - owner/repo/sub/path → git + subpath\n * - github.com/o/r/tree/<ref>/<subpath> → git + ref + subpath\n * - github.com/o/r/blob/<ref>/<path> → git + ref + subpath (parent dir)\n * - gitlab.com/o/r/-/tree/<ref>/<subpath> → git + ref + subpath\n * - Full URLs (https/git@/git://) → git\n * - Local paths → local\n */\nexport function parseSource(source: string): ParsedSource {\n // git@ or git:// protocols\n if (source.startsWith('git@') || source.startsWith('git://')) {\n return { type: 'git', url: source };\n }\n\n // Full HTTP(S) URLs\n if (source.startsWith('https://') || source.startsWith('http://')) {\n // GitHub tree URL: github.com/o/r/tree/<ref>/<subpath>\n const ghTree = source.match(/github\\.com\\/([^/]+)\\/([^/]+)\\/tree\\/([^/]+)(?:\\/(.+))?/);\n if (ghTree) {\n const url = `https://github.com/${ghTree[1]}/${ghTree[2]}.git`;\n return { type: 'git', url, ref: ghTree[3], subpath: ghTree[4] };\n }\n\n // GitHub blob URL: github.com/o/r/blob/<ref>/<path> → parent dir as subpath\n const ghBlob = source.match(/github\\.com\\/([^/]+)\\/([^/]+)\\/blob\\/([^/]+)\\/(.+)/);\n if (ghBlob) {\n const url = `https://github.com/${ghBlob[1]}/${ghBlob[2]}.git`;\n const filePath = ghBlob[4];\n const subpath = filePath.includes('/') ? filePath.slice(0, filePath.lastIndexOf('/')) : undefined;\n return { type: 'git', url, ref: ghBlob[3], subpath };\n }\n\n // GitLab tree URL: gitlab.com/o/r/-/tree/<ref>/<subpath>\n const glTree = source.match(/gitlab\\.com\\/([^/]+)\\/([^/]+)\\/-\\/tree\\/([^/]+)(?:\\/(.+))?/);\n if (glTree) {\n const url = `https://gitlab.com/${glTree[1]}/${glTree[2]}.git`;\n return { type: 'git', url, ref: glTree[3], subpath: glTree[4] };\n }\n\n // Plain github.com or gitlab.com URL\n if (source.includes('github.com/') || source.includes('gitlab.com/')) {\n return { type: 'git', url: source };\n }\n\n // Other https URLs — treat as git\n return { type: 'git', url: source };\n }\n\n // Contains github.com or gitlab.com without protocol\n if (source.includes('github.com/') || source.includes('gitlab.com/')) {\n return parseSource('https://' + source);\n }\n\n // Local path — exists on filesystem\n if (existsSync(source) || source.startsWith('/') || source.startsWith('./') || source.startsWith('../')) {\n return { type: 'local', path: source };\n }\n\n // Shorthand: extract @skill filter first\n let skillFilter: string | undefined;\n let shorthand = source;\n const atIdx = shorthand.indexOf('@');\n if (atIdx > 0 && !shorthand.includes('/') === false) {\n // Could be owner/repo@skill or owner/repo/path@skill\n // Only treat as skillFilter if @ is after the repo part\n const lastAt = shorthand.lastIndexOf('@');\n if (lastAt > 0) {\n const afterAt = shorthand.slice(lastAt + 1);\n const beforeAt = shorthand.slice(0, lastAt);\n // If afterAt has no slashes, it's a skill filter\n if (afterAt && !afterAt.includes('/')) {\n skillFilter = afterAt;\n shorthand = beforeAt;\n }\n }\n }\n\n // owner/repo (exactly 2 segments)\n if (/^[a-zA-Z0-9_.-]+\\/[a-zA-Z0-9_.-]+$/.test(shorthand)) {\n return {\n type: 'git',\n url: `https://github.com/${shorthand}.git`,\n skillFilter,\n };\n }\n\n // owner/repo/sub/path (3+ segments, first two are owner/repo)\n const segments = shorthand.split('/');\n if (segments.length >= 3 && /^[a-zA-Z0-9_.-]+$/.test(segments[0]) && /^[a-zA-Z0-9_.-]+$/.test(segments[1])) {\n const owner = segments[0];\n const repo = segments[1];\n const subpath = segments.slice(2).join('/');\n return {\n type: 'git',\n url: `https://github.com/${owner}/${repo}.git`,\n subpath,\n skillFilter,\n };\n }\n\n throw new SourceParseError(source, 'Unable to determine source type');\n}\n\n/** Check if a string looks like a git URL or GitHub shorthand */\nexport function isGitUrl(source: string): boolean {\n try {\n return parseSource(source).type === 'git';\n } catch {\n return false;\n }\n}\n\n/** Normalize a source string to a full clone URL */\nexport function normalizeGitUrl(source: string): string {\n const parsed = parseSource(source);\n if (parsed.type !== 'git' || !parsed.url) return source;\n\n let url = parsed.url;\n // Ensure .git suffix for HTTPS URLs\n if (url.startsWith('https://') && !url.endsWith('.git')) {\n url += '.git';\n }\n return url;\n}\n\n/** Parse a GitHub URL into owner and repo */\nexport function parseGitUrl(url: string): { owner: string; repo: string; branch?: string } {\n // Handle tree/branch in URL: github.com/owner/repo/tree/branch\n const treeMatch = url.match(/github\\.com\\/([^/]+)\\/([^/]+)\\/tree\\/(.+)/);\n if (treeMatch) {\n return {\n owner: treeMatch[1],\n repo: treeMatch[2].replace(/\\.git$/, ''),\n branch: treeMatch[3],\n };\n }\n\n // Standard URL: github.com/owner/repo\n const match = url.match(/github\\.com[/:]([^/]+)\\/([^/.]+)/);\n if (match) {\n return { owner: match[1], repo: match[2] };\n }\n\n throw new GitCloneError(url, 'Unable to parse GitHub URL');\n}\n\n/** Clone a git repository to a temporary directory */\nexport async function cloneRepo(\n url: string,\n branch?: string,\n): Promise<string> {\n const normalizedUrl = normalizeGitUrl(url);\n const tempDir = createTempDir();\n await ensureDir(tempDir);\n\n const args = ['clone', '--depth', '1'];\n if (branch) {\n args.push('--branch', branch);\n }\n args.push(normalizedUrl, tempDir);\n\n logger.debug(`Cloning ${normalizedUrl} to ${tempDir}`);\n\n try {\n await execFileAsync('git', args, { timeout: 60_000 });\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n throw new GitCloneError(url, msg);\n }\n\n return tempDir;\n}\n\n/** Check if a local path exists and contains a skill */\nexport function isLocalPath(source: string): boolean {\n return existsSync(source);\n}","import { mkdir, cp, readFile, writeFile, rename, symlink, lstat, rm } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { tmpdir } from 'node:os';\nimport { randomBytes } from 'node:crypto';\n\n/** Ensure a directory exists (recursive) */\nexport async function ensureDir(dir: string): Promise<void> {\n await mkdir(dir, { recursive: true });\n}\n\n/** Recursively copy a directory */\nexport async function copyDir(src: string, dest: string): Promise<void> {\n await ensureDir(dest);\n await cp(src, dest, { recursive: true, force: true });\n}\n\n/** Remove a directory or file recursively */\nexport async function removePath(target: string): Promise<void> {\n if (existsSync(target)) {\n await rm(target, { recursive: true, force: true });\n }\n}\n\n/** Atomic JSON write: write to .tmp then rename */\nexport async function atomicWriteJson(filePath: string, data: unknown): Promise<void> {\n await ensureDir(dirname(filePath));\n const tmpPath = filePath + '.tmp';\n await writeFile(tmpPath, JSON.stringify(data, null, 2) + '\\n', 'utf-8');\n await rename(tmpPath, filePath);\n}\n\n/** Safely read and parse a JSON file, return null on failure */\nexport async function readJsonSafe<T>(filePath: string): Promise<T | null> {\n try {\n const content = await readFile(filePath, 'utf-8');\n return JSON.parse(content) as T;\n } catch {\n return null;\n }\n}\n\n/** Read a text file, return null if not found */\nexport async function readTextSafe(filePath: string): Promise<string | null> {\n try {\n return await readFile(filePath, 'utf-8');\n } catch {\n return null;\n }\n}\n\n/** Write text to a file, ensuring parent directory exists */\nexport async function writeText(filePath: string, content: string): Promise<void> {\n await ensureDir(dirname(filePath));\n await writeFile(filePath, content, 'utf-8');\n}\n\n/** Create a symlink, or copy if symlink fails (Windows fallback) */\nexport async function symlinkOrCopy(target: string, linkPath: string, forceCopy = false): Promise<'symlink' | 'copy'> {\n await ensureDir(dirname(linkPath));\n\n // Remove existing link/dir\n await removePath(linkPath);\n\n if (forceCopy) {\n await copyDir(target, linkPath);\n return 'copy';\n }\n\n try {\n await symlink(target, linkPath, 'dir');\n return 'symlink';\n } catch {\n // Fallback to copy on platforms that don't support symlinks\n await copyDir(target, linkPath);\n return 'copy';\n }\n}\n\n/** Check if a path is a symlink */\nexport async function isSymlink(path: string): Promise<boolean> {\n try {\n const stat = await lstat(path);\n return stat.isSymbolicLink();\n } catch {\n return false;\n }\n}\n\n/** Create a temporary directory with a unique name */\nexport function createTempDir(): string {\n const id = randomBytes(8).toString('hex');\n return join(tmpdir(), `skill-master-${id}`);\n}\n","/** Base error class for skill-master */\nexport class SkillManagerError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'SkillManagerError';\n }\n}\n\n/** Skill not found in registry or filesystem */\nexport class SkillNotFoundError extends SkillManagerError {\n constructor(skillName: string) {\n super(`Skill \"${skillName}\" not found`);\n this.name = 'SkillNotFoundError';\n }\n}\n\n/** Required .env key is missing */\nexport class EnvMissingError extends SkillManagerError {\n constructor(skillName: string, keys: string[]) {\n super(`Skill \"${skillName}\" is missing env keys: ${keys.join(', ')}`);\n this.name = 'EnvMissingError';\n }\n}\n\n/** Registry file is corrupted or invalid */\nexport class RegistryCorruptError extends SkillManagerError {\n constructor(detail?: string) {\n super(`Registry is corrupted${detail ? ': ' + detail : ''}`);\n this.name = 'RegistryCorruptError';\n }\n}\n\n/** Git clone operation failed */\nexport class GitCloneError extends SkillManagerError {\n constructor(url: string, detail?: string) {\n super(`Failed to clone \"${url}\"${detail ? ': ' + detail : ''}`);\n this.name = 'GitCloneError';\n }\n}\n\n/** SKILL.md parsing or validation failed */\nexport class SkillParseError extends SkillManagerError {\n constructor(detail: string) {\n super(`Failed to parse SKILL.md: ${detail}`);\n this.name = 'SkillParseError';\n }\n}\n\n/** Platform detection failed or unsupported */\nexport class PlatformError extends SkillManagerError {\n constructor(detail: string) {\n super(`Platform error: ${detail}`);\n this.name = 'PlatformError';\n }\n}\n\n/** Source string parsing failed */\nexport class SourceParseError extends SkillManagerError {\n constructor(source: string, detail?: string) {\n super(`Failed to parse source \"${source}\"${detail ? ': ' + detail : ''}`);\n this.name = 'SourceParseError';\n }\n}\n","import chalk from 'chalk';\n\nconst PREFIX = chalk.blue('skill-master');\n\n/** Informational message */\nexport function info(msg: string): void {\n console.log(`${PREFIX} ${chalk.cyan('info')} ${msg}`);\n}\n\n/** Success message */\nexport function success(msg: string): void {\n console.log(`${PREFIX} ${chalk.green('✔')} ${msg}`);\n}\n\n/** Warning message */\nexport function warn(msg: string): void {\n console.log(`${PREFIX} ${chalk.yellow('⚠')} ${msg}`);\n}\n\n/** Error message */\nexport function error(msg: string): void {\n console.error(`${PREFIX} ${chalk.red('✖')} ${msg}`);\n}\n\n/** Debug message (only when DEBUG env is set) */\nexport function debug(msg: string): void {\n if (process.env.DEBUG) {\n console.log(`${PREFIX} ${chalk.gray('debug')} ${msg}`);\n }\n}\n\n/** Step indicator with number */\nexport function step(num: number, total: number, msg: string): void {\n const counter = chalk.gray(`[${num}/${total}]`);\n console.log(`${PREFIX} ${counter} ${msg}`);\n}\n\n/** Print a blank line */\nexport function blank(): void {\n console.log();\n}\n\n/** Print a key-value pair */\nexport function kv(key: string, value: string): void {\n console.log(` ${chalk.gray(key + ':')} ${value}`);\n}\n\n/** Print a table header */\nexport function tableHeader(...cols: string[]): void {\n console.log(chalk.bold(cols.map(c => c.padEnd(20)).join('')));\n console.log(chalk.gray('─'.repeat(cols.length * 20)));\n}\n\n/** Print a table row */\nexport function tableRow(...cols: string[]): void {\n console.log(cols.map(c => c.padEnd(20)).join(''));\n}\n","import { parse as parseYaml, stringify as stringifyYaml } from 'yaml';\nimport { readdir } from 'node:fs/promises';\nimport { join, basename } from 'node:path';\nimport { existsSync } from 'node:fs';\nimport { readTextSafe } from '../utils/fs-helpers.js';\nimport { SkillParseError } from '../utils/errors.js';\nimport type { ParsedSkill, SkillFrontmatter, Capability } from '../types/index.js';\n\n/** Tool-to-capability reverse mapping for Claude Code tools */\nconst TOOL_CAPABILITY_MAP: Record<string, Capability> = {\n 'Bash': 'shell',\n 'Read': 'read_file',\n 'Write': 'write_file',\n 'Edit': 'edit_file',\n 'Glob': 'find_file',\n 'Grep': 'search_content',\n 'Task': 'sub_task',\n 'WebFetch': 'web_fetch',\n 'WebSearch': 'web_search',\n};\n\n/** Parse a SKILL.md file content into frontmatter + body */\nexport function parseSkillMd(content: string, dirName?: string): ParsedSkill {\n const match = content.match(/^---\\r?\\n([\\s\\S]*?)\\r?\\n---\\r?\\n?([\\s\\S]*)$/);\n if (!match) {\n throw new SkillParseError('No valid frontmatter block found');\n }\n\n const rawFrontmatter = match[1];\n const body = match[2];\n\n let frontmatter: SkillFrontmatter;\n try {\n frontmatter = parseYaml(rawFrontmatter) as SkillFrontmatter;\n } catch (err) {\n throw new SkillParseError(`YAML parse error: ${(err as Error).message}`);\n }\n\n validateFrontmatter(frontmatter);\n\n // Infer name from directory if not provided in frontmatter\n if (!frontmatter.name && dirName) {\n frontmatter.name = dirName;\n }\n\n if (!frontmatter.name) {\n throw new SkillParseError('Missing \"name\" field and unable to infer from directory');\n }\n\n return { frontmatter, body, rawFrontmatter };\n}\n\n/** Validate required frontmatter fields */\nexport function validateFrontmatter(fm: SkillFrontmatter): void {\n if (fm.name !== undefined && typeof fm.name !== 'string') {\n throw new SkillParseError('Invalid \"name\" field — must be a string');\n }\n if (fm.version !== undefined && typeof fm.version !== 'string') {\n throw new SkillParseError('Invalid \"version\" field — must be a string');\n }\n if (fm['allowed-tools'] !== undefined && !Array.isArray(fm['allowed-tools'])) {\n throw new SkillParseError('Invalid \"allowed-tools\" field — must be an array');\n }\n}\n\n/** Infer abstract capabilities from allowed-tools list */\nexport function inferCapabilities(allowedTools: string[]): Capability[] {\n const caps = new Set<Capability>();\n for (const tool of allowedTools) {\n const cap = TOOL_CAPABILITY_MAP[tool];\n if (cap) {\n caps.add(cap);\n }\n }\n return [...caps];\n}\n\n/** Serialize a ParsedSkill back to SKILL.md format */\nexport function serializeSkillMd(parsed: ParsedSkill): string {\n const yamlStr = stringifyYaml(parsed.frontmatter, { lineWidth: 0 }).trimEnd();\n return `---\\n${yamlStr}\\n---\\n${parsed.body}`;\n}\n\n/** Search for SKILL.md files within a directory (looks in .claude/skills/*) */\nexport async function findSkillDirectory(dir: string): Promise<string | null> {\n const dirs = await findAllSkillDirectories(dir);\n return dirs.length > 0 ? dirs[0] : null;\n}\n\nconst SKIP_DIRS = new Set(['node_modules', '.git', 'dist', 'build']);\n\n/** Discover all directories containing SKILL.md within a source */\nexport async function findAllSkillDirectories(dir: string, fullDepth = false): Promise<string[]> {\n if (fullDepth) {\n const results = new Set<string>();\n await walkForSkills(dir, 0, 5, results);\n return [...results];\n }\n\n const results: string[] = [];\n\n // Direct SKILL.md in root\n if (existsSync(join(dir, 'SKILL.md'))) {\n results.push(dir);\n return results;\n }\n\n // Search in .claude/skills/*/SKILL.md\n const skillsRoot = join(dir, '.claude', 'skills');\n if (existsSync(skillsRoot)) {\n try {\n const entries = await readdir(skillsRoot, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isDirectory()) {\n const skillMdPath = join(skillsRoot, entry.name, 'SKILL.md');\n if (existsSync(skillMdPath)) {\n results.push(join(skillsRoot, entry.name));\n }\n }\n }\n } catch {\n // continue to next search strategy\n }\n }\n\n // Search one-level subdirectories for SKILL.md (skip hidden dirs)\n try {\n const topEntries = await readdir(dir, { withFileTypes: true });\n for (const entry of topEntries) {\n if (entry.isDirectory() && !entry.name.startsWith('.')) {\n const skillMdPath = join(dir, entry.name, 'SKILL.md');\n if (existsSync(skillMdPath)) {\n results.push(join(dir, entry.name));\n }\n }\n }\n } catch {\n // ignore\n }\n\n return results;\n}\n\n/** Recursively walk directories up to maxDepth looking for SKILL.md */\nasync function walkForSkills(dir: string, depth: number, maxDepth: number, results: Set<string>): Promise<void> {\n if (depth > maxDepth) return;\n\n if (existsSync(join(dir, 'SKILL.md'))) {\n results.add(dir);\n }\n\n try {\n const entries = await readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isDirectory() && !entry.name.startsWith('.') && !SKIP_DIRS.has(entry.name)) {\n await walkForSkills(join(dir, entry.name), depth + 1, maxDepth, results);\n }\n }\n } catch {\n // ignore permission errors etc.\n }\n}\n\n/** Read and parse a SKILL.md from a directory */\nexport async function readSkillMd(dir: string): Promise<ParsedSkill | null> {\n const content = await readTextSafe(join(dir, 'SKILL.md'));\n if (!content) return null;\n return parseSkillMd(content, basename(dir));\n}\n\n/** Extract env keys from a .env.example file */\nexport function extractEnvKeys(envExampleContent: string): string[] {\n const keys: string[] = [];\n for (const line of envExampleContent.split('\\n')) {\n const trimmed = line.trim();\n if (trimmed && !trimmed.startsWith('#')) {\n const match = trimmed.match(/^([A-Z_][A-Z0-9_]*)=/);\n if (match) {\n keys.push(match[1]);\n }\n }\n }\n return keys;\n}\n","import { join } from 'node:path';\nimport { existsSync } from 'node:fs';\nimport { readTextSafe, writeText, ensureDir } from '../utils/fs-helpers.js';\nimport { getSkillConfigPath, getSkillCanonicalPath } from '../utils/paths.js';\nimport * as logger from '../utils/logger.js';\nimport type { EnvStatus } from '../types/index.js';\n\n/** Parse a .env file content into key-value pairs */\nexport function parseEnvFile(content: string): Record<string, string> {\n const result: Record<string, string> = {};\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) continue;\n const eqIndex = trimmed.indexOf('=');\n if (eqIndex === -1) continue;\n const key = trimmed.slice(0, eqIndex).trim();\n let value = trimmed.slice(eqIndex + 1).trim();\n // Strip surrounding quotes\n if ((value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))) {\n value = value.slice(1, -1);\n }\n result[key] = value;\n }\n return result;\n}\n\n/** Serialize key-value pairs back to .env format */\nexport function serializeEnv(data: Record<string, string>): string {\n return Object.entries(data)\n .map(([key, value]) => `${key}=${value}`)\n .join('\\n') + '\\n';\n}\n\n/**\n * Backup .env for a skill, searching multiple locations by priority:\n * 1. ~/.agents/config/<skill>/.env (persistent)\n * 2. agentSkillDir/.env (current agent dir, e.g. .claude/skills/<skill>)\n * 3. ~/.agents/skills/<skill>/.env (canonical)\n */\nexport async function backupEnv(\n skillName: string,\n agentSkillDir?: string,\n): Promise<Record<string, string> | null> {\n const locations = [\n join(getSkillConfigPath(skillName), '.env'),\n ...(agentSkillDir ? [join(agentSkillDir, '.env')] : []),\n join(getSkillCanonicalPath(skillName), '.env'),\n ];\n\n for (const loc of locations) {\n const content = await readTextSafe(loc);\n if (content) {\n const data = parseEnvFile(content);\n if (Object.keys(data).length > 0) {\n logger.debug(`Backed up .env from ${loc}`);\n return data;\n }\n }\n }\n\n return null;\n}\n\n/**\n * Restore .env to both persistent and skill directory locations.\n * Merges with .env.example if present.\n */\nexport async function restoreEnv(\n skillName: string,\n envData: Record<string, string>,\n skillDir: string,\n): Promise<void> {\n // Read .env.example from skill dir if exists\n const exampleContent = await readTextSafe(join(skillDir, '.env.example'));\n let finalContent: string;\n\n if (exampleContent) {\n finalContent = mergeEnv(envData, exampleContent);\n } else {\n finalContent = serializeEnv(envData);\n }\n\n // Write to persistent config location\n const configEnvPath = join(getSkillConfigPath(skillName), '.env');\n await writeText(configEnvPath, finalContent);\n\n // Write to skill directory (for compatibility with loadApiKey)\n const skillEnvPath = join(skillDir, '.env');\n await writeText(skillEnvPath, finalContent);\n\n logger.debug(`Restored .env to ${configEnvPath} and ${skillEnvPath}`);\n}\n\n/**\n * Merge existing env data with .env.example template.\n * - Existing keys are NEVER overwritten\n * - New keys from example are appended with empty values and comments\n */\nexport function mergeEnv(\n existing: Record<string, string>,\n exampleContent: string,\n): string {\n const lines: string[] = [];\n const usedKeys = new Set<string>();\n\n // First, write all existing keys\n for (const [key, value] of Object.entries(existing)) {\n lines.push(`${key}=${value}`);\n usedKeys.add(key);\n }\n\n // Then, append new keys from example\n const exampleKeys = parseEnvFile(exampleContent);\n const newKeys = Object.keys(exampleKeys).filter(k => !usedKeys.has(k));\n\n if (newKeys.length > 0) {\n lines.push('');\n lines.push('# New keys added by skill update (please configure):');\n for (const key of newKeys) {\n lines.push(`# ${key}=`);\n }\n }\n\n return lines.join('\\n') + '\\n';\n}\n\n/** Check the .env configuration status for a skill */\nexport async function getEnvStatus(\n skillName: string,\n requiredKeys: string[],\n): Promise<EnvStatus> {\n if (requiredKeys.length === 0) return 'configured';\n\n const configEnvPath = join(getSkillConfigPath(skillName), '.env');\n const content = await readTextSafe(configEnvPath);\n\n if (!content) return 'missing';\n\n const data = parseEnvFile(content);\n const configuredKeys = Object.entries(data)\n .filter(([, v]) => v && !v.includes('your_') && !v.includes('_here'))\n .map(([k]) => k);\n\n const allConfigured = requiredKeys.every(k => configuredKeys.includes(k));\n const someConfigured = requiredKeys.some(k => configuredKeys.includes(k));\n\n if (allConfigured) return 'configured';\n if (someConfigured) return 'partial';\n return 'missing';\n}\n\n/** Set a single env value for a skill */\nexport async function setEnvValue(\n skillName: string,\n key: string,\n value: string,\n skillDir?: string,\n): Promise<void> {\n const configEnvPath = join(getSkillConfigPath(skillName), '.env');\n const content = await readTextSafe(configEnvPath);\n const data = content ? parseEnvFile(content) : {};\n\n data[key] = value;\n const newContent = serializeEnv(data);\n\n // Write to persistent location\n await writeText(configEnvPath, newContent);\n\n // Sync to skill directory if provided\n if (skillDir) {\n await writeText(join(skillDir, '.env'), newContent);\n }\n}\n\n/** Get the .env file path for editing */\nexport function getEnvEditPath(skillName: string): string {\n return join(getSkillConfigPath(skillName), '.env');\n}\n","import { homedir } from 'node:os';\nimport { join } from 'node:path';\n\n/** Root directory for all skill-master data */\nexport const AGENTS_HOME = join(homedir(), '.agents');\n\n/** Persistent user config (API keys etc.) */\nexport const CONFIG_DIR = join(AGENTS_HOME, 'config');\n\n/** Canonical skill code storage */\nexport const SKILLS_DIR = join(AGENTS_HOME, 'skills');\n\n/** Registry file path */\nexport const REGISTRY_PATH = join(AGENTS_HOME, 'registry.json');\n\n/** Get canonical path for a skill's code */\nexport function getSkillCanonicalPath(name: string): string {\n return join(SKILLS_DIR, name);\n}\n\n/** Get persistent config path for a skill (holds .env) */\nexport function getSkillConfigPath(name: string): string {\n return join(CONFIG_DIR, name);\n}\n\n// Re-export from agents.ts — eliminates duplicate AGENT_SKILL_DIRS mapping\nexport { getAgentSkillPath, getAgentGlobalSkillPath, getAgentSkillsRoot } from '../platform/agents.js';\n","import { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { homedir } from 'node:os';\n\nconst home = homedir();\nconst configHome = process.env.XDG_CONFIG_HOME?.trim() || join(home, '.config');\nconst codexHome = process.env.CODEX_HOME?.trim() || join(home, '.codex');\nconst claudeHome = process.env.CLAUDE_CONFIG_DIR?.trim() || join(home, '.claude');\n\nexport interface AgentConfig {\n name: string;\n displayName: string;\n skillsDir: string;\n globalSkillsDir: string;\n detectMarker?: string;\n}\n\nexport const AGENTS = {\n amp: {\n name: 'amp',\n displayName: 'Amp',\n skillsDir: '.agents/skills',\n globalSkillsDir: join(configHome, 'agents/skills'),\n },\n antigravity: {\n name: 'antigravity',\n displayName: 'Antigravity',\n skillsDir: '.agent/skills',\n globalSkillsDir: join(home, '.gemini/antigravity/skills'),\n detectMarker: '.agent',\n },\n augment: {\n name: 'augment',\n displayName: 'Augment',\n skillsDir: '.augment/skills',\n globalSkillsDir: join(home, '.augment/skills'),\n detectMarker: '.augment',\n },\n 'claude-code': {\n name: 'claude-code',\n displayName: 'Claude Code',\n skillsDir: '.claude/skills',\n globalSkillsDir: join(claudeHome, 'skills'),\n detectMarker: '.claude',\n },\n openclaw: {\n name: 'openclaw',\n displayName: 'OpenClaw',\n skillsDir: 'skills',\n globalSkillsDir: join(home, '.openclaw/skills'),\n },\n cline: {\n name: 'cline',\n displayName: 'Cline',\n skillsDir: '.cline/skills',\n globalSkillsDir: join(home, '.cline/skills'),\n detectMarker: '.cline',\n },\n codebuddy: {\n name: 'codebuddy',\n displayName: 'CodeBuddy',\n skillsDir: '.codebuddy/skills',\n globalSkillsDir: join(home, '.codebuddy/skills'),\n detectMarker: '.codebuddy',\n },\n codex: {\n name: 'codex',\n displayName: 'Codex',\n skillsDir: '.agents/skills',\n globalSkillsDir: join(codexHome, 'skills'),\n },\n 'command-code': {\n name: 'command-code',\n displayName: 'Command Code',\n skillsDir: '.commandcode/skills',\n globalSkillsDir: join(home, '.commandcode/skills'),\n detectMarker: '.commandcode',\n },\n continue: {\n name: 'continue',\n displayName: 'Continue',\n skillsDir: '.continue/skills',\n globalSkillsDir: join(home, '.continue/skills'),\n detectMarker: '.continue',\n },\n crush: {\n name: 'crush',\n displayName: 'Crush',\n skillsDir: '.crush/skills',\n globalSkillsDir: join(home, '.config/crush/skills'),\n },\n cursor: {\n name: 'cursor',\n displayName: 'Cursor',\n skillsDir: '.cursor/skills',\n globalSkillsDir: join(home, '.cursor/skills'),\n detectMarker: '.cursor',\n },\n droid: {\n name: 'droid',\n displayName: 'Droid',\n skillsDir: '.factory/skills',\n globalSkillsDir: join(home, '.factory/skills'),\n detectMarker: '.factory',\n },\n 'gemini-cli': {\n name: 'gemini-cli',\n displayName: 'Gemini CLI',\n skillsDir: '.agents/skills',\n globalSkillsDir: join(home, '.gemini/skills'),\n },\n 'github-copilot': {\n name: 'github-copilot',\n displayName: 'GitHub Copilot',\n skillsDir: '.agents/skills',\n globalSkillsDir: join(home, '.copilot/skills'),\n },\n goose: {\n name: 'goose',\n displayName: 'Goose',\n skillsDir: '.goose/skills',\n globalSkillsDir: join(configHome, 'goose/skills'),\n detectMarker: '.goose',\n },\n junie: {\n name: 'junie',\n displayName: 'Junie',\n skillsDir: '.junie/skills',\n globalSkillsDir: join(home, '.junie/skills'),\n detectMarker: '.junie',\n },\n 'iflow-cli': {\n name: 'iflow-cli',\n displayName: 'iFlow CLI',\n skillsDir: '.iflow/skills',\n globalSkillsDir: join(home, '.iflow/skills'),\n detectMarker: '.iflow',\n },\n kilo: {\n name: 'kilo',\n displayName: 'Kilo Code',\n skillsDir: '.kilocode/skills',\n globalSkillsDir: join(home, '.kilocode/skills'),\n detectMarker: '.kilocode',\n },\n 'kimi-cli': {\n name: 'kimi-cli',\n displayName: 'Kimi Code CLI',\n skillsDir: '.agents/skills',\n globalSkillsDir: join(home, '.config/agents/skills'),\n },\n 'kiro-cli': {\n name: 'kiro-cli',\n displayName: 'Kiro CLI',\n skillsDir: '.kiro/skills',\n globalSkillsDir: join(home, '.kiro/skills'),\n detectMarker: '.kiro',\n },\n kode: {\n name: 'kode',\n displayName: 'Kode',\n skillsDir: '.kode/skills',\n globalSkillsDir: join(home, '.kode/skills'),\n detectMarker: '.kode',\n },\n mcpjam: {\n name: 'mcpjam',\n displayName: 'MCPJam',\n skillsDir: '.mcpjam/skills',\n globalSkillsDir: join(home, '.mcpjam/skills'),\n detectMarker: '.mcpjam',\n },\n 'mistral-vibe': {\n name: 'mistral-vibe',\n displayName: 'Mistral Vibe',\n skillsDir: '.vibe/skills',\n globalSkillsDir: join(home, '.vibe/skills'),\n detectMarker: '.vibe',\n },\n mux: {\n name: 'mux',\n displayName: 'Mux',\n skillsDir: '.mux/skills',\n globalSkillsDir: join(home, '.mux/skills'),\n detectMarker: '.mux',\n },\n opencode: {\n name: 'opencode',\n displayName: 'OpenCode',\n skillsDir: '.opencode/skills',\n globalSkillsDir: join(configHome, 'opencode/skills'),\n },\n openhands: {\n name: 'openhands',\n displayName: 'OpenHands',\n skillsDir: '.openhands/skills',\n globalSkillsDir: join(home, '.openhands/skills'),\n detectMarker: '.openhands',\n },\n pi: {\n name: 'pi',\n displayName: 'Pi',\n skillsDir: '.pi/skills',\n globalSkillsDir: join(home, '.pi/agent/skills'),\n detectMarker: '.pi',\n },\n qoder: {\n name: 'qoder',\n displayName: 'Qoder',\n skillsDir: '.qoder/skills',\n globalSkillsDir: join(home, '.qoder/skills'),\n detectMarker: '.qoder',\n },\n 'qwen-code': {\n name: 'qwen-code',\n displayName: 'Qwen Code',\n skillsDir: '.qwen/skills',\n globalSkillsDir: join(home, '.qwen/skills'),\n detectMarker: '.qwen',\n },\n replit: {\n name: 'replit',\n displayName: 'Replit',\n skillsDir: '.agents/skills',\n globalSkillsDir: join(configHome, 'agents/skills'),\n },\n roo: {\n name: 'roo',\n displayName: 'Roo Code',\n skillsDir: '.roo/skills',\n globalSkillsDir: join(home, '.roo/skills'),\n detectMarker: '.roo',\n },\n trae: {\n name: 'trae',\n displayName: 'Trae',\n skillsDir: '.trae/skills',\n globalSkillsDir: join(home, '.trae/skills'),\n detectMarker: '.trae',\n },\n 'trae-cn': {\n name: 'trae-cn',\n displayName: 'Trae CN',\n skillsDir: '.trae/skills',\n globalSkillsDir: join(home, '.trae-cn/skills'),\n },\n windsurf: {\n name: 'windsurf',\n displayName: 'Windsurf',\n skillsDir: '.windsurf/skills',\n globalSkillsDir: join(home, '.codeium/windsurf/skills'),\n detectMarker: '.windsurf',\n },\n zencoder: {\n name: 'zencoder',\n displayName: 'Zencoder',\n skillsDir: '.zencoder/skills',\n globalSkillsDir: join(home, '.zencoder/skills'),\n detectMarker: '.zencoder',\n },\n neovate: {\n name: 'neovate',\n displayName: 'Neovate',\n skillsDir: '.neovate/skills',\n globalSkillsDir: join(home, '.neovate/skills'),\n detectMarker: '.neovate',\n },\n pochi: {\n name: 'pochi',\n displayName: 'Pochi',\n skillsDir: '.pochi/skills',\n globalSkillsDir: join(home, '.pochi/skills'),\n detectMarker: '.pochi',\n },\n adal: {\n name: 'adal',\n displayName: 'AdaL',\n skillsDir: '.adal/skills',\n globalSkillsDir: join(home, '.adal/skills'),\n detectMarker: '.adal',\n },\n} as const satisfies Record<string, AgentConfig>;\n\nexport type AgentPlatform = keyof typeof AGENTS;\n\n/** Get config for a specific agent */\nexport function getAgentConfig(type: AgentPlatform): AgentConfig {\n return AGENTS[type];\n}\n\n/** List all supported platform keys */\nexport function getSupportedPlatforms(): AgentPlatform[] {\n return Object.keys(AGENTS) as AgentPlatform[];\n}\n\n/** Detect current platform by checking cwd for directory markers */\nexport function detectPlatform(cwd: string): AgentPlatform {\n for (const [key, config] of Object.entries(AGENTS) as Array<[AgentPlatform, AgentConfig]>) {\n if (config.detectMarker && existsSync(join(cwd, config.detectMarker))) {\n return key;\n }\n }\n\n // Fallback: check opencode via global config\n if (existsSync(join(configHome, 'opencode'))) {\n return 'opencode';\n }\n\n return 'claude-code';\n}\n\n/** Get the project-level skills directory name for an agent */\nexport function getAgentSkillsDir(platform: AgentPlatform): string {\n return AGENTS[platform].skillsDir;\n}\n\n/** Get full skill installation path: cwd + skillsDir + skillName */\nexport function getAgentSkillPath(cwd: string, agent: AgentPlatform, name: string): string {\n return join(cwd, AGENTS[agent].skillsDir, name);\n}\n\n/** Get the global skill path: globalSkillsDir + skillName */\nexport function getAgentGlobalSkillPath(agent: AgentPlatform, name: string): string {\n return join(AGENTS[agent].globalSkillsDir, name);\n}\n\n/** Get the agent skills root directory: cwd + skillsDir */\nexport function getAgentSkillsRoot(cwd: string, agent: AgentPlatform): string {\n return join(cwd, AGENTS[agent].skillsDir);\n}\n","import { existsSync } from 'node:fs';\nimport { REGISTRY_PATH } from '../utils/paths.js';\nimport { atomicWriteJson, readJsonSafe } from '../utils/fs-helpers.js';\nimport { RegistryCorruptError } from '../utils/errors.js';\nimport type { Registry, RegistryEntry, RegistryEntryV1, AgentPlatform } from '../types/index.js';\n\n/** Create an empty v2 registry */\nfunction createEmptyRegistry(): Registry {\n return { version: 2, skills: {} };\n}\n\n/** Migrate a v1 entry to v2 format */\nfunction migrateEntryV1(v1: RegistryEntryV1): RegistryEntry {\n return {\n source: v1.source,\n version: v1.version,\n installed_at: v1.installed_at,\n updated_at: v1.updated_at,\n agents: [{\n agent: v1.agent,\n agent_path: v1.agent_path,\n global: v1.agent_path.includes('/.agents/') || v1.agent_path.includes('\\\\.agents\\\\'),\n }],\n env_keys: v1.env_keys,\n capabilities: v1.capabilities,\n canonical_path: v1.canonical_path,\n };\n}\n\n/** Validate and auto-migrate registry */\nfunction validateAndMigrate(data: unknown): Registry | null {\n if (!data || typeof data !== 'object') return null;\n const reg = data as Record<string, unknown>;\n if (typeof reg.skills !== 'object' || reg.skills === null) return null;\n\n // Already v2\n if (reg.version === 2) return data as Registry;\n\n // V1 → V2 migration\n if (reg.version === 1) {\n const v1Skills = reg.skills as Record<string, RegistryEntryV1>;\n const v2Skills: Record<string, RegistryEntry> = {};\n for (const [name, entry] of Object.entries(v1Skills)) {\n v2Skills[name] = migrateEntryV1(entry);\n }\n return { version: 2, skills: v2Skills };\n }\n\n return null;\n}\n\n/** Read the registry, auto-migrating v1 → v2 if needed */\nexport async function readRegistry(): Promise<Registry> {\n if (!existsSync(REGISTRY_PATH)) {\n return createEmptyRegistry();\n }\n\n const data = await readJsonSafe<unknown>(REGISTRY_PATH);\n if (!data) {\n throw new RegistryCorruptError('Failed to parse registry.json');\n }\n\n const registry = validateAndMigrate(data);\n if (!registry) {\n throw new RegistryCorruptError('Invalid registry structure');\n }\n\n // Persist migration if version changed\n if ((data as Record<string, unknown>).version !== registry.version) {\n await atomicWriteJson(REGISTRY_PATH, registry);\n }\n\n return registry;\n}\n\n/**\n * Update or add a skill entry in the registry (atomic write).\n * Merges agents: same agent → replace, new agent → append.\n */\nexport async function updateRegistry(\n skillName: string,\n entry: RegistryEntry,\n): Promise<void> {\n const registry = await readRegistry();\n const existing = registry.skills[skillName];\n\n if (existing) {\n // Merge agents: replace matching, append new\n for (const newAgent of entry.agents) {\n const idx = existing.agents.findIndex(a => a.agent === newAgent.agent);\n if (idx >= 0) {\n existing.agents[idx] = newAgent;\n } else {\n existing.agents.push(newAgent);\n }\n }\n // Update other fields\n existing.source = entry.source;\n existing.version = entry.version;\n existing.updated_at = entry.updated_at;\n existing.env_keys = entry.env_keys;\n existing.capabilities = entry.capabilities;\n existing.canonical_path = entry.canonical_path;\n } else {\n registry.skills[skillName] = entry;\n }\n\n await atomicWriteJson(REGISTRY_PATH, registry);\n}\n\n/** Remove a single agent record from a skill. Removes entire entry if last agent. */\nexport async function removeAgentFromRegistry(\n skillName: string,\n agent: AgentPlatform,\n): Promise<void> {\n const registry = await readRegistry();\n const entry = registry.skills[skillName];\n if (!entry) return;\n\n entry.agents = entry.agents.filter(a => a.agent !== agent);\n if (entry.agents.length === 0) {\n delete registry.skills[skillName];\n }\n await atomicWriteJson(REGISTRY_PATH, registry);\n}\n\n/** Remove a skill entirely from the registry */\nexport async function removeFromRegistry(skillName: string): Promise<void> {\n const registry = await readRegistry();\n delete registry.skills[skillName];\n await atomicWriteJson(REGISTRY_PATH, registry);\n}\n\n/** List all registered skills */\nexport async function listRegistry(): Promise<Record<string, RegistryEntry>> {\n const registry = await readRegistry();\n return registry.skills;\n}\n\n/** Get a single registry entry */\nexport async function getRegistryEntry(skillName: string): Promise<RegistryEntry | null> {\n const registry = await readRegistry();\n return registry.skills[skillName] ?? null;\n}\n","import { installSkill } from '../core/installer.js';\nimport { cloneRepo, parseSource } from '../core/git-source.js';\nimport { findAllSkillDirectories, readSkillMd } from '../core/skill-parser.js';\nimport { SkillNotFoundError } from '../utils/errors.js';\nimport * as logger from '../utils/logger.js';\nimport type { SkillSource, AgentPlatform } from '../types/index.js';\nimport { existsSync } from 'node:fs';\nimport { basename, join } from 'node:path';\n\nexport interface AddFlags {\n global: boolean;\n agent: string[];\n skill: string[];\n yes: boolean;\n list: boolean;\n all: boolean;\n fullDepth: boolean;\n copy: boolean;\n force: boolean;\n help: boolean;\n}\n\n/**\n * Parse POSIX-style flags for the add command.\n * Supports: -g/--global, -a/--agent, -s/--skill, -y/--yes,\n * -l/--list, --all, --full-depth, --copy, --force\n */\nexport function parseAddFlags(args: string[]): { source: string | null; flags: AddFlags } {\n const flags: AddFlags = {\n global: false,\n agent: [],\n skill: [],\n yes: false,\n list: false,\n all: false,\n fullDepth: false,\n copy: false,\n force: false,\n help: false,\n };\n\n let source: string | null = null;\n let i = 0;\n\n while (i < args.length) {\n const arg = args[i];\n\n // Long flags with = syntax (backward compat: --agent=claude-code)\n if (arg.startsWith('--') && arg.includes('=')) {\n const eqIdx = arg.indexOf('=');\n const key = arg.slice(2, eqIdx);\n const val = arg.slice(eqIdx + 1);\n switch (key) {\n case 'agent': flags.agent.push(val); break;\n case 'skill': flags.skill.push(val); break;\n default:\n throw new Error(`Unknown option: --${key}`);\n }\n i++;\n continue;\n }\n\n switch (arg) {\n case '-h':\n case '--help':\n flags.help = true;\n i++;\n break;\n\n case '-g':\n case '--global':\n flags.global = true;\n i++;\n break;\n\n case '-a':\n case '--agent':\n i++;\n while (i < args.length && !args[i].startsWith('-')) {\n flags.agent.push(args[i]);\n i++;\n }\n break;\n\n case '-s':\n case '--skill':\n i++;\n while (i < args.length && !args[i].startsWith('-')) {\n flags.skill.push(args[i]);\n i++;\n }\n break;\n\n case '-y':\n case '--yes':\n flags.yes = true;\n i++;\n break;\n\n case '-l':\n case '--list':\n flags.list = true;\n i++;\n break;\n\n case '--all':\n flags.all = true;\n i++;\n break;\n\n case '--full-depth':\n flags.fullDepth = true;\n i++;\n break;\n\n case '--copy':\n flags.copy = true;\n i++;\n break;\n\n case '--force':\n flags.force = true;\n i++;\n break;\n\n default:\n // First non-flag argument is the source\n if (!arg.startsWith('-') && source === null) {\n source = arg;\n } else if (arg.startsWith('-')) {\n throw new Error(`Unknown option: ${arg}`);\n }\n i++;\n break;\n }\n }\n\n // --all implies --skill '*' --agent '*' -y\n if (flags.all) {\n if (flags.skill.length === 0) flags.skill.push('*');\n if (flags.agent.length === 0) flags.agent.push('*');\n flags.yes = true;\n }\n\n return { source, flags };\n}\n\nfunction printAddHelp(): void {\n console.log('Usage: skill-master add <source> [options]');\n console.log('');\n console.log('Options:');\n console.log(' -h, --help Show this help message');\n console.log(' -g, --global Install globally (~/.agents/)');\n console.log(' -a, --agent <agents> Target agents (space-separated)');\n console.log(' -s, --skill <skills> Select skills (space-separated)');\n console.log(' -y, --yes Skip confirmations');\n console.log(' -l, --list List available skills without installing');\n console.log(' --all Install all skills to all agents');\n console.log(' --full-depth Search all subdirectories');\n console.log(' --copy Copy instead of symlink');\n console.log(' --force Force reinstall');\n}\n\n/** add command — install skills (compatible with `npx skills add`) */\nexport async function add(args: string[]): Promise<void> {\n if (args.length === 0) {\n printAddHelp();\n process.exit(1);\n }\n\n const { source, flags } = parseAddFlags(args);\n\n if (flags.help) {\n printAddHelp();\n process.exit(0);\n }\n\n if (!source) {\n logger.error('No source specified. Provide a GitHub URL, owner/repo, or local path.');\n process.exit(1);\n }\n\n const cwd = process.cwd();\n\n // Parse source string into structured form\n const parsed = parseSource(source);\n\n // Merge skillFilter from source (e.g. owner/repo@skill) into flags.skill\n if (parsed.skillFilter && !flags.skill.includes(parsed.skillFilter)) {\n flags.skill.push(parsed.skillFilter);\n }\n\n // Resolve source directory\n let sourceDir: string;\n\n if (parsed.type === 'git') {\n logger.step(1, 9, 'Fetching skill source...');\n sourceDir = await cloneRepo(parsed.url!, parsed.ref);\n // Narrow to subpath if specified\n if (parsed.subpath) {\n const sub = join(sourceDir, parsed.subpath);\n if (existsSync(sub)) {\n sourceDir = sub;\n }\n }\n } else {\n sourceDir = parsed.path!;\n if (!existsSync(sourceDir)) {\n throw new SkillNotFoundError(sourceDir);\n }\n }\n\n // Discover all skill directories in the source\n const allSkillDirs = await findAllSkillDirectories(sourceDir, flags.fullDepth);\n if (allSkillDirs.length === 0) {\n throw new SkillNotFoundError(`No SKILL.md found in ${sourceDir}`);\n }\n\n // --list mode: print discovered skills and exit\n if (flags.list) {\n logger.blank();\n logger.tableHeader('Skill', 'Version', 'Description');\n for (const dir of allSkillDirs) {\n const sk = await readSkillMd(dir);\n if (sk) {\n logger.tableRow(\n sk.frontmatter.name,\n sk.frontmatter.version ?? '-',\n sk.frontmatter.description ?? '-',\n );\n }\n }\n logger.blank();\n return;\n }\n\n // Filter by --skill if specified\n let targetDirs = allSkillDirs;\n if (flags.skill.length > 0 && !flags.skill.includes('*')) {\n const requested = new Set(flags.skill.map(s => s.toLowerCase()));\n const filtered: string[] = [];\n\n for (const dir of allSkillDirs) {\n const sk = await readSkillMd(dir);\n if (!sk) continue;\n const name = sk.frontmatter.name.toLowerCase();\n const dirName = basename(dir).toLowerCase();\n if (requested.has(name) || requested.has(dirName)) {\n filtered.push(dir);\n }\n }\n\n if (filtered.length === 0) {\n const available = [];\n for (const dir of allSkillDirs) {\n const sk = await readSkillMd(dir);\n if (sk) available.push(sk.frontmatter.name);\n }\n logger.error(\n `No matching skills found for: ${flags.skill.join(', ')}\\n` +\n ` Available skills: ${available.join(', ')}`\n );\n process.exit(1);\n }\n\n targetDirs = filtered;\n }\n\n // If multiple agents specified, install for each\n const agents = flags.agent.length > 0 ? flags.agent : [undefined];\n\n try {\n for (const dir of targetDirs) {\n for (const agent of agents) {\n await installSkill({\n source: { type: 'local', path: dir },\n agent: agent as AgentPlatform | undefined,\n cwd,\n global: flags.global,\n copy: flags.copy,\n force: flags.force,\n yes: flags.yes,\n });\n }\n }\n } catch (err) {\n logger.error((err as Error).message);\n process.exit(1);\n }\n}\n","import { getRegistryEntry } from '../core/registry.js';\nimport { installSkill } from '../core/installer.js';\nimport { isGitUrl } from '../core/git-source.js';\nimport * as logger from '../utils/logger.js';\nimport { SkillNotFoundError } from '../utils/errors.js';\nimport type { SkillSource } from '../types/index.js';\n\nexport async function update(args: string[]): Promise<void> {\n if (args.length === 0) {\n logger.error('Usage: skill-master update <skill-name> [--force]');\n process.exit(1);\n }\n\n const skillName = args[0];\n const force = args.includes('--force');\n\n try {\n const entry = await getRegistryEntry(skillName);\n if (!entry) {\n throw new SkillNotFoundError(skillName);\n }\n\n logger.info(`Updating skill: ${skillName}`);\n logger.info(`Source: ${entry.source}`);\n\n const source: SkillSource = isGitUrl(entry.source)\n ? { type: 'git', url: entry.source }\n : { type: 'local', path: entry.source };\n\n // Reinstall for each registered agent\n for (const agentRecord of entry.agents) {\n await installSkill({\n source,\n agent: agentRecord.agent,\n cwd: process.cwd(),\n global: agentRecord.global,\n force: true,\n });\n }\n\n logger.success(`Skill \"${skillName}\" updated successfully!`);\n } catch (err) {\n logger.error((err as Error).message);\n process.exit(1);\n }\n}\n","import { getRegistryEntry, removeFromRegistry, removeAgentFromRegistry, listRegistry } from '../core/registry.js';\nimport { removePath } from '../utils/fs-helpers.js';\nimport { getSkillCanonicalPath, getSkillConfigPath, getAgentGlobalSkillPath } from '../utils/paths.js';\nimport * as logger from '../utils/logger.js';\nimport { SkillNotFoundError } from '../utils/errors.js';\nimport type { AgentPlatform } from '../types/index.js';\n\nexport interface RemoveFlags {\n global: boolean;\n agent: string[];\n skill: string[];\n yes: boolean;\n all: boolean;\n purge: boolean;\n help: boolean;\n}\n\n/** Parse POSIX-style flags for the remove command */\nexport function parseRemoveFlags(args: string[]): { names: string[]; flags: RemoveFlags } {\n const flags: RemoveFlags = {\n global: false,\n agent: [],\n skill: [],\n yes: false,\n all: false,\n purge: false,\n help: false,\n };\n\n const names: string[] = [];\n let i = 0;\n\n while (i < args.length) {\n const arg = args[i];\n\n // Long flags with = syntax (backward compat: --agent=claude-code)\n if (arg.startsWith('--') && arg.includes('=')) {\n const eqIdx = arg.indexOf('=');\n const key = arg.slice(2, eqIdx);\n const val = arg.slice(eqIdx + 1);\n switch (key) {\n case 'agent': flags.agent.push(val); break;\n case 'skill': flags.skill.push(val); break;\n default:\n throw new Error(`Unknown option: --${key}`);\n }\n i++;\n continue;\n }\n\n switch (arg) {\n case '-h':\n case '--help':\n flags.help = true;\n i++;\n break;\n\n case '-g':\n case '--global':\n flags.global = true;\n i++;\n break;\n\n case '-a':\n case '--agent':\n i++;\n while (i < args.length && !args[i].startsWith('-')) {\n flags.agent.push(args[i]);\n i++;\n }\n break;\n\n case '-s':\n case '--skill':\n i++;\n while (i < args.length && !args[i].startsWith('-')) {\n flags.skill.push(args[i]);\n i++;\n }\n break;\n\n case '-y':\n case '--yes':\n flags.yes = true;\n i++;\n break;\n\n case '--all':\n flags.all = true;\n i++;\n break;\n\n case '--purge':\n flags.purge = true;\n i++;\n break;\n\n default:\n // Non-flag arguments are skill names (positional)\n if (!arg.startsWith('-')) {\n names.push(arg);\n } else {\n throw new Error(`Unknown option: ${arg}`);\n }\n i++;\n break;\n }\n }\n\n // --all implies removing all skills with -y\n if (flags.all) {\n flags.yes = true;\n }\n\n return { names, flags };\n}\n\nfunction printRemoveHelp(): void {\n console.log('Usage: skill-master remove [skills...] [options]');\n console.log('');\n console.log('Options:');\n console.log(' -h, --help Show this help message');\n console.log(' -g, --global Remove from global (~/.agents/)');\n console.log(' -a, --agent <agents> Target agents (space-separated)');\n console.log(' -s, --skill <skills> Select skills (space-separated)');\n console.log(' -y, --yes Skip confirmations');\n console.log(' --all Remove all skills');\n console.log(' --purge Also remove config data');\n}\n\n/** remove command — remove installed skills */\nexport async function remove(args: string[]): Promise<void> {\n if (args.length === 0) {\n printRemoveHelp();\n process.exit(1);\n }\n\n const { names, flags } = parseRemoveFlags(args);\n\n if (flags.help) {\n printRemoveHelp();\n process.exit(0);\n }\n\n // Determine which skills to remove\n let skillNames: string[];\n if (flags.all) {\n const registry = await listRegistry();\n skillNames = Object.keys(registry);\n } else if (flags.skill.length > 0) {\n skillNames = flags.skill;\n } else {\n skillNames = names;\n }\n\n if (skillNames.length === 0) {\n logger.error('No skills specified. Provide skill names or use --all.');\n process.exit(1);\n }\n\n try {\n for (const skillName of skillNames) {\n const entry = await getRegistryEntry(skillName);\n if (!entry) {\n throw new SkillNotFoundError(skillName);\n }\n\n logger.info(`Removing skill: ${skillName}`);\n\n if (flags.agent.length > 0) {\n // Remove only specified agent(s)\n for (const agentName of flags.agent) {\n const agentRecord = entry.agents.find(a => a.agent === agentName);\n if (!agentRecord) {\n logger.warn(`Agent \"${agentName}\" not found for skill \"${skillName}\"`);\n continue;\n }\n await removePath(agentRecord.agent_path);\n logger.success(`Removed ${agentName} path: ${agentRecord.agent_path}`);\n await removeAgentFromRegistry(skillName, agentName as AgentPlatform);\n }\n\n // Check if all agents removed — if so, clean up canonical\n const updated = await getRegistryEntry(skillName);\n if (!updated) {\n await removePath(entry.canonical_path);\n logger.success(`Removed canonical path: ${entry.canonical_path}`);\n if (flags.purge) {\n await removePath(getSkillConfigPath(skillName));\n logger.success('Purged config directory');\n }\n }\n } else {\n // Remove all agent paths\n for (const agentRecord of entry.agents) {\n await removePath(agentRecord.agent_path);\n logger.success(`Removed ${agentRecord.agent} path: ${agentRecord.agent_path}`);\n }\n\n // Remove canonical directory\n await removePath(entry.canonical_path);\n logger.success(`Removed canonical path: ${entry.canonical_path}`);\n\n // Optionally purge config\n if (flags.purge) {\n await removePath(getSkillConfigPath(skillName));\n logger.success('Purged config directory');\n }\n\n // Remove entire registry entry\n await removeFromRegistry(skillName);\n }\n\n logger.success(`Skill \"${skillName}\" removed successfully!`);\n }\n } catch (err) {\n logger.error((err as Error).message);\n process.exit(1);\n }\n}\n","import { listRegistry } from '../core/registry.js';\nimport { getEnvStatus, setEnvValue, getEnvEditPath } from '../core/env-manager.js';\nimport { getSkillCanonicalPath } from '../utils/paths.js';\nimport * as logger from '../utils/logger.js';\nimport { spawn } from 'node:child_process';\n\nexport async function env(args: string[]): Promise<void> {\n const subcommand = args[0];\n\n if (!subcommand || subcommand === 'list') {\n await envList();\n } else if (subcommand === 'set') {\n await envSet(args.slice(1));\n } else if (subcommand === 'edit') {\n await envEdit(args.slice(1));\n } else {\n logger.error('Usage: skill-master env <list|set|edit>');\n process.exit(1);\n }\n}\n\nasync function envList(): Promise<void> {\n const skills = await listRegistry();\n const entries = Object.entries(skills);\n\n if (entries.length === 0) {\n logger.info('No skills installed');\n return;\n }\n\n logger.blank();\n logger.tableHeader('Skill', 'Status', 'Keys');\n\n for (const [name, entry] of entries) {\n const status = await getEnvStatus(name, entry.env_keys);\n const statusIcon = status === 'configured' ? '✓' : status === 'partial' ? '⚠' : '✗';\n logger.tableRow(name, `${statusIcon} ${status}`, entry.env_keys.join(', '));\n }\n logger.blank();\n}\n\nasync function envSet(args: string[]): Promise<void> {\n if (args.length < 2) {\n logger.error('Usage: skill-master env set <skill> KEY=VALUE');\n process.exit(1);\n }\n\n const skillName = args[0];\n const [key, value] = args[1].split('=');\n\n if (!key || !value) {\n logger.error('Invalid format. Use: KEY=VALUE');\n process.exit(1);\n }\n\n try {\n const skillDir = getSkillCanonicalPath(skillName);\n await setEnvValue(skillName, key, value, skillDir);\n logger.success(`Set ${key} for ${skillName}`);\n } catch (err) {\n logger.error((err as Error).message);\n process.exit(1);\n }\n}\n\nasync function envEdit(args: string[]): Promise<void> {\n if (args.length === 0) {\n logger.error('Usage: skill-master env edit <skill>');\n process.exit(1);\n }\n\n const skillName = args[0];\n const envPath = getEnvEditPath(skillName);\n const editor = process.env.EDITOR || 'vi';\n\n logger.info(`Opening ${envPath} with ${editor}...`);\n\n const child = spawn(editor, [envPath], {\n stdio: 'inherit',\n shell: true,\n });\n\n child.on('exit', (code) => {\n if (code === 0) {\n logger.success('Saved');\n } else {\n logger.error('Editor exited with error');\n process.exit(1);\n }\n });\n}\n","import { listRegistry } from '../core/registry.js';\nimport * as logger from '../utils/logger.js';\n\nexport interface ListFlags {\n global: boolean;\n agent: string[];\n}\n\n/** Parse flags for the list command */\nexport function parseListFlags(args: string[]): ListFlags {\n const flags: ListFlags = {\n global: false,\n agent: [],\n };\n\n let i = 0;\n while (i < args.length) {\n const arg = args[i];\n\n if (arg.startsWith('--') && arg.includes('=')) {\n const eqIdx = arg.indexOf('=');\n const key = arg.slice(2, eqIdx);\n const val = arg.slice(eqIdx + 1);\n if (key === 'agent') flags.agent.push(val);\n i++;\n continue;\n }\n\n switch (arg) {\n case '-g':\n case '--global':\n flags.global = true;\n i++;\n break;\n case '-a':\n case '--agent':\n i++;\n while (i < args.length && !args[i].startsWith('-')) {\n flags.agent.push(args[i]);\n i++;\n }\n break;\n default:\n i++;\n break;\n }\n }\n\n return flags;\n}\n\n/** list command — list installed skills */\nexport async function list(args: string[] = []): Promise<void> {\n const flags = parseListFlags(args);\n const skills = await listRegistry();\n let entries = Object.entries(skills);\n\n // Filter by agent if specified\n if (flags.agent.length > 0) {\n entries = entries.filter(([, entry]) =>\n entry.agents.some(a => flags.agent.includes(a.agent))\n );\n }\n\n if (entries.length === 0) {\n logger.info('No skills installed');\n return;\n }\n\n logger.blank();\n logger.tableHeader('Skill', 'Version', 'Platform(s)', 'Installed');\n\n for (const [name, entry] of entries) {\n const date = new Date(entry.installed_at).toLocaleDateString();\n const platforms = entry.agents.map(a => a.agent).join(', ');\n logger.tableRow(name, entry.version ?? '-', platforms, date);\n }\n logger.blank();\n}\n","import { getRegistryEntry } from '../core/registry.js';\nimport { getEnvStatus } from '../core/env-manager.js';\nimport * as logger from '../utils/logger.js';\nimport { SkillNotFoundError } from '../utils/errors.js';\n\nexport async function info(args: string[]): Promise<void> {\n if (args.length === 0) {\n logger.error('Usage: skill-master info <skill-name>');\n process.exit(1);\n }\n\n const skillName = args[0];\n\n try {\n const entry = await getRegistryEntry(skillName);\n if (!entry) {\n throw new SkillNotFoundError(skillName);\n }\n\n const envStatus = await getEnvStatus(skillName, entry.env_keys);\n\n logger.blank();\n logger.info(`Skill: ${skillName}`);\n logger.kv('Version', entry.version ?? '-');\n logger.kv('Platform(s)', entry.agents.map(a => a.agent).join(', '));\n logger.kv('Source', entry.source);\n logger.kv('Installed', new Date(entry.installed_at).toLocaleString());\n logger.kv('Updated', new Date(entry.updated_at).toLocaleString());\n logger.kv('Canonical Path', entry.canonical_path);\n\n // Show all agent paths\n for (const a of entry.agents) {\n logger.kv(` ${a.agent} Path`, `${a.agent_path}${a.global ? ' (global)' : ''}`);\n }\n\n logger.kv('Capabilities', entry.capabilities.join(', '));\n logger.kv('Env Keys', entry.env_keys.join(', ') || 'none');\n logger.kv('Env Status', envStatus);\n logger.blank();\n } catch (err) {\n logger.error((err as Error).message);\n process.exit(1);\n }\n}\n","import { existsSync } from 'node:fs';\nimport { listRegistry } from '../core/registry.js';\nimport { getEnvStatus } from '../core/env-manager.js';\nimport { isSymlink } from '../utils/fs-helpers.js';\nimport { AGENTS_HOME, CONFIG_DIR, SKILLS_DIR, REGISTRY_PATH } from '../utils/paths.js';\nimport * as logger from '../utils/logger.js';\n\nexport async function doctor(): Promise<void> {\n logger.blank();\n logger.info('Running diagnostics...');\n logger.blank();\n\n let issues = 0;\n\n // Check directory structure\n logger.info('Checking directory structure...');\n const dirs = [AGENTS_HOME, CONFIG_DIR, SKILLS_DIR];\n for (const dir of dirs) {\n if (existsSync(dir)) {\n logger.success(`✓ ${dir}`);\n } else {\n logger.warn(`✗ ${dir} (missing)`);\n issues++;\n }\n }\n logger.blank();\n\n // Check registry\n logger.info('Checking registry...');\n if (existsSync(REGISTRY_PATH)) {\n logger.success(`✓ ${REGISTRY_PATH}`);\n try {\n const skills = await listRegistry();\n logger.info(` Found ${Object.keys(skills).length} skill(s)`);\n } catch (err) {\n logger.error(`✗ Registry corrupted: ${(err as Error).message}`);\n issues++;\n }\n } else {\n logger.info(` No registry found (will be created on first install)`);\n }\n logger.blank();\n\n // Check each skill\n logger.info('Checking installed skills...');\n try {\n const skills = await listRegistry();\n for (const [name, entry] of Object.entries(skills)) {\n logger.info(`Skill: ${name}`);\n\n // Check canonical path\n if (existsSync(entry.canonical_path)) {\n logger.success(` ✓ Canonical path exists`);\n } else {\n logger.error(` ✗ Canonical path missing: ${entry.canonical_path}`);\n issues++;\n }\n\n // Check each agent path\n for (const agentRecord of entry.agents) {\n if (existsSync(agentRecord.agent_path)) {\n const isLink = await isSymlink(agentRecord.agent_path);\n logger.success(` ✓ ${agentRecord.agent} path exists (${isLink ? 'symlink' : 'copy'}${agentRecord.global ? ', global' : ''})`);\n } else {\n logger.error(` ✗ ${agentRecord.agent} path missing: ${agentRecord.agent_path}`);\n issues++;\n }\n }\n\n // Check env status\n const envStatus = await getEnvStatus(name, entry.env_keys);\n if (envStatus === 'configured') {\n logger.success(` ✓ Environment configured`);\n } else if (envStatus === 'partial') {\n logger.warn(` ⚠ Environment partially configured`);\n } else if (entry.env_keys.length > 0) {\n logger.warn(` ⚠ Environment not configured`);\n }\n }\n } catch (err) {\n logger.error(`Failed to check skills: ${(err as Error).message}`);\n issues++;\n }\n\n logger.blank();\n if (issues === 0) {\n logger.success('All checks passed!');\n } else {\n logger.warn(`Found ${issues} issue(s)`);\n }\n logger.blank();\n}\n","import * as logger from '../utils/logger.js';\n\n/** find command — search for skills from the registry */\nexport async function find(args: string[]): Promise<void> {\n const query = args.filter(a => !a.startsWith('-')).join(' ').trim();\n\n if (!query) {\n console.log('Usage: skill-master find <query>');\n console.log('');\n console.log('Search for skills in the online registry.');\n console.log('');\n console.log('Examples:');\n console.log(' skill-master find git');\n console.log(' skill-master find \"code review\"');\n process.exit(0);\n }\n\n logger.info(`Searching for \"${query}\"...`);\n\n try {\n const url = `https://skills.sh/api/search?q=${encodeURIComponent(query)}`;\n const response = await fetch(url, {\n headers: { 'Accept': 'application/json' },\n signal: AbortSignal.timeout(10_000),\n });\n\n if (!response.ok) {\n logger.error(`Search API returned ${response.status}: ${response.statusText}`);\n process.exit(1);\n }\n\n const data = await response.json() as SearchResult[];\n\n if (!Array.isArray(data) || data.length === 0) {\n logger.info('No skills found matching your query.');\n return;\n }\n\n logger.blank();\n logger.tableHeader('Name', 'Source', 'Installs');\n\n for (const item of data) {\n logger.tableRow(\n item.name ?? '—',\n item.source ?? '—',\n String(item.installs ?? 0),\n );\n }\n logger.blank();\n } catch (err) {\n if ((err as Error).name === 'TimeoutError') {\n logger.error('Search request timed out. Please try again.');\n } else {\n logger.error(`Search failed: ${(err as Error).message}`);\n }\n process.exit(1);\n }\n}\n\ninterface SearchResult {\n name?: string;\n source?: string;\n installs?: number;\n}\n","import { existsSync } from 'node:fs';\nimport { join, basename } from 'node:path';\nimport { ensureDir, writeText } from '../utils/fs-helpers.js';\nimport * as logger from '../utils/logger.js';\n\nconst SKILL_MD_TEMPLATE = `---\nname: {{NAME}}\nversion: 0.1.0\nauthor: \"\"\ndescription: \"\"\nallowed-tools:\n - Read\n - Edit\n - Write\n - Bash\n - Glob\n - Grep\nuser-invocable: true\n---\n\n# {{NAME}}\n\n<!-- Describe what this skill does -->\n`;\n\n/** init command — create a new skill template */\nexport async function init(args: string[]): Promise<void> {\n const nameArg = args.filter(a => !a.startsWith('-'))[0];\n const cwd = process.cwd();\n\n let targetDir: string;\n let skillName: string;\n\n if (nameArg) {\n targetDir = join(cwd, nameArg);\n skillName = nameArg;\n } else {\n targetDir = cwd;\n skillName = basename(cwd);\n }\n\n const skillMdPath = join(targetDir, 'SKILL.md');\n\n if (existsSync(skillMdPath)) {\n logger.error(`SKILL.md already exists at ${skillMdPath}`);\n process.exit(1);\n }\n\n await ensureDir(targetDir);\n\n const content = SKILL_MD_TEMPLATE\n .replace(/\\{\\{NAME\\}\\}/g, skillName);\n\n await writeText(skillMdPath, content);\n logger.success(`Created ${skillMdPath}`);\n logger.info(`Edit the file to configure your skill.`);\n}\n","import { execFile } from 'node:child_process';\nimport { promisify } from 'node:util';\nimport { listRegistry } from '../core/registry.js';\nimport { isGitUrl, parseGitUrl } from '../core/git-source.js';\nimport * as logger from '../utils/logger.js';\n\nconst execFileAsync = promisify(execFile);\n\n/** check command — check for skill updates */\nexport async function check(_args: string[]): Promise<void> {\n const skills = await listRegistry();\n const entries = Object.entries(skills);\n\n if (entries.length === 0) {\n logger.info('No skills installed');\n return;\n }\n\n logger.info('Checking for updates...');\n logger.blank();\n\n let updatable = 0;\n\n for (const [name, entry] of entries) {\n if (!isGitUrl(entry.source)) {\n logger.info(`${name}: local source — skipped`);\n continue;\n }\n\n // Skip version check for skills without version info\n if (!entry.version) {\n logger.info(`${name}: no version info — skipped`);\n continue;\n }\n\n try {\n const remoteHead = await getRemoteHead(entry.source);\n if (!remoteHead) {\n logger.warn(`${name}: unable to query remote`);\n continue;\n }\n\n // Compare with installed version (stored as git short hash or semver)\n // If version differs from remote HEAD, an update is available\n const isUpToDate = entry.version === remoteHead.slice(0, entry.version.length);\n if (isUpToDate) {\n logger.success(`${name}: up to date (${entry.version})`);\n } else {\n logger.warn(`${name}: update available (${entry.version} → ${remoteHead.slice(0, 7)})`);\n updatable++;\n }\n } catch {\n logger.warn(`${name}: failed to check remote`);\n }\n }\n\n logger.blank();\n if (updatable === 0) {\n logger.success('All skills are up to date!');\n } else {\n logger.info(`${updatable} skill(s) can be updated. Run \"skill-master update <name>\" to update.`);\n }\n}\n\n/** Get the latest commit hash from a remote git repo */\nasync function getRemoteHead(source: string): Promise<string | null> {\n try {\n const { owner, repo } = parseGitUrl(source);\n const url = `https://github.com/${owner}/${repo}.git`;\n const { stdout } = await execFileAsync('git', ['ls-remote', url, 'HEAD'], {\n timeout: 15_000,\n });\n const match = stdout.trim().split(/\\s+/)[0];\n return match || null;\n } catch {\n return null;\n }\n}\n","#!/usr/bin/env node\n\nimport { add } from './commands/add.js';\nimport { update } from './commands/update.js';\nimport { remove } from './commands/remove.js';\nimport { env } from './commands/env.js';\nimport { list } from './commands/list.js';\nimport { info } from './commands/info.js';\nimport { doctor } from './commands/doctor.js';\nimport { find } from './commands/find.js';\nimport { init } from './commands/init.js';\nimport { check } from './commands/check.js';\nimport * as logger from './utils/logger.js';\n\nconst VERSION = '0.1.0';\n\nconst HELP = `\nskill-master v${VERSION}\n\nUsage:\n skill-master add <source> [options] Install skills (aliases: install, a, i)\n skill-master remove [skills...] [opts] Remove skills (aliases: rm, r)\n skill-master list [options] List installed skills (alias: ls)\n skill-master find [query] Search for skills (aliases: search, f, s)\n skill-master update [skill] Update skills (alias: upgrade)\n skill-master init [name] Create a new skill template\n skill-master check Check for skill updates\n skill-master env <list|set|edit> Manage environment variables\n skill-master info <skill-name> Show skill details\n skill-master doctor Run diagnostics\n\nAdd Options:\n -g, --global Install globally (~/.agents/)\n -a, --agent <agents> Target agents (space-separated)\n -s, --skill <skills> Select skills (space-separated)\n -y, --yes Skip confirmations\n -l, --list List available skills without installing\n --all Install all skills to all agents\n --full-depth Search all subdirectories\n --copy Copy instead of symlink\n --force Force reinstall\n\nExamples:\n skill-master add owner/repo\n skill-master add https://github.com/user/skill -a claude-code cursor -y\n skill-master add ./local-skill --agent=cursor --copy\n skill-master remove my-skill --purge\n skill-master find \"code review\"\n skill-master init my-new-skill\n skill-master check\n`;\n\nasync function main() {\n const args = process.argv.slice(2);\n\n if (args.length === 0 || args[0] === '--help' || args[0] === '-h') {\n console.log(HELP);\n process.exit(0);\n }\n\n if (args[0] === '--version' || args[0] === '-v') {\n console.log(VERSION);\n process.exit(0);\n }\n\n const command = args[0];\n const commandArgs = args.slice(1);\n\n try {\n switch (command) {\n // add (primary) with aliases: install, a, i\n case 'add':\n case 'a':\n case 'install':\n case 'i':\n await add(commandArgs);\n break;\n\n // remove with aliases: rm, r\n case 'remove':\n case 'rm':\n case 'r':\n await remove(commandArgs);\n break;\n\n // list with alias: ls\n case 'list':\n case 'ls':\n await list(commandArgs);\n break;\n\n // find with aliases: search, f, s\n case 'find':\n case 'search':\n case 'f':\n case 's':\n await find(commandArgs);\n break;\n\n // update with alias: upgrade\n case 'update':\n case 'upgrade':\n await update(commandArgs);\n break;\n\n // init\n case 'init':\n await init(commandArgs);\n break;\n\n // check\n case 'check':\n await check(commandArgs);\n break;\n\n // env, info, doctor — skill-master extensions\n case 'env':\n await env(commandArgs);\n break;\n case 'info':\n await info(commandArgs);\n break;\n case 'doctor':\n await doctor();\n break;\n\n default:\n logger.error(`Unknown command: ${command}`);\n console.log(HELP);\n process.exit(1);\n }\n } catch (err) {\n logger.error((err as Error).message);\n if (process.env.DEBUG) {\n console.error(err);\n }\n process.exit(1);\n }\n}\n\nmain();\n"],"mappings":"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","names":["join","existsSync","existsSync","existsSync","join","existsSync","results","existsSync","join","join","homedir","join","existsSync","join","existsSync","join","join","join","homedir","join","existsSync","existsSync","existsSync","join","existsSync","basename","join","info","existsSync","existsSync","existsSync","join","basename","join","basename","existsSync","execFile","promisify","execFileAsync","promisify","execFile","info"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skill-master",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "Cross-platform skill package manager for AI coding agents",
5
5
  "type": "module",
6
6
  "main": "./dist/cli.js",