skill-master 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +214 -0
- package/README.zh-CN.md +199 -0
- package/bin/skill-master.mjs +6 -0
- package/dist/cli.js +1368 -0
- package/dist/cli.js.map +1 -0
- package/package.json +48 -0
package/dist/cli.js.map
ADDED
|
@@ -0,0 +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/core/registry.ts","../src/platform/detector.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} 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 */\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 );\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 } 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): 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 return { frontmatter, body, rawFrontmatter };\n}\n\n/** Validate required frontmatter fields */\nexport function validateFrontmatter(fm: SkillFrontmatter): void {\n if (!fm.name || typeof fm.name !== 'string') {\n throw new SkillParseError('Missing or invalid \"name\" field');\n }\n if (!fm.version || typeof fm.version !== 'string') {\n throw new SkillParseError('Missing or invalid \"version\" field');\n }\n if (!Array.isArray(fm['allowed-tools']) || fm['allowed-tools'].length === 0) {\n throw new SkillParseError('Missing or empty \"allowed-tools\" field');\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 return null;\n }\n\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 return null;\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);\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';\nimport type { AgentPlatform } from '../types/index.js';\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/** Platform-specific skill directory mappings */\nconst AGENT_SKILL_DIRS: Record<AgentPlatform, string> = {\n 'claude-code': '.claude/skills',\n 'opencode': '.opencode/skills',\n 'cursor': '.cursor/skills',\n 'cline': '.cline/skills',\n 'windsurf': '.windsurf/skills',\n};\n\n/** Get the agent-specific skill installation path */\nexport function getAgentSkillPath(\n cwd: string,\n agent: AgentPlatform,\n name: string,\n): string {\n return join(cwd, AGENT_SKILL_DIRS[agent], name);\n}\n\n/** Get the agent skills root directory */\nexport function getAgentSkillsRoot(cwd: string, agent: AgentPlatform): string {\n return join(cwd, AGENT_SKILL_DIRS[agent]);\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 { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { homedir } from 'node:os';\nimport type { AgentPlatform } from '../types/index.js';\n\n/** Platform detection markers in order of priority */\nconst PLATFORM_MARKERS: Array<{ dir: string; platform: AgentPlatform }> = [\n { dir: '.claude', platform: 'claude-code' },\n { dir: '.cursor', platform: 'cursor' },\n { dir: '.windsurf', platform: 'windsurf' },\n { dir: '.cline', platform: 'cline' },\n];\n\n/**\n * Detect the agent platform based on directory markers in cwd.\n * Falls back to checking ~/.config/opencode, then defaults to claude-code.\n */\nexport function detectPlatform(cwd: string): AgentPlatform {\n for (const { dir, platform } of PLATFORM_MARKERS) {\n if (existsSync(join(cwd, dir))) {\n return platform;\n }\n }\n\n // Check for opencode\n if (existsSync(join(homedir(), '.config', 'opencode'))) {\n return 'opencode';\n }\n\n // Default\n return 'claude-code';\n}\n\n/** Agent-specific skills directory names */\nconst AGENT_SKILLS_DIRS: Record<AgentPlatform, string> = {\n 'claude-code': '.claude/skills',\n 'opencode': '.opencode/skills',\n 'cursor': '.cursor/skills',\n 'cline': '.cline/skills',\n 'windsurf': '.windsurf/skills',\n};\n\n/** Get the skills directory for a given platform */\nexport function getAgentSkillsDir(platform: AgentPlatform): string {\n return AGENT_SKILLS_DIRS[platform];\n}\n\n/** List all supported platforms */\nexport function getSupportedPlatforms(): AgentPlatform[] {\n return ['claude-code', 'opencode', 'cursor', 'cline', 'windsurf'];\n}\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 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","join","join","existsSync","existsSync","existsSync","join","homedir","existsSync","join","info","existsSync","existsSync","existsSync","join","join","existsSync","execFile","promisify","execFileAsync","promisify","execFile","info"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "skill-master",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Cross-platform skill package manager for AI coding agents",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/cli.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"skill-master": "./bin/skill-master.mjs"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"bin",
|
|
13
|
+
"README.md",
|
|
14
|
+
"LICENSE"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "tsup",
|
|
18
|
+
"dev": "tsup --watch",
|
|
19
|
+
"test": "vitest",
|
|
20
|
+
"test:run": "vitest run",
|
|
21
|
+
"lint": "tsc --noEmit",
|
|
22
|
+
"prepublishOnly": "npm run lint && npm run build"
|
|
23
|
+
},
|
|
24
|
+
"keywords": ["skill", "manager", "claude-code", "opencode", "cursor", "cline", "agent", "ai", "skills"],
|
|
25
|
+
"author": "BenedictKing",
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "https://github.com/BenedictKing/skill-master.git"
|
|
30
|
+
},
|
|
31
|
+
"bugs": {
|
|
32
|
+
"url": "https://github.com/BenedictKing/skill-master/issues"
|
|
33
|
+
},
|
|
34
|
+
"homepage": "https://github.com/BenedictKing/skill-master#readme",
|
|
35
|
+
"engines": {
|
|
36
|
+
"node": ">=18"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"yaml": "^2.7.0",
|
|
40
|
+
"chalk": "^5.4.1"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"typescript": "^5.7.0",
|
|
44
|
+
"@types/node": "^22.0.0",
|
|
45
|
+
"tsup": "^8.3.0",
|
|
46
|
+
"vitest": "^3.0.0"
|
|
47
|
+
}
|
|
48
|
+
}
|