skill-master 0.1.4 → 0.1.5
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 +80 -25
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -261,8 +261,14 @@ function inferCapabilities(allowedTools) {
|
|
|
261
261
|
return [...caps];
|
|
262
262
|
}
|
|
263
263
|
async function findSkillDirectory(dir) {
|
|
264
|
+
const dirs = await findAllSkillDirectories(dir);
|
|
265
|
+
return dirs.length > 0 ? dirs[0] : null;
|
|
266
|
+
}
|
|
267
|
+
async function findAllSkillDirectories(dir) {
|
|
268
|
+
const results = [];
|
|
264
269
|
if (existsSync3(join2(dir, "SKILL.md"))) {
|
|
265
|
-
|
|
270
|
+
results.push(dir);
|
|
271
|
+
return results;
|
|
266
272
|
}
|
|
267
273
|
const skillsRoot = join2(dir, ".claude", "skills");
|
|
268
274
|
if (existsSync3(skillsRoot)) {
|
|
@@ -272,7 +278,7 @@ async function findSkillDirectory(dir) {
|
|
|
272
278
|
if (entry.isDirectory()) {
|
|
273
279
|
const skillMdPath = join2(skillsRoot, entry.name, "SKILL.md");
|
|
274
280
|
if (existsSync3(skillMdPath)) {
|
|
275
|
-
|
|
281
|
+
results.push(join2(skillsRoot, entry.name));
|
|
276
282
|
}
|
|
277
283
|
}
|
|
278
284
|
}
|
|
@@ -285,13 +291,13 @@ async function findSkillDirectory(dir) {
|
|
|
285
291
|
if (entry.isDirectory() && !entry.name.startsWith(".")) {
|
|
286
292
|
const skillMdPath = join2(dir, entry.name, "SKILL.md");
|
|
287
293
|
if (existsSync3(skillMdPath)) {
|
|
288
|
-
|
|
294
|
+
results.push(join2(dir, entry.name));
|
|
289
295
|
}
|
|
290
296
|
}
|
|
291
297
|
}
|
|
292
298
|
} catch {
|
|
293
299
|
}
|
|
294
|
-
return
|
|
300
|
+
return results;
|
|
295
301
|
}
|
|
296
302
|
async function readSkillMd(dir) {
|
|
297
303
|
const content = await readTextSafe(join2(dir, "SKILL.md"));
|
|
@@ -842,6 +848,8 @@ async function installSkill(options) {
|
|
|
842
848
|
}
|
|
843
849
|
|
|
844
850
|
// src/commands/add.ts
|
|
851
|
+
import { existsSync as existsSync7 } from "fs";
|
|
852
|
+
import { basename as basename2 } from "path";
|
|
845
853
|
function parseAddFlags(args) {
|
|
846
854
|
const flags = {
|
|
847
855
|
global: false,
|
|
@@ -870,7 +878,7 @@ function parseAddFlags(args) {
|
|
|
870
878
|
flags.skill.push(val);
|
|
871
879
|
break;
|
|
872
880
|
default:
|
|
873
|
-
|
|
881
|
+
throw new Error(`Unknown option: --${key}`);
|
|
874
882
|
}
|
|
875
883
|
i++;
|
|
876
884
|
continue;
|
|
@@ -926,6 +934,8 @@ function parseAddFlags(args) {
|
|
|
926
934
|
default:
|
|
927
935
|
if (!arg.startsWith("-") && source === null) {
|
|
928
936
|
source = arg;
|
|
937
|
+
} else if (arg.startsWith("-")) {
|
|
938
|
+
throw new Error(`Unknown option: ${arg}`);
|
|
929
939
|
}
|
|
930
940
|
i++;
|
|
931
941
|
break;
|
|
@@ -959,19 +969,62 @@ async function add(args) {
|
|
|
959
969
|
error("No source specified. Provide a GitHub URL, owner/repo, or local path.");
|
|
960
970
|
process.exit(1);
|
|
961
971
|
}
|
|
962
|
-
const skillSource = isGitUrl(source) ? { type: "git", url: source } : { type: "local", path: source };
|
|
963
972
|
const cwd = process.cwd();
|
|
973
|
+
let sourceDir;
|
|
974
|
+
const isGit = isGitUrl(source);
|
|
975
|
+
if (isGit) {
|
|
976
|
+
step(1, 9, "Fetching skill source...");
|
|
977
|
+
sourceDir = await cloneRepo(source);
|
|
978
|
+
} else {
|
|
979
|
+
sourceDir = source;
|
|
980
|
+
if (!existsSync7(sourceDir)) {
|
|
981
|
+
throw new SkillNotFoundError(sourceDir);
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
const allSkillDirs = await findAllSkillDirectories(sourceDir);
|
|
985
|
+
if (allSkillDirs.length === 0) {
|
|
986
|
+
throw new SkillNotFoundError(`No SKILL.md found in ${sourceDir}`);
|
|
987
|
+
}
|
|
988
|
+
let targetDirs = allSkillDirs;
|
|
989
|
+
if (flags.skill.length > 0 && !flags.skill.includes("*")) {
|
|
990
|
+
const requested = new Set(flags.skill.map((s) => s.toLowerCase()));
|
|
991
|
+
const filtered = [];
|
|
992
|
+
for (const dir of allSkillDirs) {
|
|
993
|
+
const parsed = await readSkillMd(dir);
|
|
994
|
+
if (!parsed) continue;
|
|
995
|
+
const name = parsed.frontmatter.name.toLowerCase();
|
|
996
|
+
const dirName = basename2(dir).toLowerCase();
|
|
997
|
+
if (requested.has(name) || requested.has(dirName)) {
|
|
998
|
+
filtered.push(dir);
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
if (filtered.length === 0) {
|
|
1002
|
+
const available = [];
|
|
1003
|
+
for (const dir of allSkillDirs) {
|
|
1004
|
+
const parsed = await readSkillMd(dir);
|
|
1005
|
+
if (parsed) available.push(parsed.frontmatter.name);
|
|
1006
|
+
}
|
|
1007
|
+
error(
|
|
1008
|
+
`No matching skills found for: ${flags.skill.join(", ")}
|
|
1009
|
+
Available skills: ${available.join(", ")}`
|
|
1010
|
+
);
|
|
1011
|
+
process.exit(1);
|
|
1012
|
+
}
|
|
1013
|
+
targetDirs = filtered;
|
|
1014
|
+
}
|
|
964
1015
|
const agents = flags.agent.length > 0 ? flags.agent : [void 0];
|
|
965
1016
|
try {
|
|
966
|
-
for (const
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
1017
|
+
for (const dir of targetDirs) {
|
|
1018
|
+
for (const agent of agents) {
|
|
1019
|
+
await installSkill({
|
|
1020
|
+
source: { type: "local", path: dir },
|
|
1021
|
+
agent,
|
|
1022
|
+
cwd,
|
|
1023
|
+
copy: flags.copy,
|
|
1024
|
+
force: flags.force,
|
|
1025
|
+
yes: flags.yes
|
|
1026
|
+
});
|
|
1027
|
+
}
|
|
975
1028
|
}
|
|
976
1029
|
} catch (err) {
|
|
977
1030
|
error(err.message);
|
|
@@ -1034,7 +1087,7 @@ function parseRemoveFlags(args) {
|
|
|
1034
1087
|
flags.skill.push(val);
|
|
1035
1088
|
break;
|
|
1036
1089
|
default:
|
|
1037
|
-
|
|
1090
|
+
throw new Error(`Unknown option: --${key}`);
|
|
1038
1091
|
}
|
|
1039
1092
|
i++;
|
|
1040
1093
|
continue;
|
|
@@ -1077,6 +1130,8 @@ function parseRemoveFlags(args) {
|
|
|
1077
1130
|
default:
|
|
1078
1131
|
if (!arg.startsWith("-")) {
|
|
1079
1132
|
names.push(arg);
|
|
1133
|
+
} else {
|
|
1134
|
+
throw new Error(`Unknown option: ${arg}`);
|
|
1080
1135
|
}
|
|
1081
1136
|
i++;
|
|
1082
1137
|
break;
|
|
@@ -1303,7 +1358,7 @@ async function info2(args) {
|
|
|
1303
1358
|
}
|
|
1304
1359
|
|
|
1305
1360
|
// src/commands/doctor.ts
|
|
1306
|
-
import { existsSync as
|
|
1361
|
+
import { existsSync as existsSync8 } from "fs";
|
|
1307
1362
|
async function doctor() {
|
|
1308
1363
|
blank();
|
|
1309
1364
|
info("Running diagnostics...");
|
|
@@ -1312,7 +1367,7 @@ async function doctor() {
|
|
|
1312
1367
|
info("Checking directory structure...");
|
|
1313
1368
|
const dirs = [AGENTS_HOME, CONFIG_DIR, SKILLS_DIR];
|
|
1314
1369
|
for (const dir of dirs) {
|
|
1315
|
-
if (
|
|
1370
|
+
if (existsSync8(dir)) {
|
|
1316
1371
|
success(`\u2713 ${dir}`);
|
|
1317
1372
|
} else {
|
|
1318
1373
|
warn(`\u2717 ${dir} (missing)`);
|
|
@@ -1321,7 +1376,7 @@ async function doctor() {
|
|
|
1321
1376
|
}
|
|
1322
1377
|
blank();
|
|
1323
1378
|
info("Checking registry...");
|
|
1324
|
-
if (
|
|
1379
|
+
if (existsSync8(REGISTRY_PATH)) {
|
|
1325
1380
|
success(`\u2713 ${REGISTRY_PATH}`);
|
|
1326
1381
|
try {
|
|
1327
1382
|
const skills = await listRegistry();
|
|
@@ -1339,13 +1394,13 @@ async function doctor() {
|
|
|
1339
1394
|
const skills = await listRegistry();
|
|
1340
1395
|
for (const [name, entry] of Object.entries(skills)) {
|
|
1341
1396
|
info(`Skill: ${name}`);
|
|
1342
|
-
if (
|
|
1397
|
+
if (existsSync8(entry.canonical_path)) {
|
|
1343
1398
|
success(` \u2713 Canonical path exists`);
|
|
1344
1399
|
} else {
|
|
1345
1400
|
error(` \u2717 Canonical path missing: ${entry.canonical_path}`);
|
|
1346
1401
|
issues++;
|
|
1347
1402
|
}
|
|
1348
|
-
if (
|
|
1403
|
+
if (existsSync8(entry.agent_path)) {
|
|
1349
1404
|
const isLink = await isSymlink(entry.agent_path);
|
|
1350
1405
|
success(` \u2713 Agent path exists (${isLink ? "symlink" : "copy"})`);
|
|
1351
1406
|
} else {
|
|
@@ -1424,8 +1479,8 @@ async function find(args) {
|
|
|
1424
1479
|
}
|
|
1425
1480
|
|
|
1426
1481
|
// src/commands/init.ts
|
|
1427
|
-
import { existsSync as
|
|
1428
|
-
import { join as join7, basename as
|
|
1482
|
+
import { existsSync as existsSync9 } from "fs";
|
|
1483
|
+
import { join as join7, basename as basename3 } from "path";
|
|
1429
1484
|
var SKILL_MD_TEMPLATE = `---
|
|
1430
1485
|
name: {{NAME}}
|
|
1431
1486
|
version: 0.1.0
|
|
@@ -1455,10 +1510,10 @@ async function init(args) {
|
|
|
1455
1510
|
skillName = nameArg;
|
|
1456
1511
|
} else {
|
|
1457
1512
|
targetDir = cwd;
|
|
1458
|
-
skillName =
|
|
1513
|
+
skillName = basename3(cwd);
|
|
1459
1514
|
}
|
|
1460
1515
|
const skillMdPath = join7(targetDir, "SKILL.md");
|
|
1461
|
-
if (
|
|
1516
|
+
if (existsSync9(skillMdPath)) {
|
|
1462
1517
|
error(`SKILL.md already exists at ${skillMdPath}`);
|
|
1463
1518
|
process.exit(1);
|
|
1464
1519
|
}
|
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 // Direct SKILL.md in root\n if (existsSync(join(dir, 'SKILL.md'))) {\n return dir;\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 return join(skillsRoot, entry.name);\n }\n }\n }\n } catch {\n // continue to next search strategy\n }\n }\n\n // Step 3: 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 return join(dir, entry.name);\n }\n }\n }\n } catch {\n // ignore\n }\n\n return null;\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 { isGitUrl } from '../core/git-source.js';\nimport * as logger from '../utils/logger.js';\nimport type { SkillSource, AgentPlatform } from '../types/index.js';\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: break;\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 }\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 skillSource: SkillSource = isGitUrl(source)\n ? { type: 'git', url: source }\n : { type: 'local', path: source };\n\n const cwd = process.cwd();\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 agent of agents) {\n await installSkill({\n source: skillSource,\n agent: agent as AgentPlatform | undefined,\n cwd,\n copy: flags.copy,\n force: flags.force,\n yes: flags.yes,\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: break;\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 }\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","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 } 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"]}
|