skillverse 0.1.5 → 0.1.8

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/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/config.ts","../src/lib/db.ts","../../shared/src/index.ts","../src/middleware/errorHandler.ts","../src/services/skillService.ts","../src/index.ts","../src/routes/skills.ts","../src/services/workspaceService.ts","../src/routes/workspaces.ts","../src/routes/marketplace.ts","../src/services/bundleService.ts","../src/routes/dashboard.ts","../src/routes/config.ts","../src/middleware/logger.ts","../src/lib/initDb.ts"],"sourcesContent":["import { join, dirname } from 'path';\nimport { existsSync, mkdirSync, readFileSync } from 'fs';\nimport { fileURLToPath } from 'url';\nimport dotenv from 'dotenv';\n\n// Load .env file\ndotenv.config();\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nexport function setupEnvironment() {\n const home = process.env.HOME || process.env.USERPROFILE || '';\n // The \"Bootstrap\" home is always the default location\n const defaultHome = join(home, '.skillverse');\n const bootstrapConfigPath = join(defaultHome, 'config.json');\n\n let skillverseHome = process.env.SKILLVERSE_HOME || defaultHome;\n\n // Try to read config.json from the default location to see if there's an override\n if (existsSync(bootstrapConfigPath)) {\n try {\n const config = JSON.parse(readFileSync(bootstrapConfigPath, 'utf-8'));\n if (config.skillverseHome) {\n skillverseHome = config.skillverseHome;\n // CRITICAL: Update process.env so that other modules (and routes) see the new path\n process.env.SKILLVERSE_HOME = skillverseHome;\n console.log(`Common config found. Using custom home: ${skillverseHome}`);\n }\n } catch (e) {\n console.warn('Failed to read bootstrap config:', e);\n }\n }\n\n const dbUrl = process.env.DATABASE_URL;\n\n // Ensure config directory exists (for the active home)\n if (!existsSync(skillverseHome)) {\n try {\n mkdirSync(skillverseHome, { recursive: true });\n } catch (error) {\n console.error('Failed to create .skillverse directory:', error);\n }\n }\n\n // Set default database URL if not provided or if we have a custom home override\n if (!dbUrl || (skillverseHome !== defaultHome)) {\n const dbPath = join(skillverseHome, 'skillverse.db');\n process.env.DATABASE_URL = `file:${dbPath}`;\n // strict logic: index.ts calls this before initDb, so initDb will see the updated env\n console.log(`Using database at: ${dbPath}`);\n }\n\n // CRITICAL: Ensure other derived paths are also updated in process.env\n // This prevents modules from using stale paths from .env if they were pre-set\n process.env.SKILLS_DIR = join(skillverseHome, 'skills');\n process.env.MARKETPLACE_DIR = join(skillverseHome, 'marketplace');\n process.env.TEMP_DIR = join(skillverseHome, 'temp');\n\n return {\n skillverseHome,\n databaseUrl: process.env.DATABASE_URL,\n };\n}\n\n// Run setup immediately\nexport const config = setupEnvironment();\n","import { PrismaClient } from '@prisma/client';\n\n// Force fresh config read on every module load\n// This is critical because tsx HMR can cache imports\nimport { setupEnvironment } from '../config.js';\nconst config = setupEnvironment();\n\nconst globalForPrisma = globalThis as unknown as {\n prisma: PrismaClient | undefined;\n lastDbUrl: string | undefined;\n};\n\n// Get the current DATABASE_URL after config setup\nconst currentDbUrl = process.env.DATABASE_URL;\nconsole.log(`📊 DB connection target: ${currentDbUrl}`);\n\n// If DB URL changed, we need a new client\nif (globalForPrisma.prisma && globalForPrisma.lastDbUrl !== currentDbUrl) {\n console.log(`🔄 DATABASE_URL changed from ${globalForPrisma.lastDbUrl} to ${currentDbUrl}, reconnecting...`);\n // Disconnect old client (async, but we don't wait)\n globalForPrisma.prisma.$disconnect().catch(console.error);\n globalForPrisma.prisma = undefined;\n}\n\nexport const prisma =\n globalForPrisma.prisma ??\n new PrismaClient({\n log: process.env.NODE_ENV === 'development' ? ['error', 'warn'] : ['error'],\n });\n\n// Store the current DB URL and client in global\nglobalForPrisma.prisma = prisma;\nglobalForPrisma.lastDbUrl = currentDbUrl;\n","// Skill types\nexport interface Skill {\n id: string;\n name: string;\n source: 'git' | 'local';\n sourceUrl?: string;\n description?: string;\n commitHash?: string;\n repoUrl?: string;\n updateAvailable: boolean;\n lastUpdateCheck?: Date;\n installDate: Date;\n metadata?: Record<string, any>;\n linkedWorkspaces?: SkillWorkspace[];\n}\n\nexport interface CreateSkillFromGitDto {\n gitUrl: string;\n description?: string;\n}\n\nexport interface CreateSkillFromLocalDto {\n name: string;\n description?: string;\n}\n\nexport interface UpdateSkillDto {\n name?: string;\n description?: string;\n metadata?: Record<string, any>;\n}\n\n// Workspace types\nexport interface Workspace {\n id: string;\n name: string;\n path: string;\n type: WorkspaceType;\n scope: WorkspaceScope;\n createdAt: Date;\n isPathValid?: boolean; // runtime computed, not stored in DB\n}\n\nexport type WorkspaceType = 'vscode' | 'cursor' | 'claude-desktop' | 'codex' | 'antigravity' | 'custom';\nexport type WorkspaceScope = 'project' | 'global';\n\n// 各编辑器类型对应的 skills 子目录\nexport const WORKSPACE_SKILLS_PATHS: Record<WorkspaceType, { project: string; global: string }> = {\n vscode: {\n project: '.github/skills',\n global: '~/.copilot/skills'\n },\n cursor: {\n project: '.cursor/skills',\n global: '~/.cursor/skills'\n },\n 'claude-desktop': {\n project: '.claude/skills',\n global: '~/.claude/skills'\n },\n codex: {\n project: '.codex/skills',\n global: '~/.codex/skills'\n },\n antigravity: {\n project: '.agent/skills',\n global: '~/.agent/skills'\n },\n custom: {\n project: 'skills',\n global: ''\n },\n};\n\nexport interface CreateWorkspaceDto {\n name: string;\n projectPath: string; // 项目根目录(project scope)或空(global scope)\n type: WorkspaceType;\n scope: WorkspaceScope;\n}\n\nexport interface UpdateWorkspaceDto {\n name?: string;\n path?: string;\n type?: WorkspaceType;\n scope?: WorkspaceScope;\n}\n\n// Skill-Workspace link types\nexport interface SkillWorkspace {\n id: string;\n skillId: string;\n workspaceId: string;\n linkedAt: Date;\n skill?: Skill;\n workspace?: Workspace;\n}\n\nexport interface LinkSkillToWorkspaceDto {\n skillId: string;\n workspaceId: string;\n}\n\n// Marketplace types\nexport interface MarketplaceSkill {\n id: string;\n skillId: string;\n publisherId?: string;\n publisherName?: string;\n publishDate: Date;\n downloads: number;\n skill: Skill;\n}\n\nexport interface PublishSkillDto {\n skillId: string;\n publisherName?: string;\n}\n\n// API Response types\nexport interface ApiResponse<T = any> {\n success: boolean;\n data?: T;\n error?: string;\n code?: string;\n}\n\nexport interface UpdateCheckResponse {\n hasUpdate: boolean;\n currentHash: string | null;\n remoteHash: string | null;\n message?: string;\n}\n\nexport interface PaginatedResponse<T> {\n items: T[];\n total: number;\n page: number;\n pageSize: number;\n}\n\n// Error types\nexport const ErrorCode = {\n VALIDATION_ERROR: 'VALIDATION_ERROR',\n NOT_FOUND: 'NOT_FOUND',\n ALREADY_EXISTS: 'ALREADY_EXISTS',\n INTERNAL_ERROR: 'INTERNAL_ERROR',\n GIT_ERROR: 'GIT_ERROR',\n FILE_SYSTEM_ERROR: 'FILE_SYSTEM_ERROR',\n PERMISSION_ERROR: 'PERMISSION_ERROR',\n SYMLINK_ERROR: 'SYMLINK_ERROR',\n} as const;\n\nexport type ErrorCode = typeof ErrorCode[keyof typeof ErrorCode];\n\nexport interface ApiError {\n code: ErrorCode;\n message: string;\n details?: any;\n}\n\n// Statistics types\nexport interface DashboardStats {\n totalSkills: number;\n totalWorkspaces: number;\n totalLinks: number;\n marketplaceSkills: number;\n recentSkills: Skill[];\n}\n","import { Request, Response, NextFunction } from 'express';\nimport { ErrorCode } from '@skillverse/shared';\n\nexport class AppError extends Error {\n constructor(\n public code: ErrorCode,\n message: string,\n public statusCode: number = 500,\n public details?: any\n ) {\n super(message);\n this.name = 'AppError';\n }\n}\n\nexport function errorHandler(\n err: Error | AppError,\n req: Request,\n res: Response,\n next: NextFunction\n) {\n console.error('Error:', err);\n\n if (err instanceof AppError) {\n return res.status(err.statusCode).json({\n success: false,\n error: err.message,\n code: err.code,\n details: err.details,\n });\n }\n\n // Handle other errors\n return res.status(500).json({\n success: false,\n error: 'Internal server error',\n code: ErrorCode.INTERNAL_ERROR,\n message: process.env.NODE_ENV === 'development' ? err.message : undefined,\n });\n}\n","import { join, basename } from 'path';\nimport { existsSync } from 'fs';\nimport { mkdir, rm, cp, readFile, unlink } from 'fs/promises';\nimport matter from 'gray-matter';\nimport simpleGit from 'simple-git';\nimport AdmZip from 'adm-zip';\nimport { prisma } from '../lib/db.js';\nimport { AppError } from '../middleware/errorHandler.js';\nimport { ErrorCode } from '@skillverse/shared';\n\n// Helper to get current paths dynamically from environment\n// These are set by setupEnvironment() in config.ts\nconst getPaths = () => {\n const home = process.env.SKILLVERSE_HOME || join(process.env.HOME || '', '.skillverse');\n return {\n home,\n skills: process.env.SKILLS_DIR || join(home, 'skills'),\n temp: process.env.TEMP_DIR || join(home, 'temp')\n };\n};\n\n// Helper to parse Git URL and subdirectory\nfunction parseGitUrl(url: string): { repoUrl: string; subdir?: string; skillName: string } {\n // Handle simple URL: https://github.com/owner/repo\n if (!url.includes('/tree/')) {\n const urlParts = url.split('/');\n const repoName = urlParts[urlParts.length - 1].replace('.git', '');\n return { repoUrl: url, skillName: repoName };\n }\n\n // Handle URL with tree/subdir: https://github.com/owner/repo/tree/main/path/to/skill\n // Note: This logic is specific to GitHub URLs structure\n const parts = url.split('/tree/');\n const repoUrl = parts[0] + (parts[0].endsWith('.git') ? '' : '.git');\n\n // parts[1] is like \"main/path/to/skill\"\n // We need to support branch names that might contain slashes, but for MVP standard GitHub URLs\n // usually have the branch as the first segment after /tree/\n const pathParts = parts[1].split('/');\n const branch = pathParts[0]; // Assume first part is branch for now\n const subdir = pathParts.slice(1).join('/');\n const skillName = pathParts[pathParts.length - 1];\n\n return { repoUrl, subdir, skillName };\n}\n\nexport class SkillService {\n async getAllSkills() {\n const skills = await prisma.skill.findMany({\n include: {\n linkedWorkspaces: {\n include: {\n workspace: true,\n },\n },\n marketplaceEntry: true,\n },\n orderBy: {\n installDate: 'desc',\n },\n });\n\n return skills;\n }\n\n async getSkillById(id: string) {\n const skill = await prisma.skill.findUnique({\n where: { id },\n include: {\n linkedWorkspaces: {\n include: {\n workspace: true,\n },\n },\n marketplaceEntry: true,\n },\n });\n\n if (!skill) {\n throw new AppError(ErrorCode.NOT_FOUND, 'Skill not found', 404);\n }\n\n return skill;\n }\n\n async getSkillByName(name: string) {\n const skill = await prisma.skill.findUnique({\n where: { name },\n include: {\n linkedWorkspaces: {\n include: {\n workspace: true,\n },\n },\n marketplaceEntry: true,\n },\n });\n\n if (!skill) {\n throw new AppError(ErrorCode.NOT_FOUND, `Skill \"${name}\" not found`, 404);\n }\n\n return skill;\n }\n\n private async parseSkillMetadata(skillPath: string): Promise<{ description: string; metadata: any }> {\n try {\n const skillMdPath = join(skillPath, 'SKILL.md');\n\n let description = '';\n let metadata: any = {};\n\n if (existsSync(skillMdPath)) {\n const fileContent = await readFile(skillMdPath, 'utf-8');\n const parsed = matter(fileContent);\n\n // Use description from frontmatter or from first paragraph of body?\n // Prioritize frontmatter\n description = parsed.data.description || '';\n metadata = parsed.data;\n }\n\n // Fallback to package.json or skill.json if no description\n if (!description) {\n const packageJsonPath = join(skillPath, 'package.json');\n const skillJsonPath = join(skillPath, 'skill.json');\n\n if (existsSync(skillJsonPath)) {\n const content = await readFile(skillJsonPath, 'utf-8');\n const json = JSON.parse(content);\n description = json.description || '';\n metadata = { ...metadata, ...json };\n } else if (existsSync(packageJsonPath)) {\n const content = await readFile(packageJsonPath, 'utf-8');\n const pkg = JSON.parse(content);\n description = pkg.description || '';\n metadata = { ...metadata, name: pkg.name, version: pkg.version };\n }\n }\n\n return { description, metadata };\n } catch (error) {\n console.warn('Failed to parse skill metadata:', error);\n return { description: '', metadata: {} };\n }\n }\n\n async createSkillFromGit(gitUrl: string, description?: string) {\n let tempPath: string | null = null;\n\n try {\n // Parse URL\n const { repoUrl, subdir, skillName } = parseGitUrl(gitUrl);\n\n // Check if skill already exists\n const existingSkill = await prisma.skill.findUnique({\n where: { name: skillName },\n });\n\n if (existingSkill) {\n throw new AppError(ErrorCode.ALREADY_EXISTS, `Skill \"${skillName}\" already exists`, 409);\n }\n\n const { skills: skillsDir, temp: tempDir } = getPaths();\n\n // Prepare directories\n const skillPath = join(skillsDir, skillName);\n if (existsSync(skillPath)) {\n throw new AppError(ErrorCode.ALREADY_EXISTS, `Skill directory \"${skillName}\" already exists`, 409);\n }\n\n let commitHash = '';\n\n if (subdir) {\n // Clone to temp directory first for subdirectory extraction\n tempPath = join(tempDir, `git-clone-${Date.now()}`);\n await mkdir(tempPath, { recursive: true });\n\n console.log(`Cloning ${repoUrl} to temp path for extraction...`);\n const git = simpleGit();\n await git.clone(repoUrl, tempPath);\n\n // Get commit hash\n try {\n commitHash = await simpleGit(tempPath).revparse(['HEAD']);\n console.log(`Captured commit hash: ${commitHash}`);\n } catch (e) {\n console.warn('Failed to capture commit hash:', e);\n }\n\n const sourcePath = join(tempPath, subdir);\n if (!existsSync(sourcePath)) {\n throw new AppError(\n ErrorCode.GIT_ERROR,\n `Subdirectory \"${subdir}\" not found in repository`,\n 400\n );\n }\n\n // Validate skill structure (must have SKILL.md, skill.json, or package.json)\n const hasSkillMd = existsSync(join(sourcePath, 'SKILL.md'));\n const hasSkillJson = existsSync(join(sourcePath, 'skill.json'));\n const hasPackageJson = existsSync(join(sourcePath, 'package.json'));\n\n if (!hasSkillMd && !hasSkillJson && !hasPackageJson) {\n throw new AppError(\n ErrorCode.VALIDATION_ERROR,\n `Invalid skill structure: \"${subdir}\" does not contain SKILL.md, skill.json, or package.json`,\n 400\n );\n }\n\n // Move subdir content to final skill path\n await mkdir(skillPath, { recursive: true });\n await cp(sourcePath, skillPath, { recursive: true });\n\n } else {\n // Direct clone to skill path\n if (!existsSync(skillPath)) {\n await mkdir(skillPath, { recursive: true });\n }\n\n const git = simpleGit();\n console.log(`Cloning ${gitUrl} to ${skillPath}...`);\n await git.clone(gitUrl, skillPath);\n\n // Get commit hash\n try {\n commitHash = await git.cwd(skillPath).revparse(['HEAD']);\n console.log(`Captured commit hash: ${commitHash}`);\n } catch (e) {\n console.warn('Failed to capture commit hash:', e);\n }\n }\n\n // Read metadata\n const parsed = await this.parseSkillMetadata(skillPath);\n\n // Save to database\n const skill = await prisma.skill.create({\n data: {\n name: skillName,\n source: 'git',\n sourceUrl: gitUrl,\n repoUrl,\n commitHash,\n description: description || parsed.description || '',\n storagePath: skillPath,\n metadata: JSON.stringify(parsed.metadata),\n },\n });\n\n return skill;\n } catch (error: any) {\n // Cleanup on error (only if we created files but failed DB)\n // Actually we check DB first so if we fail here it's likely during git/fs ops\n // The implementation already has cleanup for tempPath in finally\n throw error;\n } finally {\n if (tempPath && existsSync(tempPath)) {\n await rm(tempPath, { recursive: true, force: true }).catch(console.error);\n }\n }\n }\n\n\n\n async createSkillFromDirectory(path: string, name?: string, description?: string) {\n if (!existsSync(path)) {\n throw new AppError(ErrorCode.FILE_SYSTEM_ERROR, `Source path not found: ${path}`, 400);\n }\n\n const { skills: skillsDir } = getPaths();\n const skillName = name || basename(path);\n const skillPath = join(skillsDir, skillName);\n\n // Check if skill already exists\n const existingSkill = await prisma.skill.findUnique({\n where: { name: skillName },\n });\n\n if (existingSkill) {\n throw new AppError(ErrorCode.ALREADY_EXISTS, `Skill \"${skillName}\" already exists`, 409);\n }\n\n if (existsSync(skillPath)) {\n throw new AppError(ErrorCode.ALREADY_EXISTS, `Skill directory \"${skillName}\" already exists`, 409);\n }\n\n try {\n // Create skill directory\n await mkdir(skillPath, { recursive: true });\n\n // Copy files\n await cp(path, skillPath, { recursive: true });\n\n // Read metadata\n const parsed = await this.parseSkillMetadata(skillPath);\n\n const skill = await prisma.skill.create({\n data: {\n name: skillName,\n source: 'local',\n description: description || parsed.description || '',\n storagePath: skillPath,\n metadata: JSON.stringify(parsed.metadata),\n },\n });\n\n return skill;\n } catch (error) {\n // Clean up\n if (existsSync(skillPath)) {\n await rm(skillPath, { recursive: true, force: true }).catch(() => { });\n }\n throw error;\n }\n }\n\n /**\n * Helper to handle cases where the archive contains a single top-level directory.\n * Moves contents up one level if that's the case.\n */\n private async stripTopLevelDirectory(targetPath: string) {\n const { readdir, rename, rmdir, stat } = await import('fs/promises');\n\n const items = await readdir(targetPath);\n\n // Ignore system files like .DS_Store\n const validItems = items.filter(i => i !== '.DS_Store' && i !== '__MACOSX');\n\n if (validItems.length === 1) {\n const topLevelItem = validItems[0];\n const topLevelPath = join(targetPath, topLevelItem);\n const stats = await stat(topLevelPath);\n\n if (stats.isDirectory()) {\n console.log(`Striping top-level directory: ${topLevelItem}`);\n\n // Move all items from subdirectory to targetPath\n const subItems = await readdir(topLevelPath);\n for (const item of subItems) {\n await rename(join(topLevelPath, item), join(targetPath, item));\n }\n\n // Remove the empty subdirectory\n await rmdir(topLevelPath);\n }\n }\n }\n\n async createSkillFromLocal(name: string, zipPath: string, description?: string) {\n const { skills: skillsDir, temp: tempDir } = getPaths();\n const skillPath = join(skillsDir, name);\n\n // Check if skill already exists\n const existingSkill = await prisma.skill.findUnique({\n where: { name },\n });\n\n if (existingSkill) {\n throw new AppError(ErrorCode.ALREADY_EXISTS, `Skill \"${name}\" already exists`, 409);\n }\n\n if (existsSync(skillPath)) {\n throw new AppError(ErrorCode.ALREADY_EXISTS, `Skill directory \"${name}\" already exists`, 409);\n }\n\n // Use a temp path for extraction to verify structure before determining final path\n const extractPath = join(tempDir, `extract-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`);\n await mkdir(extractPath, { recursive: true });\n\n try {\n const zip = new AdmZip(zipPath);\n zip.extractAllTo(extractPath, true);\n\n // Fix nested directory structure if present\n await this.stripTopLevelDirectory(extractPath);\n\n // Read metadata from the extracted files\n const parsed = await this.parseSkillMetadata(extractPath);\n\n // Now move to final destination\n // Check again to be safe against race conditions\n if (existsSync(skillPath)) {\n throw new AppError(ErrorCode.ALREADY_EXISTS, `Skill directory \"${name}\" already exists`, 409);\n }\n\n await import('fs/promises').then(fs => fs.rename(extractPath, skillPath));\n\n const skill = await prisma.skill.create({\n data: {\n name,\n source: 'local',\n description: description || parsed.description || '',\n storagePath: skillPath,\n metadata: JSON.stringify(parsed.metadata),\n },\n });\n\n return skill;\n } catch (error) {\n // Clean up final path if it was created but DB failed\n if (existsSync(skillPath)) {\n await rm(skillPath, { recursive: true, force: true }).catch(() => { });\n }\n // Clean up temp path if it still exists\n if (existsSync(extractPath)) {\n await rm(extractPath, { recursive: true, force: true }).catch(() => { });\n }\n throw error;\n }\n }\n\n /**\n * Create a skill from a tar.gz bundle (marketplace install)\n * @param bundlePath - Path to the .tar.gz bundle\n * @param originalName - Original skill name\n * @param description - Optional skill description\n */\n async createSkillFromBundle(bundlePath: string, originalName: string, description?: string) {\n // Generate a unique name to avoid conflicts\n let name = originalName;\n let counter = 1;\n while (await prisma.skill.findUnique({ where: { name } })) {\n name = `${originalName}-${counter}`;\n counter++;\n }\n\n const { skills: skillsDir, temp: tempDir } = getPaths();\n const skillPath = join(skillsDir, name);\n\n // Use a temp path for extraction\n const extractPath = join(tempDir, `extract-bundle-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`);\n await mkdir(extractPath, { recursive: true });\n\n try {\n // Extract bundle using tar\n const { createReadStream } = await import('fs');\n const { createGunzip } = await import('zlib');\n const tar = await import('tar');\n const { pipeline } = await import('stream/promises');\n\n await pipeline(\n createReadStream(bundlePath),\n createGunzip(),\n tar.extract({ cwd: extractPath })\n );\n\n // Fix nested directory structure if present\n await this.stripTopLevelDirectory(extractPath);\n\n // Read metadata from extracted files\n const parsed = await this.parseSkillMetadata(extractPath);\n\n // Check again for existence before moving\n if (existsSync(skillPath)) {\n throw new AppError(ErrorCode.ALREADY_EXISTS, `Skill directory \"${name}\" already exists`, 409);\n }\n\n await import('fs/promises').then(fs => fs.rename(extractPath, skillPath));\n\n const skill = await prisma.skill.create({\n data: {\n name,\n source: 'local',\n description: description || parsed.description || '',\n storagePath: skillPath,\n metadata: JSON.stringify(parsed.metadata),\n },\n });\n\n console.log(`📦 Installed skill \"${name}\" from bundle`);\n return skill;\n } catch (error) {\n // Clean up final path if it was created but DB failed\n if (existsSync(skillPath)) {\n await rm(skillPath, { recursive: true, force: true }).catch(() => { });\n }\n // Clean up temp path if it still exists\n if (existsSync(extractPath)) {\n await rm(extractPath, { recursive: true, force: true }).catch(() => { });\n }\n throw error;\n }\n }\n\n async updateSkill(id: string, data: { name?: string; description?: string; metadata?: any }) {\n const skill = await this.getSkillById(id);\n\n const updatedSkill = await prisma.skill.update({\n where: { id },\n data: {\n ...(data.name && { name: data.name }),\n ...(data.description !== undefined && { description: data.description }),\n ...(data.metadata && { metadata: JSON.stringify(data.metadata) }),\n },\n });\n\n return updatedSkill;\n }\n\n async deleteSkill(id: string, removeFiles: boolean = true) {\n const skill = await this.getSkillById(id);\n\n // Remove symlinks from linked workspaces\n if (skill.linkedWorkspaces && skill.linkedWorkspaces.length > 0) {\n for (const link of skill.linkedWorkspaces) {\n try {\n const workspacePath = link.workspace.path;\n const symlinkPath = join(workspacePath, skill.name);\n\n if (existsSync(symlinkPath)) {\n // Check if it is indeed a symlink to be safe\n const stats = await import('fs/promises').then(fs => fs.lstat(symlinkPath));\n if (stats.isSymbolicLink()) {\n await unlink(symlinkPath);\n console.log(`Removed symlink for ${skill.name} in workspace ${workspacePath}`);\n }\n }\n } catch (error) {\n console.warn(`Failed to remove symlink for ${skill.name} in workspace ${link.workspace.path}:`, error);\n }\n }\n }\n\n await prisma.skill.delete({\n where: { id },\n });\n\n if (removeFiles && skill.storagePath) {\n await rm(skill.storagePath, { recursive: true, force: true }).catch(err => {\n console.warn(`Failed to delete skill directory ${skill.storagePath}:`, err);\n });\n }\n\n return { success: true, message: 'Skill deleted successfully' };\n }\n\n // Check for updates\n async checkForUpdate(id: string) {\n const skill = await this.getSkillById(id);\n\n if (skill.source !== 'git' || !skill.repoUrl) {\n return {\n hasUpdate: false,\n currentHash: skill.commitHash,\n remoteHash: null,\n message: 'Not a git skill or missing repo URL',\n };\n }\n\n const { temp: tempDir } = getPaths();\n const tempPath = join(tempDir, `check-update-${Date.now()}`);\n await mkdir(tempPath, { recursive: true });\n\n try {\n const git = simpleGit();\n // We only need to check the remote HEAD, no need to full clone\n // But ls-remote might require authentication or be tricky with some hosts\n // Safer to shallow clone to temp\n console.log(`Checking updates for ${skill.name} from ${skill.repoUrl}...`);\n\n // Parse original git URL to get branch if possible, or just HEAD\n // For now, assume main/HEAD of the repoUrl\n const remote = await git.listRemote([skill.repoUrl, 'HEAD']);\n if (!remote) {\n throw new Error('Failed to get remote HEAD');\n }\n\n // remote is like \"hash\\tHEAD\"\n const remoteHash = remote.split('\\t')[0];\n const hasUpdate = remoteHash !== skill.commitHash;\n\n // Update DB with check result\n await prisma.skill.update({\n where: { id },\n data: {\n lastUpdateCheck: new Date(),\n updateAvailable: hasUpdate,\n },\n });\n\n return {\n hasUpdate,\n currentHash: skill.commitHash,\n remoteHash,\n };\n } catch (error: any) {\n console.error('Update check error:', error);\n throw new AppError(ErrorCode.GIT_ERROR, `Failed to check for updates: ${error.message}`, 500);\n } finally {\n await rm(tempPath, { recursive: true, force: true }).catch(() => { });\n }\n }\n\n async checkUpdates(ids?: string[]) {\n // Check all git skills\n const whereClause: any = {\n source: 'git',\n repoUrl: { not: null },\n };\n\n if (ids && ids.length > 0) {\n whereClause.id = { in: ids };\n }\n\n const skills = await prisma.skill.findMany({ where: whereClause });\n const results: Record<string, any> = {};\n\n // Limit concurrency to avoid hammering network/git\n // For now simple serial or Promise.all\n console.log(`Checking updates for ${skills.length} skills...`);\n\n await Promise.all(skills.map(async (skill: any) => {\n try {\n const result = await this.checkForUpdate(skill.id);\n results[skill.id] = result;\n } catch (e) {\n results[skill.id] = { error: (e as Error).message };\n }\n }));\n\n return results;\n }\n\n async refreshMetadata(id: string) {\n const skill = await this.getSkillById(id);\n const parsed = await this.parseSkillMetadata(skill.storagePath);\n\n const updated = await prisma.skill.update({\n where: { id },\n data: {\n description: parsed.description,\n metadata: JSON.stringify(parsed.metadata),\n }\n });\n\n return updated;\n }\n\n async upgradeSkill(id: string) {\n const skill = await this.getSkillById(id);\n\n if (skill.source !== 'git' || !skill.sourceUrl) {\n throw new AppError(ErrorCode.VALIDATION_ERROR, 'Cannot upgrade non-git skill', 400);\n }\n\n // Reuse createSkillFromGit logic but force update\n // Since createSkillFromGit checks for existing skill, we need to adapt it\n // Or just manually do the steps here:\n // 1. Download new version to temp\n // 2. Validate\n // 3. Replace files\n // 4. Update DB\n\n let tempPath: string | null = null;\n let tempSkillPath: string | null = null;\n\n try {\n const { repoUrl, subdir } = parseGitUrl(skill.sourceUrl);\n\n const { temp: tempDir } = getPaths();\n tempPath = join(tempDir, `upgrade-${Date.now()}`);\n await mkdir(tempPath, { recursive: true });\n\n const git = simpleGit();\n console.log(`Cloning ${repoUrl} to temp for upgrade...`);\n await git.clone(repoUrl, tempPath);\n\n let commitHash = '';\n try {\n commitHash = await simpleGit(tempPath).revparse(['HEAD']);\n } catch (e) {\n console.warn('Failed to capture commit hash during upgrade:', e);\n }\n\n let sourcePath = tempPath;\n if (subdir) {\n sourcePath = join(tempPath, subdir);\n if (!existsSync(sourcePath)) {\n throw new AppError(ErrorCode.GIT_ERROR, `Subdirectory \"${subdir}\" not found`, 400);\n }\n }\n\n // Validate structure\n const hasSkillMd = existsSync(join(sourcePath, 'SKILL.md'));\n const hasSkillJson = existsSync(join(sourcePath, 'skill.json'));\n const hasPackageJson = existsSync(join(sourcePath, 'package.json'));\n\n if (!hasSkillMd && !hasSkillJson && !hasPackageJson) {\n throw new AppError(ErrorCode.VALIDATION_ERROR, 'Invalid skill structure in new version', 400);\n }\n\n // Validated. Now replace files.\n // We should be careful not to delete user configs if any, but for now we do full replace\n // except maybe keeping some local files? For MVP, full replace.\n\n // Clear existing directory content\n const files = await import('fs/promises').then(fs => fs.readdir(skill.storagePath));\n for (const file of files) {\n await rm(join(skill.storagePath, file), { recursive: true, force: true });\n }\n\n // Copy new files\n await cp(sourcePath, skill.storagePath, { recursive: true });\n\n // Parse new metadata after upgrade\n const parsed = await this.parseSkillMetadata(skill.storagePath);\n\n // Update DB\n const updatedSkill = await prisma.skill.update({\n where: { id },\n data: {\n commitHash,\n updateAvailable: false,\n lastUpdateCheck: new Date(),\n installDate: new Date(), // Considering upgrade as reinstall? Or user prefer generic updatedAt\n // Keeping installDate as \"last installed/upgraded\"\n description: parsed.description,\n metadata: JSON.stringify(parsed.metadata),\n },\n });\n\n return updatedSkill;\n\n } catch (error: any) {\n console.error('Upgrade error:', error);\n throw new AppError(ErrorCode.GIT_ERROR, `Failed to upgrade skill: ${error.message}`, 500);\n } finally {\n if (tempPath) await rm(tempPath, { recursive: true, force: true }).catch(() => { });\n }\n }\n async scanForSkills() {\n const { skills: skillsDir } = getPaths();\n console.log(`Scanning for skills in ${skillsDir}...`);\n\n if (!existsSync(skillsDir)) {\n console.log('Skills directory does not exist, skipping scan.');\n return;\n }\n\n const entries = await import('fs/promises').then(fs => fs.readdir(skillsDir, { withFileTypes: true }));\n const directories = entries.filter(entry => entry.isDirectory()).map(entry => entry.name);\n\n console.log(`Found ${directories.length} directories in skills folder.`);\n\n let importedCount = 0;\n\n for (const dirName of directories) {\n const skillPath = join(skillsDir, dirName);\n\n // Check if already in DB\n const existingSkill = await prisma.skill.findUnique({\n where: { name: dirName },\n });\n\n if (existingSkill) {\n // Optional: Update storage path if it changed? \n // For now, assume if name matches, it's the same skill.\n continue;\n }\n\n // Check if valid skill\n const hasSkillMd = existsSync(join(skillPath, 'SKILL.md'));\n const hasPackageJson = existsSync(join(skillPath, 'package.json'));\n const hasSkillJson = existsSync(join(skillPath, 'skill.json'));\n\n if (!hasSkillMd && !hasPackageJson && !hasSkillJson) {\n console.log(`Skipping ${dirName}: No skill metadata found.`);\n continue;\n }\n\n try {\n console.log(`Importing skill: ${dirName}`);\n const parsed = await this.parseSkillMetadata(skillPath);\n\n // Determine source type - heuristic\n let source = 'local';\n let sourceUrl = undefined;\n let repoUrl = undefined;\n let commitHash = undefined;\n\n // Try to detect git info if .git exists\n if (existsSync(join(skillPath, '.git'))) {\n source = 'git';\n try {\n const git = simpleGit(skillPath);\n const remotes = await git.getRemotes(true);\n if (remotes.length > 0) {\n sourceUrl = remotes[0].refs.fetch;\n repoUrl = sourceUrl;\n }\n commitHash = await git.revparse(['HEAD']);\n } catch (e) {\n console.warn(`Failed to read git info for ${dirName}:`, e);\n }\n }\n\n await prisma.skill.create({\n data: {\n name: dirName,\n source,\n sourceUrl,\n repoUrl,\n commitHash,\n description: parsed.description,\n storagePath: skillPath,\n metadata: JSON.stringify(parsed.metadata),\n },\n });\n importedCount++;\n } catch (error) {\n console.error(`Failed to import skill ${dirName}:`, error);\n }\n }\n\n console.log(`Scan complete. Imported ${importedCount} new skills.`);\n return importedCount;\n }\n}\n\nexport const skillService = new SkillService();\n","import express from 'express';\nimport cors from 'cors';\nimport dotenv from 'dotenv';\nimport { fileURLToPath } from 'url';\nimport { dirname, join } from 'path';\nimport { mkdir } from 'fs/promises';\nimport { existsSync } from 'fs';\n\n// Load environment variables\ndotenv.config();\n\n// Import routes\nimport skillRoutes from './routes/skills.js';\nimport workspaceRoutes from './routes/workspaces.js';\nimport marketplaceRoutes from './routes/marketplace.js';\nimport dashboardRoutes from './routes/dashboard.js';\nimport configRoutes from './routes/config.js';\n\n// Import middleware\nimport { errorHandler } from './middleware/errorHandler.js';\nimport { requestLogger } from './middleware/logger.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nconst app = express();\nconst PORT = process.env.PORT || 3001;\n\n// Middleware\napp.use(cors());\napp.use(express.json());\napp.use(express.urlencoded({ extended: true }));\napp.use(requestLogger);\n\n// Serve static files from 'public' directory (shared with client build)\n// In tsx mode: __dirname is server/src, so ../../public doesn't exist\n// In compiled mode: __dirname is server/dist, so ../public works\n// We try multiple paths to support both modes\nconst possiblePublicDirs = [\n join(__dirname, '../public'), // Production: dist/index.js -> public\n join(__dirname, '../../public'), // Dev tsx might resolve here \n join(process.cwd(), 'public'), // Fallback: relative to cwd\n join(process.cwd(), 'server/public'), // Fallback: from root\n];\n\nconst publicDir = possiblePublicDirs.find(dir => existsSync(dir));\nif (publicDir) {\n app.use(express.static(publicDir));\n console.log(`📂 Serving static files from: ${publicDir}`);\n} else {\n console.warn('⚠️ No public directory found. Run \"npm run build\" in client first.');\n}\n\n// Routes\napp.use('/api/skills', skillRoutes);\napp.use('/api/workspaces', workspaceRoutes);\napp.use('/api/marketplace', marketplaceRoutes);\napp.use('/api/dashboard', dashboardRoutes);\napp.use('/api/config', configRoutes);\n\n// Health check\napp.get('/health', (req, res) => {\n res.json({ status: 'ok', timestamp: new Date().toISOString() });\n});\n\n// Serve index.html for all other routes (SPA support)\n// Only if public dir exists, otherwise we might be in dev mode without build\nif (publicDir && existsSync(publicDir)) {\n app.get('*', (req, res) => {\n res.sendFile(join(publicDir, 'index.html'));\n });\n}\n\n// Error handling\napp.use(errorHandler);\n\n// Initialize storage directories\nasync function initializeStorage() {\n const skillverseHome = process.env.SKILLVERSE_HOME || join(process.env.HOME || '', '.skillverse');\n const skillsDir = process.env.SKILLS_DIR || join(skillverseHome, 'skills');\n const marketplaceDir = process.env.MARKETPLACE_DIR || join(skillverseHome, 'marketplace');\n\n const dirs = [skillverseHome, skillsDir, marketplaceDir];\n\n for (const dir of dirs) {\n if (!existsSync(dir)) {\n await mkdir(dir, { recursive: true });\n console.log(`Created directory: ${dir}`);\n }\n }\n}\n\nimport { ensureDatabaseInitialized } from './lib/initDb.js';\n\n// Start server\nexport async function startServer(port: number = 3001) {\n try {\n await initializeStorage();\n await ensureDatabaseInitialized();\n\n // Scan for existing skills in filesystem\n console.log('🔍 Scanning for existing skills...');\n const { skillService } = await import('./services/skillService.js');\n await skillService.scanForSkills();\n\n return new Promise<void>((resolve) => {\n app.listen(port, () => {\n console.log(`🚀 SkillVerse server running on http://localhost:${port}`);\n console.log(`📁 Storage: ${process.env.SKILLVERSE_HOME || join(process.env.HOME || '', '.skillverse')}`);\n resolve();\n });\n });\n } catch (error) {\n console.error('Failed to start server:', error);\n process.exit(1);\n }\n}\n\n// Auto-start if run directly\nif (process.argv[1] === fileURLToPath(import.meta.url)) {\n startServer();\n}\n","import { Router, Request, Response, NextFunction } from 'express';\nimport multer from 'multer';\nimport { join } from 'path';\nimport { existsSync } from 'fs';\nimport { mkdir, rm } from 'fs/promises';\nimport { skillService } from '../services/skillService.js';\nimport { workspaceService } from '../services/workspaceService.js';\n\nconst router = Router();\n\n// Configure multer for file uploads\nconst TEMP_DIR = process.env.TEMP_DIR || join(process.env.HOME || '', '.skillverse', 'temp');\n\n// Ensure temp directory exists\nif (!existsSync(TEMP_DIR)) {\n mkdir(TEMP_DIR, { recursive: true });\n}\n\nconst storage = multer.diskStorage({\n destination: (req, file, cb) => {\n cb(null, TEMP_DIR);\n },\n filename: (req, file, cb) => {\n const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9);\n cb(null, uniqueSuffix + '-' + file.originalname);\n },\n});\n\nconst upload = multer({\n storage,\n limits: {\n fileSize: 100 * 1024 * 1024, // 100MB limit\n },\n fileFilter: (req, file, cb) => {\n if (file.mimetype === 'application/zip' || file.originalname.endsWith('.zip')) {\n cb(null, true);\n } else {\n cb(new Error('Only ZIP files are allowed'));\n }\n },\n});\n\n// GET /api/skills - Get all skills\nrouter.get('/', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const skills = await skillService.getAllSkills();\n res.json({\n success: true,\n data: skills,\n });\n } catch (error) {\n next(error);\n }\n});\n\n// GET /api/skills/:id - Get skill by ID\nrouter.get('/:id', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const skill = await skillService.getSkillById(req.params.id);\n res.json({\n success: true,\n data: skill,\n });\n } catch (error) {\n next(error);\n }\n});\n\n// POST /api/skills/from-git - Create skill from Git repository\nrouter.post('/from-git', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const { gitUrl, description } = req.body;\n\n if (!gitUrl) {\n return res.status(400).json({\n success: false,\n error: 'gitUrl is required',\n });\n }\n\n const skill = await skillService.createSkillFromGit(gitUrl, description);\n res.status(201).json({\n success: true,\n data: skill,\n message: 'Skill created successfully from Git repository',\n });\n } catch (error) {\n next(error);\n }\n});\n\n// POST /api/skills/from-local - Create skill from local ZIP file\nrouter.post(\n '/from-local',\n upload.single('file'),\n async (req: Request, res: Response, next: NextFunction) => {\n try {\n const { name, description } = req.body;\n const file = req.file;\n\n if (!name) {\n // Clean up uploaded file\n if (file) {\n await rm(file.path, { force: true });\n }\n return res.status(400).json({\n success: false,\n error: 'name is required',\n });\n }\n\n if (!file) {\n return res.status(400).json({\n success: false,\n error: 'ZIP file is required',\n });\n }\n\n const skill = await skillService.createSkillFromLocal(name, file.path, description);\n\n // Clean up temp file\n await rm(file.path, { force: true });\n\n res.status(201).json({\n success: true,\n data: skill,\n message: 'Skill created successfully from local file',\n });\n } catch (error) {\n // Clean up uploaded file on error\n if (req.file) {\n await rm(req.file.path, { force: true }).catch(() => { });\n }\n next(error);\n }\n }\n);\n\n// PUT /api/skills/:id - Update skill\nrouter.put('/:id', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const { name, description, metadata } = req.body;\n const skill = await skillService.updateSkill(req.params.id, {\n name,\n description,\n metadata,\n });\n res.json({\n success: true,\n data: skill,\n message: 'Skill updated successfully',\n });\n } catch (error) {\n next(error);\n }\n});\n\n// DELETE /api/skills/:id - Delete skill\nrouter.delete('/:id', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const removeFiles = req.query.removeFiles !== 'false';\n const result = await skillService.deleteSkill(req.params.id, removeFiles);\n res.json(result);\n } catch (error) {\n next(error);\n }\n});\n\n// POST /api/skills/:id/link - Link skill to workspace\nrouter.post('/:id/link', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const { workspaceId } = req.body;\n\n if (!workspaceId) {\n return res.status(400).json({\n success: false,\n error: 'workspaceId is required',\n });\n }\n\n const link = await workspaceService.linkSkillToWorkspace(req.params.id, workspaceId);\n res.status(201).json({\n success: true,\n data: link,\n message: 'Skill linked to workspace successfully',\n });\n } catch (error) {\n next(error);\n }\n});\n\n// DELETE /api/skills/:id/unlink/:workspaceId - Unlink skill from workspace\nrouter.delete(\n '/:id/unlink/:workspaceId',\n async (req: Request, res: Response, next: NextFunction) => {\n try {\n const result = await workspaceService.unlinkSkillFromWorkspace(\n req.params.id,\n req.params.workspaceId\n );\n res.json(result);\n } catch (error) {\n next(error);\n }\n }\n);\n\n// GET /api/skills/:id/check-update - Check for updates\nrouter.get('/:id/check-update', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const result = await skillService.checkForUpdate(req.params.id);\n res.json({\n success: true,\n data: result,\n });\n } catch (error) {\n next(error);\n }\n});\n\n// POST /api/skills/:id/upgrade - Upgrade skill\nrouter.post('/:id/upgrade', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const skill = await skillService.upgradeSkill(req.params.id);\n res.json({\n success: true,\n data: skill,\n message: 'Skill upgraded successfully',\n });\n } catch (error) {\n next(error);\n }\n});\n\n// POST /api/skills/check-updates - Check for updates for multiple skills\nrouter.post('/check-updates', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const { ids } = req.body; // Optional: ids array to check specific skills\n const results = await skillService.checkUpdates(ids);\n res.json({\n success: true,\n data: results,\n });\n } catch (error) {\n next(error);\n }\n});\n\n// POST /api/skills/:id/refresh-metadata - Refresh skill metadata\nrouter.post('/:id/refresh-metadata', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const skill = await skillService.refreshMetadata(req.params.id);\n res.json({\n success: true,\n data: skill,\n message: 'Metadata refreshed successfully',\n });\n } catch (error) {\n next(error);\n }\n});\n\n// GET /api/skills/:id/skill-md - Get SKILL.md content for preview\nrouter.get('/:id/skill-md', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const { readFile } = await import('fs/promises');\n const skill = await skillService.getSkillById(req.params.id);\n const skillMdPath = join(skill.storagePath, 'SKILL.md');\n\n if (!existsSync(skillMdPath)) {\n return res.json({\n success: true,\n data: {\n exists: false,\n content: null,\n },\n });\n }\n\n const content = await readFile(skillMdPath, 'utf-8');\n res.json({\n success: true,\n data: {\n exists: true,\n content,\n },\n });\n } catch (error) {\n next(error);\n }\n});\n\nexport default router;\n\n","import { join } from 'path';\nimport { homedir } from 'os';\nimport { symlink, unlink, rm, mkdir, appendFile, readFile } from 'fs/promises';\nimport { existsSync, lstatSync } from 'fs';\nimport { prisma } from '../lib/db.js';\nimport { AppError } from '../middleware/errorHandler.js';\nimport { ErrorCode, WorkspaceType, WorkspaceScope, WORKSPACE_SKILLS_PATHS } from '@skillverse/shared';\n\n/**\n * Compute the final skills path based on project path, type, and scope\n */\nfunction computeSkillsPath(projectPath: string, type: WorkspaceType, scope: WorkspaceScope): string {\n const pathConfig = WORKSPACE_SKILLS_PATHS[type];\n\n if (scope === 'global') {\n // Global path: replace ~ with actual home directory\n return pathConfig.global.replace('~', homedir());\n }\n\n // Project path = projectPath + sub-directory\n return join(projectPath, pathConfig.project);\n}\n\nexport class WorkspaceService {\n /**\n * Helper to get expected skills path for a project\n */\n getSkillsPath(projectPath: string, type: WorkspaceType, scope: WorkspaceScope): string {\n return computeSkillsPath(projectPath, type, scope);\n }\n\n /**\n * Sync database links with filesystem state\n * Removes links from DB if the symlink is missing from the workspace\n */\n private async syncLinks(workspace: any) {\n if (!workspace.linkedSkills || workspace.linkedSkills.length === 0) return;\n\n for (const link of workspace.linkedSkills) {\n if (!link.skill) continue;\n\n const linkPath = join(workspace.path, link.skill.name);\n\n // Check if symlink exists\n if (!existsSync(linkPath)) {\n console.log(`Link missing for skill \"${link.skill.name}\" in workspace \"${workspace.name}\". Removing from DB.`);\n try {\n await prisma.skillWorkspace.delete({\n where: { id: link.id },\n });\n // Update the in-memory object so the returned response is correct\n workspace.linkedSkills = workspace.linkedSkills.filter((l: any) => l.id !== link.id);\n } catch (err) {\n console.error(`Failed to sync link for ${link.skill.name}:`, err);\n }\n }\n }\n }\n\n async findWorkspaceByPath(path: string) {\n const workspace = await prisma.workspace.findUnique({\n where: { path },\n include: {\n linkedSkills: {\n include: {\n skill: true,\n },\n },\n },\n });\n return workspace;\n }\n\n async getAllWorkspaces() {\n const workspaces = await prisma.workspace.findMany({\n include: {\n linkedSkills: {\n include: {\n skill: true,\n },\n },\n },\n orderBy: {\n createdAt: 'desc',\n },\n });\n\n // Sync links for all workspaces (in parallel)\n await Promise.all(workspaces.map(w => this.syncLinks(w)));\n\n // Add isPathValid status for each workspace\n return workspaces.map(workspace => ({\n ...workspace,\n isPathValid: existsSync(workspace.path),\n }));\n }\n\n async getWorkspaceById(id: string) {\n const workspace = await prisma.workspace.findUnique({\n where: { id },\n include: {\n linkedSkills: {\n include: {\n skill: true,\n },\n },\n },\n });\n\n if (!workspace) {\n throw new AppError(ErrorCode.NOT_FOUND, 'Workspace not found', 404);\n }\n\n // Sync links with filesystem\n await this.syncLinks(workspace);\n\n return {\n ...workspace,\n isPathValid: existsSync(workspace.path),\n };\n }\n\n async createWorkspace(name: string, projectPath: string, type: WorkspaceType, scope: WorkspaceScope) {\n // Compute the final skills path\n const skillsPath = computeSkillsPath(projectPath, type, scope);\n\n // For project scope, check if project path exists\n if (scope === 'project' && projectPath && !existsSync(projectPath)) {\n throw new AppError(ErrorCode.FILE_SYSTEM_ERROR, `Project path does not exist: ${projectPath}`, 400);\n }\n\n // Auto-create skills directory if it doesn't exist\n if (!existsSync(skillsPath)) {\n try {\n await mkdir(skillsPath, { recursive: true });\n } catch (err: any) {\n throw new AppError(\n ErrorCode.FILE_SYSTEM_ERROR,\n `Failed to create skills directory: ${err.message}`,\n 500\n );\n }\n }\n\n // Check if workspace already exists at this path\n const existingWorkspace = await prisma.workspace.findUnique({\n where: { path: skillsPath },\n });\n\n if (existingWorkspace) {\n throw new AppError(ErrorCode.ALREADY_EXISTS, 'Workspace already exists at this path', 409);\n }\n\n const workspace = await prisma.workspace.create({\n data: {\n name,\n path: skillsPath,\n type,\n scope,\n },\n });\n\n // For project scope, try to add skills directory to .gitignore\n if (scope === 'project' && projectPath && existsSync(projectPath)) {\n try {\n const gitignorePath = join(projectPath, '.gitignore');\n const relativeSkillsPath = WORKSPACE_SKILLS_PATHS[type].project;\n\n let shouldAppend = false;\n\n if (existsSync(gitignorePath)) {\n const content = await readFile(gitignorePath, 'utf-8');\n // Check if path is already ignored (simple check)\n if (!content.includes(relativeSkillsPath)) {\n shouldAppend = true;\n }\n } else {\n // Create .gitignore if it doesn't exist\n shouldAppend = true;\n }\n\n if (shouldAppend) {\n const ignoreEntry = `\\n\\n# SkillVerse\\n${relativeSkillsPath}/\\n`;\n await appendFile(gitignorePath, ignoreEntry);\n console.log(`Added ${relativeSkillsPath}/ to .gitignore in ${projectPath}`);\n }\n } catch (err) {\n // Non-fatal error, just log it\n console.warn('Failed to update .gitignore:', err);\n }\n }\n\n return {\n ...workspace,\n isPathValid: true,\n };\n }\n\n async updateWorkspace(id: string, data: { name?: string; path?: string; type?: WorkspaceType; scope?: WorkspaceScope }) {\n await this.getWorkspaceById(id);\n\n const workspace = await prisma.workspace.update({\n where: { id },\n data,\n });\n\n return {\n ...workspace,\n isPathValid: existsSync(workspace.path),\n };\n }\n\n async deleteWorkspace(id: string) {\n const workspace = await this.getWorkspaceById(id);\n\n // Remove all symlinks for this workspace\n const links = await prisma.skillWorkspace.findMany({\n where: { workspaceId: id },\n include: { skill: true },\n });\n\n for (const link of links) {\n try {\n const linkPath = join(workspace.path, link.skill.name);\n if (existsSync(linkPath)) {\n await rm(linkPath, { recursive: true, force: true });\n }\n } catch (error) {\n console.error(`Failed to remove symlink for ${link.skill.name}:`, error);\n }\n }\n\n // Delete workspace\n await prisma.workspace.delete({ where: { id } });\n\n return { success: true, message: 'Workspace deleted successfully' };\n }\n\n async linkSkillToWorkspace(skillId: string, workspaceId: string) {\n const skill = await prisma.skill.findUnique({ where: { id: skillId } });\n const workspace = await prisma.workspace.findUnique({ where: { id: workspaceId } });\n\n if (!skill) {\n throw new AppError(ErrorCode.NOT_FOUND, 'Skill not found', 404);\n }\n\n if (!workspace) {\n throw new AppError(ErrorCode.NOT_FOUND, 'Workspace not found', 404);\n }\n\n // Validate workspace path still exists\n if (!existsSync(workspace.path)) {\n throw new AppError(\n ErrorCode.FILE_SYSTEM_ERROR,\n `Workspace skills directory does not exist: ${workspace.path}. The folder may have been deleted. Please recreate it or remove this workspace.`,\n 400\n );\n }\n\n // Check if link already exists\n const existingLink = await prisma.skillWorkspace.findFirst({\n where: {\n skillId,\n workspaceId,\n },\n });\n\n if (existingLink) {\n throw new AppError(ErrorCode.ALREADY_EXISTS, 'Skill is already linked to this workspace', 409);\n }\n\n // Create symlink\n const targetPath = join(workspace.path, skill.name);\n\n try {\n // Remove existing file/link if it exists\n if (existsSync(targetPath)) {\n const stats = lstatSync(targetPath);\n if (stats.isSymbolicLink()) {\n await unlink(targetPath);\n } else {\n throw new AppError(\n ErrorCode.FILE_SYSTEM_ERROR,\n `A file or directory already exists at ${targetPath}`,\n 409\n );\n }\n }\n\n // Create symlink\n await symlink(skill.storagePath, targetPath, 'dir');\n\n // Record link in database\n const link = await prisma.skillWorkspace.create({\n data: {\n skillId,\n workspaceId,\n },\n include: {\n skill: true,\n workspace: true,\n },\n });\n\n return link;\n } catch (error: any) {\n if (error instanceof AppError) throw error;\n\n console.error('Symlink creation error:', error);\n throw new AppError(\n ErrorCode.SYMLINK_ERROR,\n `Failed to create symlink: ${error.message}`,\n 500,\n error\n );\n }\n }\n\n async unlinkSkillFromWorkspace(skillId: string, workspaceId: string) {\n const link = await prisma.skillWorkspace.findFirst({\n where: {\n skillId,\n workspaceId,\n },\n include: {\n skill: true,\n workspace: true,\n },\n });\n\n if (!link) {\n throw new AppError(ErrorCode.NOT_FOUND, 'Link not found', 404);\n }\n\n // Remove symlink\n const linkPath = join(link.workspace.path, link.skill.name);\n\n try {\n if (existsSync(linkPath)) {\n await rm(linkPath, { recursive: true, force: true });\n }\n\n // Remove link from database\n await prisma.skillWorkspace.delete({\n where: { id: link.id },\n });\n\n return { success: true, message: 'Skill unlinked successfully' };\n } catch (error: any) {\n console.error('Unlink error:', error);\n throw new AppError(\n ErrorCode.FILE_SYSTEM_ERROR,\n `Failed to unlink skill: ${error.message}`,\n 500,\n error\n );\n }\n }\n\n /**\n * Detect existing skills in a workspace skills directory\n * Returns list of skill names that could be migrated\n */\n async detectExistingSkills(skillsPath: string): Promise<{ name: string; hasSkillMd: boolean; path: string }[]> {\n if (!existsSync(skillsPath)) {\n return [];\n }\n\n const { readdir, stat, readFile } = await import('fs/promises');\n const items = await readdir(skillsPath);\n const existingSkills: { name: string; hasSkillMd: boolean; path: string }[] = [];\n\n for (const item of items) {\n // Skip hidden files/directories\n if (item.startsWith('.')) continue;\n\n const itemPath = join(skillsPath, item);\n try {\n const itemStat = await stat(itemPath);\n\n // Skip symlinks (already linked skills)\n const lstats = lstatSync(itemPath);\n if (lstats.isSymbolicLink()) continue;\n\n if (itemStat.isDirectory()) {\n // Check if it has SKILL.md or other skill markers\n const hasSkillMd = existsSync(join(itemPath, 'SKILL.md'));\n const hasSkillJson = existsSync(join(itemPath, 'skill.json'));\n const hasPackageJson = existsSync(join(itemPath, 'package.json'));\n\n if (hasSkillMd || hasSkillJson || hasPackageJson) {\n existingSkills.push({\n name: item,\n hasSkillMd,\n path: itemPath,\n });\n }\n }\n } catch (error) {\n console.warn(`Failed to check ${itemPath}:`, error);\n }\n }\n\n return existingSkills;\n }\n\n /**\n * Migrate existing skills from workspace to unified storage\n * 1. Move skills to ~/.skillverse/skills/\n * 2. Register in database\n * 3. Create symlinks back to workspace\n */\n async migrateExistingSkills(workspaceId: string, skillNames: string[]): Promise<{ success: boolean; migrated: string[]; errors: string[] }> {\n const workspace = await this.getWorkspaceById(workspaceId);\n const SKILLVERSE_HOME = process.env.SKILLVERSE_HOME || join(homedir(), '.skillverse');\n const SKILLS_DIR = process.env.SKILLS_DIR || join(SKILLVERSE_HOME, 'skills');\n\n // Ensure skills directory exists\n if (!existsSync(SKILLS_DIR)) {\n await mkdir(SKILLS_DIR, { recursive: true });\n }\n\n const { rename, readFile, cp } = await import('fs/promises');\n const migrated: string[] = [];\n const errors: string[] = [];\n\n for (const skillName of skillNames) {\n const sourcePath = join(workspace.path, skillName);\n const targetPath = join(SKILLS_DIR, skillName);\n\n try {\n // Check if source exists and is not a symlink\n if (!existsSync(sourcePath)) {\n errors.push(`${skillName}: Source path not found`);\n continue;\n }\n\n const lstats = lstatSync(sourcePath);\n if (lstats.isSymbolicLink()) {\n errors.push(`${skillName}: Already a symlink, skipping`);\n continue;\n }\n\n // Check if skill already exists in unified storage\n if (existsSync(targetPath)) {\n // Check if it's the same skill by comparing paths or skip\n errors.push(`${skillName}: Already exists in unified storage`);\n continue;\n }\n\n // Check if skill already exists in database\n const existingSkill = await prisma.skill.findUnique({\n where: { name: skillName },\n });\n\n if (existingSkill) {\n errors.push(`${skillName}: Already registered in database`);\n continue;\n }\n\n // Parse metadata before moving\n const skillMdPath = join(sourcePath, 'SKILL.md');\n let description = '';\n let metadata: any = {};\n\n if (existsSync(skillMdPath)) {\n try {\n const matter = await import('gray-matter');\n const fileContent = await readFile(skillMdPath, 'utf-8');\n const parsed = matter.default(fileContent);\n description = parsed.data.description || '';\n metadata = parsed.data;\n } catch (e) {\n console.warn(`Failed to parse SKILL.md for ${skillName}:`, e);\n }\n }\n\n // Move skill to unified storage\n await cp(sourcePath, targetPath, { recursive: true });\n await rm(sourcePath, { recursive: true, force: true });\n\n // Register in database\n const skill = await prisma.skill.create({\n data: {\n name: skillName,\n source: 'local',\n description,\n storagePath: targetPath,\n metadata: JSON.stringify(metadata),\n },\n });\n\n // Create symlink back to workspace\n await symlink(targetPath, sourcePath, 'dir');\n\n // Create skill-workspace link in database\n await prisma.skillWorkspace.create({\n data: {\n skillId: skill.id,\n workspaceId: workspace.id,\n },\n });\n\n migrated.push(skillName);\n console.log(`✅ Migrated skill \"${skillName}\" to unified storage`);\n\n } catch (error: any) {\n console.error(`Failed to migrate ${skillName}:`, error);\n errors.push(`${skillName}: ${error.message}`);\n }\n }\n\n return {\n success: errors.length === 0,\n migrated,\n errors,\n };\n }\n}\n\nexport const workspaceService = new WorkspaceService();\n","import { Router, Request, Response, NextFunction } from 'express';\nimport { workspaceService } from '../services/workspaceService.js';\nimport { WorkspaceType, WorkspaceScope } from '@skillverse/shared';\n\nconst router = Router();\n\n// GET /api/workspaces - Get all workspaces\nrouter.get('/', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const workspaces = await workspaceService.getAllWorkspaces();\n res.json({\n success: true,\n data: workspaces,\n });\n } catch (error) {\n next(error);\n }\n});\n\n// GET /api/workspaces/:id - Get workspace by ID\nrouter.get('/:id', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const workspace = await workspaceService.getWorkspaceById(req.params.id);\n res.json({\n success: true,\n data: workspace,\n });\n } catch (error) {\n next(error);\n }\n});\n\n// POST /api/workspaces - Create workspace\nrouter.post('/', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const { name, projectPath, type, scope } = req.body;\n\n if (!name || !type || !scope) {\n return res.status(400).json({\n success: false,\n error: 'name, type, and scope are required',\n });\n }\n\n // For project scope, projectPath is required\n if (scope === 'project' && !projectPath) {\n return res.status(400).json({\n success: false,\n error: 'projectPath is required for project scope',\n });\n }\n\n const validTypes: WorkspaceType[] = ['vscode', 'cursor', 'claude-desktop', 'codex', 'antigravity', 'custom'];\n if (!validTypes.includes(type)) {\n return res.status(400).json({\n success: false,\n error: `type must be one of: ${validTypes.join(', ')}`,\n });\n }\n\n const validScopes: WorkspaceScope[] = ['project', 'global'];\n if (!validScopes.includes(scope)) {\n return res.status(400).json({\n success: false,\n error: `scope must be one of: ${validScopes.join(', ')}`,\n });\n }\n\n const workspace = await workspaceService.createWorkspace(name, projectPath || '', type, scope);\n res.status(201).json({\n success: true,\n data: workspace,\n message: 'Workspace created successfully',\n });\n } catch (error) {\n next(error);\n }\n});\n\n// PUT /api/workspaces/:id - Update workspace\nrouter.put('/:id', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const { name, path, type, scope } = req.body;\n\n if (type) {\n const validTypes: WorkspaceType[] = ['vscode', 'cursor', 'claude-desktop', 'codex', 'antigravity', 'custom'];\n if (!validTypes.includes(type)) {\n return res.status(400).json({\n success: false,\n error: `type must be one of: ${validTypes.join(', ')}`,\n });\n }\n }\n\n if (scope) {\n const validScopes: WorkspaceScope[] = ['project', 'global'];\n if (!validScopes.includes(scope)) {\n return res.status(400).json({\n success: false,\n error: `scope must be one of: ${validScopes.join(', ')}`,\n });\n }\n }\n\n const workspace = await workspaceService.updateWorkspace(req.params.id, {\n name,\n path,\n type,\n scope,\n });\n res.json({\n success: true,\n data: workspace,\n message: 'Workspace updated successfully',\n });\n } catch (error) {\n next(error);\n }\n});\n\n// DELETE /api/workspaces/:id - Delete workspace\nrouter.delete('/:id', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const result = await workspaceService.deleteWorkspace(req.params.id);\n res.json(result);\n } catch (error) {\n next(error);\n }\n});\n\n// POST /api/workspaces/:id/detect-skills - Detect existing skills in workspace\nrouter.post('/:id/detect-skills', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const workspace = await workspaceService.getWorkspaceById(req.params.id);\n const existingSkills = await workspaceService.detectExistingSkills(workspace.path);\n res.json({\n success: true,\n data: existingSkills,\n });\n } catch (error) {\n next(error);\n }\n});\n\n// POST /api/workspaces/:id/migrate-skills - Migrate existing skills to unified storage\nrouter.post('/:id/migrate-skills', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const { skillNames } = req.body;\n\n if (!skillNames || !Array.isArray(skillNames) || skillNames.length === 0) {\n return res.status(400).json({\n success: false,\n error: 'skillNames array is required',\n });\n }\n\n const result = await workspaceService.migrateExistingSkills(req.params.id, skillNames);\n res.json({\n success: true,\n data: result,\n });\n } catch (error) {\n next(error);\n }\n});\n\nexport default router;\n\n","import { Router, Request, Response, NextFunction } from 'express';\nimport { prisma } from '../lib/db.js';\nimport { skillService } from '../services/skillService.js';\nimport { bundleService } from '../services/bundleService.js';\nimport { AppError } from '../middleware/errorHandler.js';\nimport { ErrorCode } from '@skillverse/shared';\nimport { existsSync } from 'fs';\n\nconst router = Router();\n\n// GET /api/marketplace/skills - Get all marketplace skills\nrouter.get('/skills', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const { search, page = '1', pageSize = '20' } = req.query;\n\n const where: any = {};\n if (search) {\n where.skill = {\n OR: [\n { name: { contains: search as string } },\n { description: { contains: search as string } },\n ],\n };\n }\n\n const [items, total] = await Promise.all([\n prisma.marketplaceSkill.findMany({\n where,\n include: {\n skill: true,\n },\n orderBy: {\n downloads: 'desc',\n },\n skip: (parseInt(page as string) - 1) * parseInt(pageSize as string),\n take: parseInt(pageSize as string),\n }),\n prisma.marketplaceSkill.count({ where }),\n ]);\n\n res.json({\n success: true,\n data: {\n items,\n total,\n page: parseInt(page as string),\n pageSize: parseInt(pageSize as string),\n },\n });\n } catch (error) {\n next(error);\n }\n});\n\n// GET /api/marketplace/skills/:id - Get marketplace skill by ID\nrouter.get('/skills/:id', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const marketplaceSkill = await prisma.marketplaceSkill.findUnique({\n where: { id: req.params.id },\n include: {\n skill: true,\n },\n });\n\n if (!marketplaceSkill) {\n throw new AppError(ErrorCode.NOT_FOUND, 'Marketplace skill not found', 404);\n }\n\n res.json({\n success: true,\n data: marketplaceSkill,\n });\n } catch (error) {\n next(error);\n }\n});\n\n// GET /api/marketplace/download/:id - Download skill bundle\nrouter.get('/download/:id', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const marketplaceSkill = await prisma.marketplaceSkill.findUnique({\n where: { id: req.params.id },\n include: {\n skill: true,\n },\n });\n\n if (!marketplaceSkill) {\n throw new AppError(ErrorCode.NOT_FOUND, 'Marketplace skill not found', 404);\n }\n\n // For Git skills, redirect to the source URL or return info\n if (marketplaceSkill.skill.source === 'git' && marketplaceSkill.skill.sourceUrl) {\n return res.json({\n success: true,\n data: {\n type: 'git',\n sourceUrl: marketplaceSkill.skill.sourceUrl,\n },\n });\n }\n\n // For bundled skills, serve the bundle file\n if (marketplaceSkill.bundlePath && existsSync(marketplaceSkill.bundlePath)) {\n res.setHeader('Content-Type', 'application/gzip');\n res.setHeader(\n 'Content-Disposition',\n `attachment; filename=\"${marketplaceSkill.skill.name}.tar.gz\"`\n );\n return res.sendFile(marketplaceSkill.bundlePath);\n }\n\n throw new AppError(ErrorCode.NOT_FOUND, 'Bundle not available for this skill', 404);\n } catch (error) {\n next(error);\n }\n});\n\n// POST /api/marketplace/publish - Publish skill to marketplace\nrouter.post('/publish', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const { skillId, publisherName } = req.body;\n\n if (!skillId) {\n return res.status(400).json({\n success: false,\n error: 'skillId is required',\n });\n }\n\n // Check if skill exists\n const skill = await prisma.skill.findUnique({\n where: { id: skillId },\n });\n\n if (!skill) {\n throw new AppError(ErrorCode.NOT_FOUND, 'Skill not found', 404);\n }\n\n // Check if already published\n const existingEntry = await prisma.marketplaceSkill.findUnique({\n where: { skillId },\n });\n\n if (existingEntry) {\n throw new AppError(ErrorCode.ALREADY_EXISTS, 'Skill is already published to marketplace', 409);\n }\n\n // Create bundle for local skills\n let bundlePath: string | null = null;\n let bundleSize: number | null = null;\n\n if (skill.source === 'local' && existsSync(skill.storagePath)) {\n bundlePath = await bundleService.createBundle(skill.storagePath, skill.name);\n bundleSize = await bundleService.getBundleSize(bundlePath);\n }\n\n // Create marketplace entry\n const marketplaceSkill = await prisma.marketplaceSkill.create({\n data: {\n skillId,\n publisherName: publisherName || 'Anonymous',\n bundlePath,\n bundleSize,\n },\n include: {\n skill: true,\n },\n });\n\n res.status(201).json({\n success: true,\n data: marketplaceSkill,\n message: 'Skill published to marketplace successfully',\n });\n } catch (error) {\n next(error);\n }\n});\n\n\n// POST /api/marketplace/install/:id - Install skill from marketplace\nrouter.post('/install/:id', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const marketplaceSkill = await prisma.marketplaceSkill.findUnique({\n where: { id: req.params.id },\n include: {\n skill: true,\n },\n });\n\n if (!marketplaceSkill) {\n throw new AppError(ErrorCode.NOT_FOUND, 'Marketplace skill not found', 404);\n }\n\n const sourceSkill = marketplaceSkill.skill;\n\n // For Git source, clone the repository\n if (sourceSkill.source === 'git' && sourceSkill.sourceUrl) {\n const newSkill = await skillService.createSkillFromGit(\n sourceSkill.sourceUrl,\n sourceSkill.description || undefined\n );\n\n // Increment download count\n await prisma.marketplaceSkill.update({\n where: { id: req.params.id },\n data: { downloads: { increment: 1 } },\n });\n\n return res.status(201).json({\n success: true,\n data: newSkill,\n message: 'Skill installed from marketplace successfully',\n });\n }\n\n // For local source with bundle, extract the bundle\n if (sourceSkill.source === 'local' && marketplaceSkill.bundlePath && existsSync(marketplaceSkill.bundlePath)) {\n const newSkill = await skillService.createSkillFromBundle(\n marketplaceSkill.bundlePath,\n sourceSkill.name,\n sourceSkill.description || undefined\n );\n\n // Increment download count\n await prisma.marketplaceSkill.update({\n where: { id: req.params.id },\n data: { downloads: { increment: 1 } },\n });\n\n return res.status(201).json({\n success: true,\n data: newSkill,\n message: 'Skill installed from marketplace successfully',\n });\n }\n\n // No bundle available\n return res.status(400).json({\n success: false,\n error: 'Cannot install this skill. Bundle not available.',\n });\n } catch (error) {\n next(error);\n }\n});\n\n// DELETE /api/marketplace/unpublish/:id - Unpublish skill from marketplace\nrouter.delete('/unpublish/:skillId', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const marketplaceSkill = await prisma.marketplaceSkill.findUnique({\n where: { skillId: req.params.skillId },\n });\n\n if (!marketplaceSkill) {\n throw new AppError(ErrorCode.NOT_FOUND, 'Skill is not published to marketplace', 404);\n }\n\n await prisma.marketplaceSkill.delete({\n where: { id: marketplaceSkill.id },\n });\n\n res.json({\n success: true,\n message: 'Skill unpublished from marketplace successfully',\n });\n } catch (error) {\n next(error);\n }\n});\n\nexport default router;\n","import { createWriteStream, existsSync, createReadStream } from 'fs';\nimport { mkdir, rm, readdir, stat } from 'fs/promises';\nimport { join, basename } from 'path';\nimport { pipeline } from 'stream/promises';\nimport archiver from 'archiver';\nimport { createGunzip } from 'zlib';\nimport { extract } from 'tar';\n\nconst BUNDLES_DIR = join(\n process.env.SKILLVERSE_HOME || join(process.env.HOME || '', '.skillverse'),\n 'bundles'\n);\n\n/**\n * Ensures the bundles directory exists\n */\nasync function ensureBundlesDir(): Promise<void> {\n if (!existsSync(BUNDLES_DIR)) {\n await mkdir(BUNDLES_DIR, { recursive: true });\n }\n}\n\n/**\n * Creates a .tar.gz bundle from a skill directory\n * @param skillPath - Path to the skill directory\n * @param skillName - Name of the skill (used for bundle filename)\n * @returns Path to the created bundle\n */\nexport async function createBundle(skillPath: string, skillName: string): Promise<string> {\n await ensureBundlesDir();\n\n const bundleName = `${skillName}-${Date.now()}.tar.gz`;\n const bundlePath = join(BUNDLES_DIR, bundleName);\n\n return new Promise((resolve, reject) => {\n const output = createWriteStream(bundlePath);\n const archive = archiver('tar', {\n gzip: true,\n gzipOptions: { level: 9 },\n });\n\n output.on('close', () => {\n console.log(`📦 Bundle created: ${bundlePath} (${archive.pointer()} bytes)`);\n resolve(bundlePath);\n });\n\n archive.on('error', (err) => {\n reject(err);\n });\n\n archive.pipe(output);\n\n // Add all files from the skill directory\n archive.directory(skillPath, false);\n\n archive.finalize();\n });\n}\n\n/**\n * Extracts a bundle to a target directory\n * @param bundlePath - Path to the .tar.gz bundle\n * @param targetDir - Directory to extract to\n */\nexport async function extractBundle(bundlePath: string, targetDir: string): Promise<void> {\n if (!existsSync(bundlePath)) {\n throw new Error(`Bundle not found: ${bundlePath}`);\n }\n\n // Create target directory if it doesn't exist\n if (!existsSync(targetDir)) {\n await mkdir(targetDir, { recursive: true });\n }\n\n await pipeline(\n createReadStream(bundlePath),\n createGunzip(),\n extract({ cwd: targetDir })\n );\n\n console.log(`📂 Bundle extracted to: ${targetDir}`);\n}\n\n/**\n * Deletes a bundle file\n * @param bundlePath - Path to the bundle to delete\n */\nexport async function deleteBundle(bundlePath: string): Promise<void> {\n if (existsSync(bundlePath)) {\n await rm(bundlePath);\n console.log(`🗑️ Bundle deleted: ${bundlePath}`);\n }\n}\n\n/**\n * Gets the size of a bundle in bytes\n * @param bundlePath - Path to the bundle\n */\nexport async function getBundleSize(bundlePath: string): Promise<number> {\n if (!existsSync(bundlePath)) {\n return 0;\n }\n const stats = await stat(bundlePath);\n return stats.size;\n}\n\n/**\n * Lists all bundles in the bundles directory\n */\nexport async function listBundles(): Promise<string[]> {\n await ensureBundlesDir();\n const files = await readdir(BUNDLES_DIR);\n return files.filter((f) => f.endsWith('.tar.gz')).map((f) => join(BUNDLES_DIR, f));\n}\n\nexport const bundleService = {\n createBundle,\n extractBundle,\n deleteBundle,\n getBundleSize,\n listBundles,\n BUNDLES_DIR,\n};\n","import { Router, Request, Response, NextFunction } from 'express';\nimport { prisma } from '../lib/db.js';\n\nconst router = Router();\n\n// GET /api/dashboard/stats - Get dashboard statistics\nrouter.get('/stats', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const [totalSkills, totalWorkspaces, totalLinks, marketplaceSkills, recentSkills] =\n await Promise.all([\n prisma.skill.count(),\n prisma.workspace.count(),\n prisma.skillWorkspace.count(),\n prisma.marketplaceSkill.count(),\n prisma.skill.findMany({\n orderBy: { installDate: 'desc' },\n take: 5,\n include: {\n linkedWorkspaces: {\n include: {\n workspace: true,\n },\n },\n },\n }),\n ]);\n\n res.json({\n success: true,\n data: {\n totalSkills,\n totalWorkspaces,\n totalLinks,\n marketplaceSkills,\n recentSkills,\n },\n });\n } catch (error) {\n next(error);\n }\n});\n\n// GET /api/dashboard/activity - Get recent activity\nrouter.get('/activity', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const [recentSkills, recentLinks, recentPublished] = await Promise.all([\n prisma.skill.findMany({\n orderBy: { createdAt: 'desc' },\n take: 10,\n select: {\n id: true,\n name: true,\n source: true,\n createdAt: true,\n },\n }),\n prisma.skillWorkspace.findMany({\n orderBy: { linkedAt: 'desc' },\n take: 10,\n include: {\n skill: { select: { name: true } },\n workspace: { select: { name: true } },\n },\n }),\n prisma.marketplaceSkill.findMany({\n orderBy: { publishDate: 'desc' },\n take: 10,\n include: {\n skill: { select: { name: true } },\n },\n }),\n ]);\n\n // Combine and sort by date\n const activities = [\n ...recentSkills.map((s) => ({\n type: 'skill_added' as const,\n date: s.createdAt,\n data: { skillName: s.name, source: s.source },\n })),\n ...recentLinks.map((l) => ({\n type: 'skill_linked' as const,\n date: l.linkedAt,\n data: { skillName: l.skill.name, workspaceName: l.workspace.name },\n })),\n ...recentPublished.map((p) => ({\n type: 'skill_published' as const,\n date: p.publishDate,\n data: { skillName: p.skill.name },\n })),\n ].sort((a, b) => b.date.getTime() - a.date.getTime());\n\n res.json({\n success: true,\n data: activities.slice(0, 20),\n });\n } catch (error) {\n next(error);\n }\n});\n\nexport default router;\n","import { Router, Request, Response, NextFunction } from 'express';\nimport { join } from 'path';\nimport { existsSync, readFileSync, writeFileSync } from 'fs';\n\nconst router = Router();\n\n// Path to config.json\n// We ALWAYS read/write to the bootstrap location to ensure persistence works\nconst HOME = process.env.HOME || process.env.USERPROFILE || '';\nconst BOOTSTRAP_HOME = join(HOME, '.skillverse');\nconst CONFIG_FILE = join(BOOTSTRAP_HOME, 'config.json');\n\n// Helper to read config\nfunction readConfig() {\n if (existsSync(CONFIG_FILE)) {\n try {\n return JSON.parse(readFileSync(CONFIG_FILE, 'utf-8'));\n } catch (e) {\n console.error('Failed to read config.json:', e);\n return {};\n }\n }\n return {};\n}\n\n// GET /api/config - Get current configuration\nrouter.get('/', (req: Request, res: Response, next: NextFunction) => {\n try {\n const fileConfig = readConfig();\n\n // Combine env vars with file config\n // logic: File config represents \"User Preference\" (potentially pending restart)\n // Env vars represent \"Current Runtime State\" or \"System Defaults\"\n // We prioritize File Config for editable fields so the UI shows what is saved.\n\n const config = {\n // Show saved preference if available, otherwise current env/default\n skillverseHome: fileConfig.skillverseHome || process.env.SKILLVERSE_HOME || BOOTSTRAP_HOME,\n // registryUrl is potentially in config.json already\n registryUrl: fileConfig.registryUrl || process.env.SKILLVERSE_REGISTRY || 'http://localhost:4000',\n // ... add other configurable items\n };\n\n res.json({\n success: true,\n data: config,\n });\n } catch (error) {\n next(error);\n }\n});\n\n// POST /api/config - Update configuration\nrouter.post('/', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const { skillverseHome, registryUrl, migrate } = req.body;\n\n const currentConfig = readConfig();\n const oldHome = process.env.SKILLVERSE_HOME || BOOTSTRAP_HOME;\n\n if (migrate && skillverseHome && skillverseHome !== oldHome) {\n console.log(`Migrating data from ${oldHome} to ${skillverseHome}...`);\n const { cp } = await import('fs/promises');\n\n // Ensure new directory exists\n if (!existsSync(skillverseHome)) {\n const { mkdir } = await import('fs/promises');\n await mkdir(skillverseHome, { recursive: true });\n }\n\n // Helper to copy if source exists\n const copyDir = async (srcName: string) => {\n const src = join(oldHome, srcName);\n const dest = join(skillverseHome, srcName);\n if (existsSync(src)) {\n console.log(`Copying ${srcName}...`);\n await cp(src, dest, { recursive: true, force: true });\n }\n };\n\n await copyDir('skills');\n await copyDir('marketplace');\n\n // Copy Database\n const dbSrc = join(oldHome, 'skillverse.db');\n const dbDest = join(skillverseHome, 'skillverse.db');\n if (existsSync(dbSrc)) {\n console.log('Copying database...');\n // Try to copy main DB file\n await cp(dbSrc, dbDest, { force: true });\n\n // Try to copy WAL/SHM files if they exist (for SQLite safety)\n const walSrc = dbSrc + '-wal';\n if (existsSync(walSrc)) await cp(walSrc, dbDest + '-wal', { force: true });\n\n const shmSrc = dbSrc + '-shm';\n if (existsSync(shmSrc)) await cp(shmSrc, dbDest + '-shm', { force: true });\n\n // CRITICAL: Update storagePath in the NEW database to point to the new home\n // We need to use a direct SQLite update since Prisma is connected to the old DB\n console.log('Updating skill paths in new database...');\n const { execSync } = await import('child_process');\n const oldSkillsPath = join(oldHome, 'skills');\n const newSkillsPath = join(skillverseHome, 'skills');\n\n // Use SQLite to update all storagePath values\n const updateQuery = `UPDATE Skill SET storagePath = replace(storagePath, '${oldSkillsPath}', '${newSkillsPath}') WHERE storagePath LIKE '${oldSkillsPath}%';`;\n try {\n execSync(`sqlite3 \"${dbDest}\" \"${updateQuery}\"`, { encoding: 'utf-8' });\n console.log('✅ Updated skill paths in new database');\n } catch (sqlErr) {\n console.error('Failed to update skill paths:', sqlErr);\n }\n }\n }\n\n const newConfig = {\n ...currentConfig,\n ...(skillverseHome && { skillverseHome }),\n ...(registryUrl && { registryUrl }),\n };\n\n // Write to config.json\n writeFileSync(CONFIG_FILE, JSON.stringify(newConfig, null, 2));\n\n res.json({\n success: true,\n data: newConfig,\n message: 'Configuration saved. Restart server for changes to take effect.',\n });\n } catch (error) {\n next(error);\n }\n});\n\nexport default router;\n","import { Request, Response, NextFunction } from 'express';\n\nexport function requestLogger(req: Request, res: Response, next: NextFunction) {\n const start = Date.now();\n \n res.on('finish', () => {\n const duration = Date.now() - start;\n console.log(`${req.method} ${req.path} - ${res.statusCode} - ${duration}ms`);\n });\n \n next();\n}\n","import { existsSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\nimport { prisma } from './db.js';\nimport { spawnSync } from 'child_process';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n// Find schema.prisma\n// Dev: server/src/lib/initDb.ts -> server/prisma/schema.prisma\n// Prod: server/dist/lib/initDb.js -> server/prisma/schema.prisma (copied via package.json files)\n// Or: server/node_modules/skillverse/prisma/schema.prisma\nfunction getSchemaPath(): string | null {\n const possiblePaths = [\n // Prod: dist/bin.js -> dist/../prisma/schema.prisma (i.e. ROOT/prisma/schema.prisma)\n join(__dirname, '../prisma/schema.prisma'),\n // Dev: src/lib/initDb.ts -> src/prisma/schema.prisma ? No, src/../prisma -> server/prisma\n // If __dirname is src/lib: ../../prisma/schema.prisma\n join(__dirname, '../../prisma/schema.prisma'),\n\n // Fallbacks\n join(process.cwd(), 'prisma/schema.prisma'),\n join(process.cwd(), 'server/prisma/schema.prisma'),\n ];\n\n return possiblePaths.find(p => existsSync(p)) || null;\n}\n\nexport async function ensureDatabaseInitialized() {\n try {\n // Check if we can query the database (e.g. check if Skill table exists)\n // We can try a simple count. If it fails with \"table not found\", we need to init.\n try {\n await prisma.skill.count();\n // If successful, DB is initialized\n return;\n } catch (error: any) {\n if (error.code === 'P2021' || error.message.includes('table') || error.message.includes('does not exist')) {\n console.log('📦 Initializing database...');\n await initializeDatabase();\n } else {\n throw error;\n }\n }\n } catch (error: any) {\n // console.error('ensureDatabaseInitialized error:', error);\n throw error;\n }\n}\n\nasync function initializeDatabase() {\n const schemaPath = getSchemaPath();\n if (!schemaPath) {\n throw new Error('Could not find schema.prisma');\n }\n\n // We need to run \"prisma db push\"\n // But \"prisma\" might not be in the global path.\n // In the installed package, it should be in node_modules/.bin/prisma\n\n // Try to find local prisma binary\n // Prod: dist/bin.js -> ../node_modules/.bin/prisma\n // Dev: src/lib/initDb.ts -> ../../node_modules/.bin/prisma\n const possiblePrismaBins = [\n join(__dirname, '../node_modules/.bin/prisma'),\n join(__dirname, '../../node_modules/.bin/prisma'),\n join(__dirname, '../../../node_modules/.bin/prisma'),\n join(process.cwd(), 'node_modules/.bin/prisma'),\n ];\n\n const prismaBin = possiblePrismaBins.find(p => existsSync(p)) || 'prisma';\n\n console.log(` Using schema: ${schemaPath}`);\n\n const result = spawnSync(prismaBin, ['db', 'push', '--schema', schemaPath], {\n stdio: 'inherit',\n env: { ...process.env }, // Ensure env vars (DATABASE_URL) are passed\n });\n\n if (result.error) {\n throw result.error;\n }\n\n if (result.status !== 0) {\n throw new Error(`Database initialization failed with status ${result.status}`);\n }\n\n console.log('✅ Database initialized successfully');\n}\n"],"mappings":"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","names":["config","config","join","existsSync","readdir","stat","createReadStream","createGunzip","pipeline","dotenv","fileURLToPath","dirname","join","mkdir","existsSync","join","existsSync","mkdir","rm","join","unlink","rm","mkdir","readFile","existsSync","readdir","stat","cp","matter","join","existsSync","mkdir","rm","readFile","Router","router","Router","Router","existsSync","mkdir","rm","join","existsSync","router","Router","Router","router","Router","join","existsSync","readFileSync","router","config","cp","mkdir","existsSync","join","dirname","fileURLToPath","__filename","__dirname","dotenv","__filename","fileURLToPath","__dirname","dirname","join","existsSync","mkdir","skillService"]}
1
+ {"version":3,"sources":["../src/config.ts","../src/lib/db.ts","../../shared/src/index.ts","../src/middleware/errorHandler.ts","../src/services/skillService.ts","../src/index.ts","../src/routes/skills.ts","../src/services/workspaceService.ts","../src/routes/workspaces.ts","../src/routes/marketplace.ts","../src/services/bundleService.ts","../src/services/githubMarketplaceRegistry.ts","../src/marketplaceConfig.ts","../src/routes/dashboard.ts","../src/routes/config.ts","../src/middleware/logger.ts","../src/lib/initDb.ts"],"sourcesContent":["import { join, dirname } from 'path';\nimport { existsSync, mkdirSync, readFileSync } from 'fs';\nimport { fileURLToPath } from 'url';\nimport dotenv from 'dotenv';\n\n// Load .env file\ndotenv.config();\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nexport function setupEnvironment() {\n const home = process.env.HOME || process.env.USERPROFILE || '';\n // The \"Bootstrap\" home is always the default location\n const defaultHome = join(home, '.skillverse');\n const bootstrapConfigPath = join(defaultHome, 'config.json');\n\n let skillverseHome = process.env.SKILLVERSE_HOME || defaultHome;\n\n // Try to read config.json from the default location to see if there's an override\n if (existsSync(bootstrapConfigPath)) {\n try {\n const config = JSON.parse(readFileSync(bootstrapConfigPath, 'utf-8'));\n if (config.skillverseHome) {\n skillverseHome = config.skillverseHome;\n // CRITICAL: Update process.env so that other modules (and routes) see the new path\n process.env.SKILLVERSE_HOME = skillverseHome;\n console.log(`Common config found. Using custom home: ${skillverseHome}`);\n }\n } catch (e) {\n console.warn('Failed to read bootstrap config:', e);\n }\n }\n\n const dbUrl = process.env.DATABASE_URL;\n\n // Ensure config directory exists (for the active home)\n if (!existsSync(skillverseHome)) {\n try {\n mkdirSync(skillverseHome, { recursive: true });\n } catch (error) {\n console.error('Failed to create .skillverse directory:', error);\n }\n }\n\n // Set default database URL if not provided or if we have a custom home override\n if (!dbUrl || (skillverseHome !== defaultHome)) {\n const dbPath = join(skillverseHome, 'skillverse.db');\n process.env.DATABASE_URL = `file:${dbPath}`;\n // strict logic: index.ts calls this before initDb, so initDb will see the updated env\n console.log(`Using database at: ${dbPath}`);\n }\n\n // CRITICAL: Ensure other derived paths are also updated in process.env\n // This prevents modules from using stale paths from .env if they were pre-set\n process.env.SKILLS_DIR = join(skillverseHome, 'skills');\n process.env.MARKETPLACE_DIR = join(skillverseHome, 'marketplace');\n process.env.TEMP_DIR = join(skillverseHome, 'temp');\n\n return {\n skillverseHome,\n databaseUrl: process.env.DATABASE_URL,\n };\n}\n\n// Run setup immediately\nexport const config = setupEnvironment();\n","import { PrismaClient } from '@prisma/client';\n\n// Force fresh config read on every module load\n// This is critical because tsx HMR can cache imports\nimport { setupEnvironment } from '../config.js';\nconst config = setupEnvironment();\n\nconst globalForPrisma = globalThis as unknown as {\n prisma: PrismaClient | undefined;\n lastDbUrl: string | undefined;\n};\n\n// Get the current DATABASE_URL after config setup\nconst currentDbUrl = process.env.DATABASE_URL;\nconsole.log(`📊 DB connection target: ${currentDbUrl}`);\n\n// If DB URL changed, we need a new client\nif (globalForPrisma.prisma && globalForPrisma.lastDbUrl !== currentDbUrl) {\n console.log(`🔄 DATABASE_URL changed from ${globalForPrisma.lastDbUrl} to ${currentDbUrl}, reconnecting...`);\n // Disconnect old client (async, but we don't wait)\n globalForPrisma.prisma.$disconnect().catch(console.error);\n globalForPrisma.prisma = undefined;\n}\n\nexport const prisma =\n globalForPrisma.prisma ??\n new PrismaClient({\n log: process.env.NODE_ENV === 'development' ? ['error', 'warn'] : ['error'],\n });\n\n// Store the current DB URL and client in global\nglobalForPrisma.prisma = prisma;\nglobalForPrisma.lastDbUrl = currentDbUrl;\n","// Skill types\nexport interface Skill {\n id: string;\n name: string;\n source: 'git' | 'local';\n sourceUrl?: string;\n description?: string;\n commitHash?: string;\n repoUrl?: string;\n updateAvailable: boolean;\n lastUpdateCheck?: Date;\n installDate: Date;\n metadata?: Record<string, any>;\n marketplaceEntry?: MarketplaceSkill;\n linkedWorkspaces?: SkillWorkspace[];\n}\n\nexport interface CreateSkillFromGitDto {\n gitUrl: string;\n description?: string;\n}\n\nexport interface CreateSkillFromLocalDto {\n name: string;\n description?: string;\n}\n\nexport interface UpdateSkillDto {\n name?: string;\n description?: string;\n metadata?: Record<string, any>;\n}\n\n// Workspace types\nexport interface Workspace {\n id: string;\n name: string;\n path: string;\n type: WorkspaceType;\n scope: WorkspaceScope;\n createdAt: Date;\n isPathValid?: boolean; // runtime computed, not stored in DB\n}\n\nexport type WorkspaceType = 'vscode' | 'cursor' | 'claude-desktop' | 'codex' | 'antigravity' | 'custom';\nexport type WorkspaceScope = 'project' | 'global';\n\n// 各编辑器类型对应的 skills 子目录\nexport const WORKSPACE_SKILLS_PATHS: Record<WorkspaceType, { project: string; global: string }> = {\n vscode: {\n project: '.github/skills',\n global: '~/.copilot/skills'\n },\n cursor: {\n project: '.cursor/skills',\n global: '~/.cursor/skills'\n },\n 'claude-desktop': {\n project: '.claude/skills',\n global: '~/.claude/skills'\n },\n codex: {\n project: '.codex/skills',\n global: '~/.codex/skills'\n },\n antigravity: {\n project: '.agent/skills',\n global: '~/.agent/skills'\n },\n custom: {\n project: 'skills',\n global: ''\n },\n};\n\nexport interface CreateWorkspaceDto {\n name: string;\n projectPath: string; // 项目根目录(project scope)或空(global scope)\n type: WorkspaceType;\n scope: WorkspaceScope;\n}\n\nexport interface UpdateWorkspaceDto {\n name?: string;\n path?: string;\n type?: WorkspaceType;\n scope?: WorkspaceScope;\n}\n\n// Skill-Workspace link types\nexport interface SkillWorkspace {\n id: string;\n skillId: string;\n workspaceId: string;\n linkedAt: Date;\n skill?: Skill;\n workspace?: Workspace;\n}\n\nexport interface LinkSkillToWorkspaceDto {\n skillId: string;\n workspaceId: string;\n}\n\n// Marketplace types\nexport interface MarketplaceSkill {\n id: string;\n skillId: string;\n publisherId?: string;\n publisherName?: string;\n publishDate: Date;\n downloads: number;\n skill: Skill;\n}\n\nexport interface PublishSkillDto {\n skillId: string;\n publisherName?: string;\n}\n\n// API Response types\nexport interface ApiResponse<T = any> {\n success: boolean;\n data?: T;\n error?: string;\n code?: string;\n}\n\nexport interface UpdateCheckResponse {\n hasUpdate: boolean;\n currentHash: string | null;\n remoteHash: string | null;\n message?: string;\n}\n\nexport interface PaginatedResponse<T> {\n items: T[];\n total: number;\n page: number;\n pageSize: number;\n}\n\n// Error types\nexport const ErrorCode = {\n VALIDATION_ERROR: 'VALIDATION_ERROR',\n NOT_FOUND: 'NOT_FOUND',\n ALREADY_EXISTS: 'ALREADY_EXISTS',\n INTERNAL_ERROR: 'INTERNAL_ERROR',\n GIT_ERROR: 'GIT_ERROR',\n FILE_SYSTEM_ERROR: 'FILE_SYSTEM_ERROR',\n PERMISSION_ERROR: 'PERMISSION_ERROR',\n SYMLINK_ERROR: 'SYMLINK_ERROR',\n} as const;\n\nexport type ErrorCode = typeof ErrorCode[keyof typeof ErrorCode];\n\nexport interface ApiError {\n code: ErrorCode;\n message: string;\n details?: any;\n}\n\n// Statistics types\nexport interface DashboardStats {\n totalSkills: number;\n totalWorkspaces: number;\n totalLinks: number;\n marketplaceSkills: number;\n recentSkills: Skill[];\n}\n","import { Request, Response, NextFunction } from 'express';\nimport { ErrorCode } from '@skillverse/shared';\n\nexport class AppError extends Error {\n constructor(\n public code: ErrorCode,\n message: string,\n public statusCode: number = 500,\n public details?: any\n ) {\n super(message);\n this.name = 'AppError';\n }\n}\n\nexport function errorHandler(\n err: Error | AppError,\n req: Request,\n res: Response,\n next: NextFunction\n) {\n console.error('Error:', err);\n\n if (err instanceof AppError) {\n return res.status(err.statusCode).json({\n success: false,\n error: err.message,\n code: err.code,\n details: err.details,\n });\n }\n\n // Handle other errors\n return res.status(500).json({\n success: false,\n error: 'Internal server error',\n code: ErrorCode.INTERNAL_ERROR,\n message: process.env.NODE_ENV === 'development' ? err.message : undefined,\n });\n}\n","import { join, basename } from 'path';\nimport { existsSync } from 'fs';\nimport { mkdir, rm, cp, readFile, unlink } from 'fs/promises';\nimport matter from 'gray-matter';\nimport simpleGit from 'simple-git';\nimport AdmZip from 'adm-zip';\nimport { prisma } from '../lib/db.js';\nimport { AppError } from '../middleware/errorHandler.js';\nimport { ErrorCode } from '@skillverse/shared';\n\n// Helper to get current paths dynamically from environment\n// These are set by setupEnvironment() in config.ts\nconst getPaths = () => {\n const home = process.env.SKILLVERSE_HOME || join(process.env.HOME || '', '.skillverse');\n return {\n home,\n skills: process.env.SKILLS_DIR || join(home, 'skills'),\n temp: process.env.TEMP_DIR || join(home, 'temp')\n };\n};\n\n// Helper to parse Git URL and subdirectory\nfunction parseGitUrl(url: string): { repoUrl: string; subdir?: string; skillName: string } {\n // Handle simple URL: https://github.com/owner/repo\n if (!url.includes('/tree/')) {\n const urlParts = url.split('/');\n const repoName = urlParts[urlParts.length - 1].replace('.git', '');\n return { repoUrl: url, skillName: repoName };\n }\n\n // Handle URL with tree/subdir: https://github.com/owner/repo/tree/main/path/to/skill\n // Note: This logic is specific to GitHub URLs structure\n const parts = url.split('/tree/');\n const repoUrl = parts[0] + (parts[0].endsWith('.git') ? '' : '.git');\n\n // parts[1] is like \"main/path/to/skill\"\n // We need to support branch names that might contain slashes, but for MVP standard GitHub URLs\n // usually have the branch as the first segment after /tree/\n const pathParts = parts[1].split('/');\n const branch = pathParts[0]; // Assume first part is branch for now\n const subdir = pathParts.slice(1).join('/');\n const skillName = pathParts[pathParts.length - 1];\n\n return { repoUrl, subdir, skillName };\n}\n\nexport class SkillService {\n async getAllSkills() {\n const skills = await prisma.skill.findMany({\n include: {\n linkedWorkspaces: {\n include: {\n workspace: true,\n },\n },\n marketplaceEntry: true,\n },\n orderBy: {\n installDate: 'desc',\n },\n });\n\n return skills;\n }\n\n async getSkillById(id: string) {\n const skill = await prisma.skill.findUnique({\n where: { id },\n include: {\n linkedWorkspaces: {\n include: {\n workspace: true,\n },\n },\n marketplaceEntry: true,\n },\n });\n\n if (!skill) {\n throw new AppError(ErrorCode.NOT_FOUND, 'Skill not found', 404);\n }\n\n return skill;\n }\n\n async getSkillByName(name: string) {\n const skill = await prisma.skill.findUnique({\n where: { name },\n include: {\n linkedWorkspaces: {\n include: {\n workspace: true,\n },\n },\n marketplaceEntry: true,\n },\n });\n\n if (!skill) {\n throw new AppError(ErrorCode.NOT_FOUND, `Skill \"${name}\" not found`, 404);\n }\n\n return skill;\n }\n\n private async parseSkillMetadata(skillPath: string): Promise<{ description: string; metadata: any }> {\n try {\n const skillMdPath = join(skillPath, 'SKILL.md');\n\n let description = '';\n let metadata: any = {};\n\n if (existsSync(skillMdPath)) {\n const fileContent = await readFile(skillMdPath, 'utf-8');\n const parsed = matter(fileContent);\n\n // Use description from frontmatter or from first paragraph of body?\n // Prioritize frontmatter\n description = parsed.data.description || '';\n metadata = parsed.data;\n }\n\n // Fallback to package.json or skill.json if no description\n if (!description) {\n const packageJsonPath = join(skillPath, 'package.json');\n const skillJsonPath = join(skillPath, 'skill.json');\n\n if (existsSync(skillJsonPath)) {\n const content = await readFile(skillJsonPath, 'utf-8');\n const json = JSON.parse(content);\n description = json.description || '';\n metadata = { ...metadata, ...json };\n } else if (existsSync(packageJsonPath)) {\n const content = await readFile(packageJsonPath, 'utf-8');\n const pkg = JSON.parse(content);\n description = pkg.description || '';\n metadata = { ...metadata, name: pkg.name, version: pkg.version };\n }\n }\n\n return { description, metadata };\n } catch (error) {\n console.warn('Failed to parse skill metadata:', error);\n return { description: '', metadata: {} };\n }\n }\n\n async createSkillFromGit(gitUrl: string, description?: string) {\n let tempPath: string | null = null;\n\n try {\n // Parse URL\n const { repoUrl, subdir, skillName } = parseGitUrl(gitUrl);\n\n // Check if skill already exists\n const existingSkill = await prisma.skill.findUnique({\n where: { name: skillName },\n });\n\n if (existingSkill) {\n throw new AppError(ErrorCode.ALREADY_EXISTS, `Skill \"${skillName}\" already exists`, 409);\n }\n\n const { skills: skillsDir, temp: tempDir } = getPaths();\n\n // Prepare directories\n const skillPath = join(skillsDir, skillName);\n if (existsSync(skillPath)) {\n throw new AppError(ErrorCode.ALREADY_EXISTS, `Skill directory \"${skillName}\" already exists`, 409);\n }\n\n let commitHash = '';\n\n if (subdir) {\n // Clone to temp directory first for subdirectory extraction\n tempPath = join(tempDir, `git-clone-${Date.now()}`);\n await mkdir(tempPath, { recursive: true });\n\n console.log(`Cloning ${repoUrl} to temp path for extraction...`);\n const git = simpleGit();\n await git.clone(repoUrl, tempPath);\n\n // Get commit hash\n try {\n commitHash = await simpleGit(tempPath).revparse(['HEAD']);\n console.log(`Captured commit hash: ${commitHash}`);\n } catch (e) {\n console.warn('Failed to capture commit hash:', e);\n }\n\n const sourcePath = join(tempPath, subdir);\n if (!existsSync(sourcePath)) {\n throw new AppError(\n ErrorCode.GIT_ERROR,\n `Subdirectory \"${subdir}\" not found in repository`,\n 400\n );\n }\n\n // Validate skill structure (must have SKILL.md, skill.json, or package.json)\n const hasSkillMd = existsSync(join(sourcePath, 'SKILL.md'));\n const hasSkillJson = existsSync(join(sourcePath, 'skill.json'));\n const hasPackageJson = existsSync(join(sourcePath, 'package.json'));\n\n if (!hasSkillMd && !hasSkillJson && !hasPackageJson) {\n throw new AppError(\n ErrorCode.VALIDATION_ERROR,\n `Invalid skill structure: \"${subdir}\" does not contain SKILL.md, skill.json, or package.json`,\n 400\n );\n }\n\n // Move subdir content to final skill path\n await mkdir(skillPath, { recursive: true });\n await cp(sourcePath, skillPath, { recursive: true });\n\n } else {\n // Direct clone to skill path\n if (!existsSync(skillPath)) {\n await mkdir(skillPath, { recursive: true });\n }\n\n const git = simpleGit();\n console.log(`Cloning ${gitUrl} to ${skillPath}...`);\n await git.clone(gitUrl, skillPath);\n\n // Get commit hash\n try {\n commitHash = await git.cwd(skillPath).revparse(['HEAD']);\n console.log(`Captured commit hash: ${commitHash}`);\n } catch (e) {\n console.warn('Failed to capture commit hash:', e);\n }\n }\n\n // Read metadata\n const parsed = await this.parseSkillMetadata(skillPath);\n\n // Save to database\n const skill = await prisma.skill.create({\n data: {\n name: skillName,\n source: 'git',\n sourceUrl: gitUrl,\n repoUrl,\n commitHash,\n description: description || parsed.description || '',\n storagePath: skillPath,\n metadata: JSON.stringify(parsed.metadata),\n },\n });\n\n return skill;\n } catch (error: any) {\n // Cleanup on error (only if we created files but failed DB)\n // Actually we check DB first so if we fail here it's likely during git/fs ops\n // The implementation already has cleanup for tempPath in finally\n throw error;\n } finally {\n if (tempPath && existsSync(tempPath)) {\n await rm(tempPath, { recursive: true, force: true }).catch(console.error);\n }\n }\n }\n\n\n\n async createSkillFromDirectory(path: string, name?: string, description?: string) {\n if (!existsSync(path)) {\n throw new AppError(ErrorCode.FILE_SYSTEM_ERROR, `Source path not found: ${path}`, 400);\n }\n\n const { skills: skillsDir } = getPaths();\n const skillName = name || basename(path);\n const skillPath = join(skillsDir, skillName);\n\n // Check if skill already exists\n const existingSkill = await prisma.skill.findUnique({\n where: { name: skillName },\n });\n\n if (existingSkill) {\n throw new AppError(ErrorCode.ALREADY_EXISTS, `Skill \"${skillName}\" already exists`, 409);\n }\n\n if (existsSync(skillPath)) {\n throw new AppError(ErrorCode.ALREADY_EXISTS, `Skill directory \"${skillName}\" already exists`, 409);\n }\n\n try {\n // Create skill directory\n await mkdir(skillPath, { recursive: true });\n\n // Copy files\n await cp(path, skillPath, { recursive: true });\n\n // Read metadata\n const parsed = await this.parseSkillMetadata(skillPath);\n\n const skill = await prisma.skill.create({\n data: {\n name: skillName,\n source: 'local',\n description: description || parsed.description || '',\n storagePath: skillPath,\n metadata: JSON.stringify(parsed.metadata),\n },\n });\n\n return skill;\n } catch (error) {\n // Clean up\n if (existsSync(skillPath)) {\n await rm(skillPath, { recursive: true, force: true }).catch(() => { });\n }\n throw error;\n }\n }\n\n /**\n * Helper to handle cases where the archive contains a single top-level directory.\n * Moves contents up one level if that's the case.\n */\n private async stripTopLevelDirectory(targetPath: string) {\n const { readdir, rename, rmdir, stat } = await import('fs/promises');\n\n const items = await readdir(targetPath);\n\n // Ignore system files like .DS_Store\n const validItems = items.filter(i => i !== '.DS_Store' && i !== '__MACOSX');\n\n if (validItems.length === 1) {\n const topLevelItem = validItems[0];\n const topLevelPath = join(targetPath, topLevelItem);\n const stats = await stat(topLevelPath);\n\n if (stats.isDirectory()) {\n console.log(`Striping top-level directory: ${topLevelItem}`);\n\n // Move all items from subdirectory to targetPath\n const subItems = await readdir(topLevelPath);\n for (const item of subItems) {\n await rename(join(topLevelPath, item), join(targetPath, item));\n }\n\n // Remove the empty subdirectory\n await rmdir(topLevelPath);\n }\n }\n }\n\n async createSkillFromLocal(name: string, zipPath: string, description?: string) {\n const { skills: skillsDir, temp: tempDir } = getPaths();\n const skillPath = join(skillsDir, name);\n\n // Check if skill already exists\n const existingSkill = await prisma.skill.findUnique({\n where: { name },\n });\n\n if (existingSkill) {\n throw new AppError(ErrorCode.ALREADY_EXISTS, `Skill \"${name}\" already exists`, 409);\n }\n\n if (existsSync(skillPath)) {\n throw new AppError(ErrorCode.ALREADY_EXISTS, `Skill directory \"${name}\" already exists`, 409);\n }\n\n // Use a temp path for extraction to verify structure before determining final path\n const extractPath = join(tempDir, `extract-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`);\n await mkdir(extractPath, { recursive: true });\n\n try {\n const zip = new AdmZip(zipPath);\n zip.extractAllTo(extractPath, true);\n\n // Fix nested directory structure if present\n await this.stripTopLevelDirectory(extractPath);\n\n // Read metadata from the extracted files\n const parsed = await this.parseSkillMetadata(extractPath);\n\n // Now move to final destination\n // Check again to be safe against race conditions\n if (existsSync(skillPath)) {\n throw new AppError(ErrorCode.ALREADY_EXISTS, `Skill directory \"${name}\" already exists`, 409);\n }\n\n await import('fs/promises').then(fs => fs.rename(extractPath, skillPath));\n\n const skill = await prisma.skill.create({\n data: {\n name,\n source: 'local',\n description: description || parsed.description || '',\n storagePath: skillPath,\n metadata: JSON.stringify(parsed.metadata),\n },\n });\n\n return skill;\n } catch (error) {\n // Clean up final path if it was created but DB failed\n if (existsSync(skillPath)) {\n await rm(skillPath, { recursive: true, force: true }).catch(() => { });\n }\n // Clean up temp path if it still exists\n if (existsSync(extractPath)) {\n await rm(extractPath, { recursive: true, force: true }).catch(() => { });\n }\n throw error;\n }\n }\n\n /**\n * Create a skill from a tar.gz bundle (marketplace install)\n * @param bundlePath - Path to the .tar.gz bundle\n * @param originalName - Original skill name\n * @param description - Optional skill description\n */\n async createSkillFromBundle(bundlePath: string, originalName: string, description?: string) {\n // Generate a unique name to avoid conflicts\n let name = originalName;\n let counter = 1;\n while (await prisma.skill.findUnique({ where: { name } })) {\n name = `${originalName}-${counter}`;\n counter++;\n }\n\n const { skills: skillsDir, temp: tempDir } = getPaths();\n const skillPath = join(skillsDir, name);\n\n // Use a temp path for extraction\n const extractPath = join(tempDir, `extract-bundle-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`);\n await mkdir(extractPath, { recursive: true });\n\n try {\n // Extract bundle using tar\n const { createReadStream } = await import('fs');\n const { createGunzip } = await import('zlib');\n const tar = await import('tar');\n const { pipeline } = await import('stream/promises');\n\n await pipeline(\n createReadStream(bundlePath),\n createGunzip(),\n tar.extract({ cwd: extractPath })\n );\n\n // Fix nested directory structure if present\n await this.stripTopLevelDirectory(extractPath);\n\n // Read metadata from extracted files\n const parsed = await this.parseSkillMetadata(extractPath);\n\n // Check again for existence before moving\n if (existsSync(skillPath)) {\n throw new AppError(ErrorCode.ALREADY_EXISTS, `Skill directory \"${name}\" already exists`, 409);\n }\n\n await import('fs/promises').then(fs => fs.rename(extractPath, skillPath));\n\n const skill = await prisma.skill.create({\n data: {\n name,\n source: 'local',\n description: description || parsed.description || '',\n storagePath: skillPath,\n metadata: JSON.stringify(parsed.metadata),\n },\n });\n\n console.log(`📦 Installed skill \"${name}\" from bundle`);\n return skill;\n } catch (error) {\n // Clean up final path if it was created but DB failed\n if (existsSync(skillPath)) {\n await rm(skillPath, { recursive: true, force: true }).catch(() => { });\n }\n // Clean up temp path if it still exists\n if (existsSync(extractPath)) {\n await rm(extractPath, { recursive: true, force: true }).catch(() => { });\n }\n throw error;\n }\n }\n\n async updateSkill(id: string, data: { name?: string; description?: string; metadata?: any }) {\n const skill = await this.getSkillById(id);\n\n const updatedSkill = await prisma.skill.update({\n where: { id },\n data: {\n ...(data.name && { name: data.name }),\n ...(data.description !== undefined && { description: data.description }),\n ...(data.metadata && { metadata: JSON.stringify(data.metadata) }),\n },\n });\n\n return updatedSkill;\n }\n\n async deleteSkill(id: string, removeFiles: boolean = true) {\n const skill = await this.getSkillById(id);\n\n // Remove symlinks from linked workspaces\n if (skill.linkedWorkspaces && skill.linkedWorkspaces.length > 0) {\n for (const link of skill.linkedWorkspaces) {\n try {\n const workspacePath = link.workspace.path;\n const symlinkPath = join(workspacePath, skill.name);\n\n if (existsSync(symlinkPath)) {\n // Check if it is indeed a symlink to be safe\n const stats = await import('fs/promises').then(fs => fs.lstat(symlinkPath));\n if (stats.isSymbolicLink()) {\n await unlink(symlinkPath);\n console.log(`Removed symlink for ${skill.name} in workspace ${workspacePath}`);\n }\n }\n } catch (error) {\n console.warn(`Failed to remove symlink for ${skill.name} in workspace ${link.workspace.path}:`, error);\n }\n }\n }\n\n await prisma.skill.delete({\n where: { id },\n });\n\n if (removeFiles && skill.storagePath) {\n await rm(skill.storagePath, { recursive: true, force: true }).catch(err => {\n console.warn(`Failed to delete skill directory ${skill.storagePath}:`, err);\n });\n }\n\n return { success: true, message: 'Skill deleted successfully' };\n }\n\n // Check for updates\n async checkForUpdate(id: string) {\n const skill = await this.getSkillById(id);\n\n if (skill.source !== 'git' || !skill.repoUrl) {\n return {\n hasUpdate: false,\n currentHash: skill.commitHash,\n remoteHash: null,\n message: 'Not a git skill or missing repo URL',\n };\n }\n\n const { temp: tempDir } = getPaths();\n const tempPath = join(tempDir, `check-update-${Date.now()}`);\n await mkdir(tempPath, { recursive: true });\n\n try {\n const git = simpleGit();\n // We only need to check the remote HEAD, no need to full clone\n // But ls-remote might require authentication or be tricky with some hosts\n // Safer to shallow clone to temp\n console.log(`Checking updates for ${skill.name} from ${skill.repoUrl}...`);\n\n // Parse original git URL to get branch if possible, or just HEAD\n // For now, assume main/HEAD of the repoUrl\n const remote = await git.listRemote([skill.repoUrl, 'HEAD']);\n if (!remote) {\n throw new Error('Failed to get remote HEAD');\n }\n\n // remote is like \"hash\\tHEAD\"\n const remoteHash = remote.split('\\t')[0];\n const hasUpdate = remoteHash !== skill.commitHash;\n\n // Update DB with check result\n await prisma.skill.update({\n where: { id },\n data: {\n lastUpdateCheck: new Date(),\n updateAvailable: hasUpdate,\n },\n });\n\n return {\n hasUpdate,\n currentHash: skill.commitHash,\n remoteHash,\n };\n } catch (error: any) {\n console.error('Update check error:', error);\n throw new AppError(ErrorCode.GIT_ERROR, `Failed to check for updates: ${error.message}`, 500);\n } finally {\n await rm(tempPath, { recursive: true, force: true }).catch(() => { });\n }\n }\n\n async checkUpdates(ids?: string[]) {\n // Check all git skills\n const whereClause: any = {\n source: 'git',\n repoUrl: { not: null },\n };\n\n if (ids && ids.length > 0) {\n whereClause.id = { in: ids };\n }\n\n const skills = await prisma.skill.findMany({ where: whereClause });\n const results: Record<string, any> = {};\n\n // Limit concurrency to avoid hammering network/git\n // For now simple serial or Promise.all\n console.log(`Checking updates for ${skills.length} skills...`);\n\n await Promise.all(skills.map(async (skill: any) => {\n try {\n const result = await this.checkForUpdate(skill.id);\n results[skill.id] = result;\n } catch (e) {\n results[skill.id] = { error: (e as Error).message };\n }\n }));\n\n return results;\n }\n\n async refreshMetadata(id: string) {\n const skill = await this.getSkillById(id);\n const parsed = await this.parseSkillMetadata(skill.storagePath);\n\n const updated = await prisma.skill.update({\n where: { id },\n data: {\n description: parsed.description,\n metadata: JSON.stringify(parsed.metadata),\n }\n });\n\n return updated;\n }\n\n async upgradeSkill(id: string) {\n const skill = await this.getSkillById(id);\n\n if (skill.source !== 'git' || !skill.sourceUrl) {\n throw new AppError(ErrorCode.VALIDATION_ERROR, 'Cannot upgrade non-git skill', 400);\n }\n\n // Reuse createSkillFromGit logic but force update\n // Since createSkillFromGit checks for existing skill, we need to adapt it\n // Or just manually do the steps here:\n // 1. Download new version to temp\n // 2. Validate\n // 3. Replace files\n // 4. Update DB\n\n let tempPath: string | null = null;\n let tempSkillPath: string | null = null;\n\n try {\n const { repoUrl, subdir } = parseGitUrl(skill.sourceUrl);\n\n const { temp: tempDir } = getPaths();\n tempPath = join(tempDir, `upgrade-${Date.now()}`);\n await mkdir(tempPath, { recursive: true });\n\n const git = simpleGit();\n console.log(`Cloning ${repoUrl} to temp for upgrade...`);\n await git.clone(repoUrl, tempPath);\n\n let commitHash = '';\n try {\n commitHash = await simpleGit(tempPath).revparse(['HEAD']);\n } catch (e) {\n console.warn('Failed to capture commit hash during upgrade:', e);\n }\n\n let sourcePath = tempPath;\n if (subdir) {\n sourcePath = join(tempPath, subdir);\n if (!existsSync(sourcePath)) {\n throw new AppError(ErrorCode.GIT_ERROR, `Subdirectory \"${subdir}\" not found`, 400);\n }\n }\n\n // Validate structure\n const hasSkillMd = existsSync(join(sourcePath, 'SKILL.md'));\n const hasSkillJson = existsSync(join(sourcePath, 'skill.json'));\n const hasPackageJson = existsSync(join(sourcePath, 'package.json'));\n\n if (!hasSkillMd && !hasSkillJson && !hasPackageJson) {\n throw new AppError(ErrorCode.VALIDATION_ERROR, 'Invalid skill structure in new version', 400);\n }\n\n // Validated. Now replace files.\n // We should be careful not to delete user configs if any, but for now we do full replace\n // except maybe keeping some local files? For MVP, full replace.\n\n // Clear existing directory content\n const files = await import('fs/promises').then(fs => fs.readdir(skill.storagePath));\n for (const file of files) {\n await rm(join(skill.storagePath, file), { recursive: true, force: true });\n }\n\n // Copy new files\n await cp(sourcePath, skill.storagePath, { recursive: true });\n\n // Parse new metadata after upgrade\n const parsed = await this.parseSkillMetadata(skill.storagePath);\n\n // Update DB\n const updatedSkill = await prisma.skill.update({\n where: { id },\n data: {\n commitHash,\n updateAvailable: false,\n lastUpdateCheck: new Date(),\n installDate: new Date(), // Considering upgrade as reinstall? Or user prefer generic updatedAt\n // Keeping installDate as \"last installed/upgraded\"\n description: parsed.description,\n metadata: JSON.stringify(parsed.metadata),\n },\n });\n\n return updatedSkill;\n\n } catch (error: any) {\n console.error('Upgrade error:', error);\n throw new AppError(ErrorCode.GIT_ERROR, `Failed to upgrade skill: ${error.message}`, 500);\n } finally {\n if (tempPath) await rm(tempPath, { recursive: true, force: true }).catch(() => { });\n }\n }\n /**\n * Sync skills between filesystem and database:\n * 1. Remove orphaned database records (skills in DB but not on disk)\n * 2. Import new skills from disk (skills on disk but not in DB)\n */\n async syncSkillsWithFileSystem() {\n const { skills: skillsDir } = getPaths();\n\n // 1. First, clean up orphaned database records\n const dbSkills = await prisma.skill.findMany();\n let removedCount = 0;\n\n for (const skill of dbSkills) {\n if (!existsSync(skill.storagePath)) {\n console.log(`🗑️ Removing orphaned skill from database: ${skill.name} (path: ${skill.storagePath})`);\n try {\n await prisma.skill.delete({ where: { id: skill.id } });\n removedCount++;\n } catch (error) {\n console.error(`Failed to remove orphaned skill ${skill.name}:`, error);\n }\n }\n }\n\n if (removedCount > 0) {\n console.log(`✅ Removed ${removedCount} orphaned skill(s) from database.`);\n }\n\n // 2. Then, import new skills from disk\n const importedCount = await this.scanForSkills();\n\n return { removedCount, importedCount: importedCount || 0 };\n }\n\n async scanForSkills() {\n const { skills: skillsDir } = getPaths();\n console.log(`Scanning for skills in ${skillsDir}...`);\n\n if (!existsSync(skillsDir)) {\n console.log('Skills directory does not exist, skipping scan.');\n return;\n }\n\n const entries = await import('fs/promises').then(fs => fs.readdir(skillsDir, { withFileTypes: true }));\n const directories = entries.filter(entry => entry.isDirectory()).map(entry => entry.name);\n\n console.log(`Found ${directories.length} directories in skills folder.`);\n\n let importedCount = 0;\n\n for (const dirName of directories) {\n const skillPath = join(skillsDir, dirName);\n\n // Check if already in DB\n const existingSkill = await prisma.skill.findUnique({\n where: { name: dirName },\n });\n\n if (existingSkill) {\n // Optional: Update storage path if it changed? \n // For now, assume if name matches, it's the same skill.\n continue;\n }\n\n // Check if valid skill\n const hasSkillMd = existsSync(join(skillPath, 'SKILL.md'));\n const hasPackageJson = existsSync(join(skillPath, 'package.json'));\n const hasSkillJson = existsSync(join(skillPath, 'skill.json'));\n\n if (!hasSkillMd && !hasPackageJson && !hasSkillJson) {\n console.log(`Skipping ${dirName}: No skill metadata found.`);\n continue;\n }\n\n try {\n console.log(`Importing skill: ${dirName}`);\n const parsed = await this.parseSkillMetadata(skillPath);\n\n // Determine source type - heuristic\n let source = 'local';\n let sourceUrl = undefined;\n let repoUrl = undefined;\n let commitHash = undefined;\n\n // Try to detect git info if .git exists\n if (existsSync(join(skillPath, '.git'))) {\n source = 'git';\n try {\n const git = simpleGit(skillPath);\n const remotes = await git.getRemotes(true);\n if (remotes.length > 0) {\n sourceUrl = remotes[0].refs.fetch;\n repoUrl = sourceUrl;\n }\n commitHash = await git.revparse(['HEAD']);\n } catch (e) {\n console.warn(`Failed to read git info for ${dirName}:`, e);\n }\n }\n\n await prisma.skill.create({\n data: {\n name: dirName,\n source,\n sourceUrl,\n repoUrl,\n commitHash,\n description: parsed.description,\n storagePath: skillPath,\n metadata: JSON.stringify(parsed.metadata),\n },\n });\n importedCount++;\n } catch (error) {\n console.error(`Failed to import skill ${dirName}:`, error);\n }\n }\n\n console.log(`Scan complete. Imported ${importedCount} new skills.`);\n return importedCount;\n }\n}\n\nexport const skillService = new SkillService();\n","import express from 'express';\nimport cors from 'cors';\nimport dotenv from 'dotenv';\nimport { fileURLToPath } from 'url';\nimport { dirname, join } from 'path';\nimport { mkdir } from 'fs/promises';\nimport { existsSync } from 'fs';\n\n// Load environment variables\ndotenv.config();\n\n// Import routes\nimport skillRoutes from './routes/skills.js';\nimport workspaceRoutes from './routes/workspaces.js';\nimport marketplaceRoutes from './routes/marketplace.js';\nimport dashboardRoutes from './routes/dashboard.js';\nimport configRoutes from './routes/config.js';\n\n// Import middleware\nimport { errorHandler } from './middleware/errorHandler.js';\nimport { requestLogger } from './middleware/logger.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nconst app = express();\nconst PORT = process.env.PORT || 3001;\n\n// Middleware\napp.use(cors());\napp.use(express.json());\napp.use(express.urlencoded({ extended: true }));\napp.use(requestLogger);\n\n// Serve static files from 'public' directory (shared with client build)\n// In tsx mode: __dirname is server/src, so ../../public doesn't exist\n// In compiled mode: __dirname is server/dist, so ../public works\n// We try multiple paths to support both modes\nconst possiblePublicDirs = [\n join(__dirname, '../public'), // Production: dist/index.js -> public\n join(__dirname, '../../public'), // Dev tsx might resolve here \n join(process.cwd(), 'public'), // Fallback: relative to cwd\n join(process.cwd(), 'server/public'), // Fallback: from root\n];\n\nconst publicDir = possiblePublicDirs.find(dir => existsSync(dir));\nif (publicDir) {\n app.use(express.static(publicDir));\n console.log(`📂 Serving static files from: ${publicDir}`);\n} else {\n console.warn('⚠️ No public directory found. Run \"npm run build\" in client first.');\n}\n\n// Routes\napp.use('/api/skills', skillRoutes);\napp.use('/api/workspaces', workspaceRoutes);\napp.use('/api/marketplace', marketplaceRoutes);\napp.use('/api/dashboard', dashboardRoutes);\napp.use('/api/config', configRoutes);\n\n// Health check\napp.get('/health', (req, res) => {\n res.json({ status: 'ok', timestamp: new Date().toISOString() });\n});\n\n// Serve index.html for all other routes (SPA support)\n// Only if public dir exists, otherwise we might be in dev mode without build\nif (publicDir && existsSync(publicDir)) {\n app.get('*', (req, res) => {\n res.sendFile(join(publicDir, 'index.html'));\n });\n}\n\n// Error handling\napp.use(errorHandler);\n\n// Initialize storage directories\nasync function initializeStorage() {\n const skillverseHome = process.env.SKILLVERSE_HOME || join(process.env.HOME || '', '.skillverse');\n const skillsDir = process.env.SKILLS_DIR || join(skillverseHome, 'skills');\n const marketplaceDir = process.env.MARKETPLACE_DIR || join(skillverseHome, 'marketplace');\n\n const dirs = [skillverseHome, skillsDir, marketplaceDir];\n\n for (const dir of dirs) {\n if (!existsSync(dir)) {\n await mkdir(dir, { recursive: true });\n console.log(`Created directory: ${dir}`);\n }\n }\n}\n\nimport { ensureDatabaseInitialized } from './lib/initDb.js';\n\n// Start server\nexport async function startServer(port: number = 3001) {\n try {\n await initializeStorage();\n await ensureDatabaseInitialized();\n\n // Initial sync: scan for new skills and clean up orphaned records\n console.log('🔍 Syncing skills with filesystem...');\n const { skillService } = await import('./services/skillService.js');\n await skillService.syncSkillsWithFileSystem();\n\n return new Promise<void>((resolve) => {\n app.listen(port, () => {\n console.log(`🚀 SkillVerse server running on http://localhost:${port}`);\n console.log(`📁 Storage: ${process.env.SKILLVERSE_HOME || join(process.env.HOME || '', '.skillverse')}`);\n resolve();\n });\n });\n } catch (error) {\n console.error('Failed to start server:', error);\n process.exit(1);\n }\n}\n\n// Auto-start if run directly\nif (process.argv[1] === fileURLToPath(import.meta.url)) {\n startServer();\n}\n","import { Router, Request, Response, NextFunction } from 'express';\nimport multer from 'multer';\nimport { join } from 'path';\nimport { existsSync } from 'fs';\nimport { mkdir, rm } from 'fs/promises';\nimport { skillService } from '../services/skillService.js';\nimport { workspaceService } from '../services/workspaceService.js';\n\nconst router = Router();\n\n// Configure multer for file uploads\nconst TEMP_DIR = process.env.TEMP_DIR || join(process.env.HOME || '', '.skillverse', 'temp');\n\n// Ensure temp directory exists\nif (!existsSync(TEMP_DIR)) {\n mkdir(TEMP_DIR, { recursive: true });\n}\n\nconst storage = multer.diskStorage({\n destination: (req, file, cb) => {\n cb(null, TEMP_DIR);\n },\n filename: (req, file, cb) => {\n const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9);\n cb(null, uniqueSuffix + '-' + file.originalname);\n },\n});\n\nconst upload = multer({\n storage,\n limits: {\n fileSize: 100 * 1024 * 1024, // 100MB limit\n },\n fileFilter: (req, file, cb) => {\n if (file.mimetype === 'application/zip' || file.originalname.endsWith('.zip')) {\n cb(null, true);\n } else {\n cb(new Error('Only ZIP files are allowed'));\n }\n },\n});\n\n// GET /api/skills - Get all skills\nrouter.get('/', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const skills = await skillService.getAllSkills();\n res.json({\n success: true,\n data: skills,\n });\n } catch (error) {\n next(error);\n }\n});\n\n// POST /api/skills/sync - Sync skills with filesystem (clean orphans + import new)\nrouter.post('/sync', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const result = await skillService.syncSkillsWithFileSystem();\n res.json({\n success: true,\n data: result,\n message: `Synced: removed ${result.removedCount} orphan(s), imported ${result.importedCount} new skill(s)`,\n });\n } catch (error) {\n next(error);\n }\n});\n\n// GET /api/skills/:id - Get skill by ID\nrouter.get('/:id', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const skill = await skillService.getSkillById(req.params.id);\n res.json({\n success: true,\n data: skill,\n });\n } catch (error) {\n next(error);\n }\n});\n\n// POST /api/skills/from-git - Create skill from Git repository\nrouter.post('/from-git', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const { gitUrl, description } = req.body;\n\n if (!gitUrl) {\n return res.status(400).json({\n success: false,\n error: 'gitUrl is required',\n });\n }\n\n const skill = await skillService.createSkillFromGit(gitUrl, description);\n res.status(201).json({\n success: true,\n data: skill,\n message: 'Skill created successfully from Git repository',\n });\n } catch (error) {\n next(error);\n }\n});\n\n// POST /api/skills/from-local - Create skill from local ZIP file\nrouter.post(\n '/from-local',\n upload.single('file'),\n async (req: Request, res: Response, next: NextFunction) => {\n try {\n const { name, description } = req.body;\n const file = req.file;\n\n if (!name) {\n // Clean up uploaded file\n if (file) {\n await rm(file.path, { force: true });\n }\n return res.status(400).json({\n success: false,\n error: 'name is required',\n });\n }\n\n if (!file) {\n return res.status(400).json({\n success: false,\n error: 'ZIP file is required',\n });\n }\n\n const skill = await skillService.createSkillFromLocal(name, file.path, description);\n\n // Clean up temp file\n await rm(file.path, { force: true });\n\n res.status(201).json({\n success: true,\n data: skill,\n message: 'Skill created successfully from local file',\n });\n } catch (error) {\n // Clean up uploaded file on error\n if (req.file) {\n await rm(req.file.path, { force: true }).catch(() => { });\n }\n next(error);\n }\n }\n);\n\n// PUT /api/skills/:id - Update skill\nrouter.put('/:id', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const { name, description, metadata } = req.body;\n const skill = await skillService.updateSkill(req.params.id, {\n name,\n description,\n metadata,\n });\n res.json({\n success: true,\n data: skill,\n message: 'Skill updated successfully',\n });\n } catch (error) {\n next(error);\n }\n});\n\n// DELETE /api/skills/:id - Delete skill\nrouter.delete('/:id', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const removeFiles = req.query.removeFiles !== 'false';\n const result = await skillService.deleteSkill(req.params.id, removeFiles);\n res.json(result);\n } catch (error) {\n next(error);\n }\n});\n\n// POST /api/skills/:id/link - Link skill to workspace\nrouter.post('/:id/link', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const { workspaceId } = req.body;\n\n if (!workspaceId) {\n return res.status(400).json({\n success: false,\n error: 'workspaceId is required',\n });\n }\n\n const link = await workspaceService.linkSkillToWorkspace(req.params.id, workspaceId);\n res.status(201).json({\n success: true,\n data: link,\n message: 'Skill linked to workspace successfully',\n });\n } catch (error) {\n next(error);\n }\n});\n\n// DELETE /api/skills/:id/unlink/:workspaceId - Unlink skill from workspace\nrouter.delete(\n '/:id/unlink/:workspaceId',\n async (req: Request, res: Response, next: NextFunction) => {\n try {\n const result = await workspaceService.unlinkSkillFromWorkspace(\n req.params.id,\n req.params.workspaceId\n );\n res.json(result);\n } catch (error) {\n next(error);\n }\n }\n);\n\n// GET /api/skills/:id/check-update - Check for updates\nrouter.get('/:id/check-update', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const result = await skillService.checkForUpdate(req.params.id);\n res.json({\n success: true,\n data: result,\n });\n } catch (error) {\n next(error);\n }\n});\n\n// POST /api/skills/:id/upgrade - Upgrade skill\nrouter.post('/:id/upgrade', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const skill = await skillService.upgradeSkill(req.params.id);\n res.json({\n success: true,\n data: skill,\n message: 'Skill upgraded successfully',\n });\n } catch (error) {\n next(error);\n }\n});\n\n// POST /api/skills/check-updates - Check for updates for multiple skills\nrouter.post('/check-updates', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const { ids } = req.body; // Optional: ids array to check specific skills\n const results = await skillService.checkUpdates(ids);\n res.json({\n success: true,\n data: results,\n });\n } catch (error) {\n next(error);\n }\n});\n\n// POST /api/skills/:id/refresh-metadata - Refresh skill metadata\nrouter.post('/:id/refresh-metadata', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const skill = await skillService.refreshMetadata(req.params.id);\n res.json({\n success: true,\n data: skill,\n message: 'Metadata refreshed successfully',\n });\n } catch (error) {\n next(error);\n }\n});\n\n// GET /api/skills/:id/skill-md - Get SKILL.md content for preview\nrouter.get('/:id/skill-md', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const { readFile } = await import('fs/promises');\n const skill = await skillService.getSkillById(req.params.id);\n const skillMdPath = join(skill.storagePath, 'SKILL.md');\n\n if (!existsSync(skillMdPath)) {\n return res.json({\n success: true,\n data: {\n exists: false,\n content: null,\n },\n });\n }\n\n const content = await readFile(skillMdPath, 'utf-8');\n res.json({\n success: true,\n data: {\n exists: true,\n content,\n },\n });\n } catch (error) {\n next(error);\n }\n});\n\nexport default router;\n\n","import { join } from 'path';\nimport { homedir } from 'os';\nimport { symlink, unlink, rm, mkdir, appendFile, readFile } from 'fs/promises';\nimport { existsSync, lstatSync } from 'fs';\nimport { prisma } from '../lib/db.js';\nimport { AppError } from '../middleware/errorHandler.js';\nimport { ErrorCode, WorkspaceType, WorkspaceScope, WORKSPACE_SKILLS_PATHS } from '@skillverse/shared';\n\n/**\n * Compute the final skills path based on project path, type, and scope\n */\nfunction computeSkillsPath(projectPath: string, type: WorkspaceType, scope: WorkspaceScope): string {\n const pathConfig = WORKSPACE_SKILLS_PATHS[type];\n\n if (scope === 'global') {\n // Global path: replace ~ with actual home directory\n return pathConfig.global.replace('~', homedir());\n }\n\n // Project path = projectPath + sub-directory\n return join(projectPath, pathConfig.project);\n}\n\nexport class WorkspaceService {\n /**\n * Helper to get expected skills path for a project\n */\n getSkillsPath(projectPath: string, type: WorkspaceType, scope: WorkspaceScope): string {\n return computeSkillsPath(projectPath, type, scope);\n }\n\n /**\n * Sync database links with filesystem state\n * Removes links from DB if the symlink is missing from the workspace\n */\n private async syncLinks(workspace: any) {\n if (!workspace.linkedSkills || workspace.linkedSkills.length === 0) return;\n\n for (const link of workspace.linkedSkills) {\n if (!link.skill) continue;\n\n const linkPath = join(workspace.path, link.skill.name);\n\n // Check if symlink exists\n if (!existsSync(linkPath)) {\n console.log(`Link missing for skill \"${link.skill.name}\" in workspace \"${workspace.name}\". Removing from DB.`);\n try {\n await prisma.skillWorkspace.delete({\n where: { id: link.id },\n });\n // Update the in-memory object so the returned response is correct\n workspace.linkedSkills = workspace.linkedSkills.filter((l: any) => l.id !== link.id);\n } catch (err) {\n console.error(`Failed to sync link for ${link.skill.name}:`, err);\n }\n }\n }\n }\n\n async findWorkspaceByPath(path: string) {\n const workspace = await prisma.workspace.findUnique({\n where: { path },\n include: {\n linkedSkills: {\n include: {\n skill: true,\n },\n },\n },\n });\n return workspace;\n }\n\n async getAllWorkspaces() {\n const workspaces = await prisma.workspace.findMany({\n include: {\n linkedSkills: {\n include: {\n skill: true,\n },\n },\n },\n orderBy: {\n createdAt: 'desc',\n },\n });\n\n // Sync links for all workspaces (in parallel)\n await Promise.all(workspaces.map(w => this.syncLinks(w)));\n\n // Add isPathValid status for each workspace\n return workspaces.map(workspace => ({\n ...workspace,\n isPathValid: existsSync(workspace.path),\n }));\n }\n\n async getWorkspaceById(id: string) {\n const workspace = await prisma.workspace.findUnique({\n where: { id },\n include: {\n linkedSkills: {\n include: {\n skill: true,\n },\n },\n },\n });\n\n if (!workspace) {\n throw new AppError(ErrorCode.NOT_FOUND, 'Workspace not found', 404);\n }\n\n // Sync links with filesystem\n await this.syncLinks(workspace);\n\n return {\n ...workspace,\n isPathValid: existsSync(workspace.path),\n };\n }\n\n async createWorkspace(name: string, projectPath: string, type: WorkspaceType, scope: WorkspaceScope) {\n // Compute the final skills path\n const skillsPath = computeSkillsPath(projectPath, type, scope);\n\n // For project scope, check if project path exists\n if (scope === 'project' && projectPath && !existsSync(projectPath)) {\n throw new AppError(ErrorCode.FILE_SYSTEM_ERROR, `Project path does not exist: ${projectPath}`, 400);\n }\n\n // Auto-create skills directory if it doesn't exist\n if (!existsSync(skillsPath)) {\n try {\n await mkdir(skillsPath, { recursive: true });\n } catch (err: any) {\n throw new AppError(\n ErrorCode.FILE_SYSTEM_ERROR,\n `Failed to create skills directory: ${err.message}`,\n 500\n );\n }\n }\n\n // Check if workspace already exists at this path\n const existingWorkspace = await prisma.workspace.findUnique({\n where: { path: skillsPath },\n });\n\n if (existingWorkspace) {\n throw new AppError(ErrorCode.ALREADY_EXISTS, 'Workspace already exists at this path', 409);\n }\n\n const workspace = await prisma.workspace.create({\n data: {\n name,\n path: skillsPath,\n type,\n scope,\n },\n });\n\n // For project scope, try to add skills directory to .gitignore\n if (scope === 'project' && projectPath && existsSync(projectPath)) {\n try {\n const gitignorePath = join(projectPath, '.gitignore');\n const relativeSkillsPath = WORKSPACE_SKILLS_PATHS[type].project;\n\n let shouldAppend = false;\n\n if (existsSync(gitignorePath)) {\n const content = await readFile(gitignorePath, 'utf-8');\n // Check if path is already ignored (simple check)\n if (!content.includes(relativeSkillsPath)) {\n shouldAppend = true;\n }\n } else {\n // Create .gitignore if it doesn't exist\n shouldAppend = true;\n }\n\n if (shouldAppend) {\n const ignoreEntry = `\\n\\n# SkillVerse\\n${relativeSkillsPath}/\\n`;\n await appendFile(gitignorePath, ignoreEntry);\n console.log(`Added ${relativeSkillsPath}/ to .gitignore in ${projectPath}`);\n }\n } catch (err) {\n // Non-fatal error, just log it\n console.warn('Failed to update .gitignore:', err);\n }\n }\n\n return {\n ...workspace,\n isPathValid: true,\n };\n }\n\n async updateWorkspace(id: string, data: { name?: string; path?: string; type?: WorkspaceType; scope?: WorkspaceScope }) {\n await this.getWorkspaceById(id);\n\n const workspace = await prisma.workspace.update({\n where: { id },\n data,\n });\n\n return {\n ...workspace,\n isPathValid: existsSync(workspace.path),\n };\n }\n\n async deleteWorkspace(id: string) {\n const workspace = await this.getWorkspaceById(id);\n\n // Remove all symlinks for this workspace\n const links = await prisma.skillWorkspace.findMany({\n where: { workspaceId: id },\n include: { skill: true },\n });\n\n for (const link of links) {\n try {\n const linkPath = join(workspace.path, link.skill.name);\n if (existsSync(linkPath)) {\n await rm(linkPath, { recursive: true, force: true });\n }\n } catch (error) {\n console.error(`Failed to remove symlink for ${link.skill.name}:`, error);\n }\n }\n\n // Delete workspace\n await prisma.workspace.delete({ where: { id } });\n\n return { success: true, message: 'Workspace deleted successfully' };\n }\n\n async linkSkillToWorkspace(skillId: string, workspaceId: string) {\n const skill = await prisma.skill.findUnique({ where: { id: skillId } });\n const workspace = await prisma.workspace.findUnique({ where: { id: workspaceId } });\n\n if (!skill) {\n throw new AppError(ErrorCode.NOT_FOUND, 'Skill not found', 404);\n }\n\n if (!workspace) {\n throw new AppError(ErrorCode.NOT_FOUND, 'Workspace not found', 404);\n }\n\n // Validate workspace path still exists\n if (!existsSync(workspace.path)) {\n throw new AppError(\n ErrorCode.FILE_SYSTEM_ERROR,\n `Workspace skills directory does not exist: ${workspace.path}. The folder may have been deleted. Please recreate it or remove this workspace.`,\n 400\n );\n }\n\n // Check if link already exists\n const existingLink = await prisma.skillWorkspace.findFirst({\n where: {\n skillId,\n workspaceId,\n },\n });\n\n if (existingLink) {\n throw new AppError(ErrorCode.ALREADY_EXISTS, 'Skill is already linked to this workspace', 409);\n }\n\n // Create symlink\n const targetPath = join(workspace.path, skill.name);\n\n try {\n // Remove existing file/link if it exists\n if (existsSync(targetPath)) {\n const stats = lstatSync(targetPath);\n if (stats.isSymbolicLink()) {\n await unlink(targetPath);\n } else {\n throw new AppError(\n ErrorCode.FILE_SYSTEM_ERROR,\n `A file or directory already exists at ${targetPath}`,\n 409\n );\n }\n }\n\n // Create symlink\n await symlink(skill.storagePath, targetPath, 'dir');\n\n // Record link in database\n const link = await prisma.skillWorkspace.create({\n data: {\n skillId,\n workspaceId,\n },\n include: {\n skill: true,\n workspace: true,\n },\n });\n\n return link;\n } catch (error: any) {\n if (error instanceof AppError) throw error;\n\n console.error('Symlink creation error:', error);\n throw new AppError(\n ErrorCode.SYMLINK_ERROR,\n `Failed to create symlink: ${error.message}`,\n 500,\n error\n );\n }\n }\n\n async unlinkSkillFromWorkspace(skillId: string, workspaceId: string) {\n const link = await prisma.skillWorkspace.findFirst({\n where: {\n skillId,\n workspaceId,\n },\n include: {\n skill: true,\n workspace: true,\n },\n });\n\n if (!link) {\n throw new AppError(ErrorCode.NOT_FOUND, 'Link not found', 404);\n }\n\n // Remove symlink\n const linkPath = join(link.workspace.path, link.skill.name);\n\n try {\n if (existsSync(linkPath)) {\n await rm(linkPath, { recursive: true, force: true });\n }\n\n // Remove link from database\n await prisma.skillWorkspace.delete({\n where: { id: link.id },\n });\n\n return { success: true, message: 'Skill unlinked successfully' };\n } catch (error: any) {\n console.error('Unlink error:', error);\n throw new AppError(\n ErrorCode.FILE_SYSTEM_ERROR,\n `Failed to unlink skill: ${error.message}`,\n 500,\n error\n );\n }\n }\n\n /**\n * Detect existing skills in a workspace skills directory\n * Returns list of skill names that could be migrated\n */\n async detectExistingSkills(skillsPath: string): Promise<{ name: string; hasSkillMd: boolean; path: string }[]> {\n if (!existsSync(skillsPath)) {\n return [];\n }\n\n const { readdir, stat, readFile } = await import('fs/promises');\n const items = await readdir(skillsPath);\n const existingSkills: { name: string; hasSkillMd: boolean; path: string }[] = [];\n\n for (const item of items) {\n // Skip hidden files/directories\n if (item.startsWith('.')) continue;\n\n const itemPath = join(skillsPath, item);\n try {\n const itemStat = await stat(itemPath);\n\n // Skip symlinks (already linked skills)\n const lstats = lstatSync(itemPath);\n if (lstats.isSymbolicLink()) continue;\n\n if (itemStat.isDirectory()) {\n // Check if it has SKILL.md or other skill markers\n const hasSkillMd = existsSync(join(itemPath, 'SKILL.md'));\n const hasSkillJson = existsSync(join(itemPath, 'skill.json'));\n const hasPackageJson = existsSync(join(itemPath, 'package.json'));\n\n if (hasSkillMd || hasSkillJson || hasPackageJson) {\n existingSkills.push({\n name: item,\n hasSkillMd,\n path: itemPath,\n });\n }\n }\n } catch (error) {\n console.warn(`Failed to check ${itemPath}:`, error);\n }\n }\n\n return existingSkills;\n }\n\n /**\n * Migrate existing skills from workspace to unified storage\n * 1. Move skills to ~/.skillverse/skills/\n * 2. Register in database\n * 3. Create symlinks back to workspace\n */\n async migrateExistingSkills(workspaceId: string, skillNames: string[]): Promise<{ success: boolean; migrated: string[]; errors: string[] }> {\n const workspace = await this.getWorkspaceById(workspaceId);\n const SKILLVERSE_HOME = process.env.SKILLVERSE_HOME || join(homedir(), '.skillverse');\n const SKILLS_DIR = process.env.SKILLS_DIR || join(SKILLVERSE_HOME, 'skills');\n\n // Ensure skills directory exists\n if (!existsSync(SKILLS_DIR)) {\n await mkdir(SKILLS_DIR, { recursive: true });\n }\n\n const { rename, readFile, cp } = await import('fs/promises');\n const migrated: string[] = [];\n const errors: string[] = [];\n\n for (const skillName of skillNames) {\n const sourcePath = join(workspace.path, skillName);\n const targetPath = join(SKILLS_DIR, skillName);\n\n try {\n // Check if source exists and is not a symlink\n if (!existsSync(sourcePath)) {\n errors.push(`${skillName}: Source path not found`);\n continue;\n }\n\n const lstats = lstatSync(sourcePath);\n if (lstats.isSymbolicLink()) {\n errors.push(`${skillName}: Already a symlink, skipping`);\n continue;\n }\n\n // Check if skill already exists in unified storage\n if (existsSync(targetPath)) {\n // Check if it's the same skill by comparing paths or skip\n errors.push(`${skillName}: Already exists in unified storage`);\n continue;\n }\n\n // Check if skill already exists in database\n const existingSkill = await prisma.skill.findUnique({\n where: { name: skillName },\n });\n\n if (existingSkill) {\n errors.push(`${skillName}: Already registered in database`);\n continue;\n }\n\n // Parse metadata before moving\n const skillMdPath = join(sourcePath, 'SKILL.md');\n let description = '';\n let metadata: any = {};\n\n if (existsSync(skillMdPath)) {\n try {\n const matter = await import('gray-matter');\n const fileContent = await readFile(skillMdPath, 'utf-8');\n const parsed = matter.default(fileContent);\n description = parsed.data.description || '';\n metadata = parsed.data;\n } catch (e) {\n console.warn(`Failed to parse SKILL.md for ${skillName}:`, e);\n }\n }\n\n // Move skill to unified storage\n await cp(sourcePath, targetPath, { recursive: true });\n await rm(sourcePath, { recursive: true, force: true });\n\n // Register in database\n const skill = await prisma.skill.create({\n data: {\n name: skillName,\n source: 'local',\n description,\n storagePath: targetPath,\n metadata: JSON.stringify(metadata),\n },\n });\n\n // Create symlink back to workspace\n await symlink(targetPath, sourcePath, 'dir');\n\n // Create skill-workspace link in database\n await prisma.skillWorkspace.create({\n data: {\n skillId: skill.id,\n workspaceId: workspace.id,\n },\n });\n\n migrated.push(skillName);\n console.log(`✅ Migrated skill \"${skillName}\" to unified storage`);\n\n } catch (error: any) {\n console.error(`Failed to migrate ${skillName}:`, error);\n errors.push(`${skillName}: ${error.message}`);\n }\n }\n\n return {\n success: errors.length === 0,\n migrated,\n errors,\n };\n }\n}\n\nexport const workspaceService = new WorkspaceService();\n","import { Router, Request, Response, NextFunction } from 'express';\nimport { workspaceService } from '../services/workspaceService.js';\nimport { WorkspaceType, WorkspaceScope } from '@skillverse/shared';\n\nconst router = Router();\n\n// GET /api/workspaces - Get all workspaces\nrouter.get('/', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const workspaces = await workspaceService.getAllWorkspaces();\n res.json({\n success: true,\n data: workspaces,\n });\n } catch (error) {\n next(error);\n }\n});\n\n// GET /api/workspaces/:id - Get workspace by ID\nrouter.get('/:id', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const workspace = await workspaceService.getWorkspaceById(req.params.id);\n res.json({\n success: true,\n data: workspace,\n });\n } catch (error) {\n next(error);\n }\n});\n\n// POST /api/workspaces - Create workspace\nrouter.post('/', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const { name, projectPath, type, scope } = req.body;\n\n if (!name || !type || !scope) {\n return res.status(400).json({\n success: false,\n error: 'name, type, and scope are required',\n });\n }\n\n // For project scope, projectPath is required\n if (scope === 'project' && !projectPath) {\n return res.status(400).json({\n success: false,\n error: 'projectPath is required for project scope',\n });\n }\n\n const validTypes: WorkspaceType[] = ['vscode', 'cursor', 'claude-desktop', 'codex', 'antigravity', 'custom'];\n if (!validTypes.includes(type)) {\n return res.status(400).json({\n success: false,\n error: `type must be one of: ${validTypes.join(', ')}`,\n });\n }\n\n const validScopes: WorkspaceScope[] = ['project', 'global'];\n if (!validScopes.includes(scope)) {\n return res.status(400).json({\n success: false,\n error: `scope must be one of: ${validScopes.join(', ')}`,\n });\n }\n\n const workspace = await workspaceService.createWorkspace(name, projectPath || '', type, scope);\n res.status(201).json({\n success: true,\n data: workspace,\n message: 'Workspace created successfully',\n });\n } catch (error) {\n next(error);\n }\n});\n\n// PUT /api/workspaces/:id - Update workspace\nrouter.put('/:id', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const { name, path, type, scope } = req.body;\n\n if (type) {\n const validTypes: WorkspaceType[] = ['vscode', 'cursor', 'claude-desktop', 'codex', 'antigravity', 'custom'];\n if (!validTypes.includes(type)) {\n return res.status(400).json({\n success: false,\n error: `type must be one of: ${validTypes.join(', ')}`,\n });\n }\n }\n\n if (scope) {\n const validScopes: WorkspaceScope[] = ['project', 'global'];\n if (!validScopes.includes(scope)) {\n return res.status(400).json({\n success: false,\n error: `scope must be one of: ${validScopes.join(', ')}`,\n });\n }\n }\n\n const workspace = await workspaceService.updateWorkspace(req.params.id, {\n name,\n path,\n type,\n scope,\n });\n res.json({\n success: true,\n data: workspace,\n message: 'Workspace updated successfully',\n });\n } catch (error) {\n next(error);\n }\n});\n\n// DELETE /api/workspaces/:id - Delete workspace\nrouter.delete('/:id', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const result = await workspaceService.deleteWorkspace(req.params.id);\n res.json(result);\n } catch (error) {\n next(error);\n }\n});\n\n// POST /api/workspaces/:id/detect-skills - Detect existing skills in workspace\nrouter.post('/:id/detect-skills', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const workspace = await workspaceService.getWorkspaceById(req.params.id);\n const existingSkills = await workspaceService.detectExistingSkills(workspace.path);\n res.json({\n success: true,\n data: existingSkills,\n });\n } catch (error) {\n next(error);\n }\n});\n\n// POST /api/workspaces/:id/migrate-skills - Migrate existing skills to unified storage\nrouter.post('/:id/migrate-skills', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const { skillNames } = req.body;\n\n if (!skillNames || !Array.isArray(skillNames) || skillNames.length === 0) {\n return res.status(400).json({\n success: false,\n error: 'skillNames array is required',\n });\n }\n\n const result = await workspaceService.migrateExistingSkills(req.params.id, skillNames);\n res.json({\n success: true,\n data: result,\n });\n } catch (error) {\n next(error);\n }\n});\n\nexport default router;\n\n","import { Router, Request, Response, NextFunction } from 'express';\nimport { skillService } from '../services/skillService.js';\nimport { bundleService } from '../services/bundleService.js';\nimport { AppError } from '../middleware/errorHandler.js';\nimport { ErrorCode } from '@skillverse/shared';\nimport { prisma } from '../lib/db.js';\nimport { existsSync, readFileSync } from 'fs';\nimport { join } from 'path';\nimport { mkdir, rm, writeFile } from 'fs/promises';\nimport { GitHubMarketplaceRegistry, type MarketplaceGitHubConfig, type MarketplaceIndex } from '../services/githubMarketplaceRegistry.js';\n\nconst router = Router();\n\nimport { marketplaceConfig } from '../marketplaceConfig.js';\n\nfunction requireMarketplaceGitHubConfig(): MarketplaceGitHubConfig {\n // Use hardcoded configuration\n const { indexUrl, owner, repo, branch, token } = marketplaceConfig;\n\n if (!indexUrl) {\n throw new AppError(\n ErrorCode.VALIDATION_ERROR,\n 'Marketplace indexUrl is not configured.',\n 400\n );\n }\n\n return {\n indexUrl,\n owner,\n repo,\n branch,\n token,\n indexPath: 'index.json',\n };\n}\n\nfunction mapIndexToMarketplaceItems(index: MarketplaceIndex, search?: string) {\n const query = (search || '').trim().toLowerCase();\n const skills = index.skills || [];\n\n const filtered = query\n ? skills.filter((s: any) => {\n const name = String(s?.name || '').toLowerCase();\n const desc = String(s?.description || '').toLowerCase();\n return name.includes(query) || desc.includes(query);\n })\n : skills;\n\n return filtered.map((entry: any) => {\n const id = GitHubMarketplaceRegistry.stableIdForEntry(entry);\n const publishDate = entry.createdAt || entry.updatedAt || index.updatedAt || new Date().toISOString();\n\n return {\n id,\n skillId: id,\n publisherId: undefined,\n publisherName: entry.publisherName || 'Anonymous',\n publishDate: new Date(publishDate),\n downloads: entry.downloads || 0,\n skill: {\n id,\n name: entry.name,\n source: entry.type === 'git' ? 'git' : 'local',\n sourceUrl: entry.type === 'git' ? entry.gitUrl : undefined,\n description: entry.description || '',\n commitHash: undefined,\n repoUrl: entry.type === 'git' ? entry.gitUrl : undefined,\n updateAvailable: false,\n lastUpdateCheck: undefined,\n installDate: new Date(publishDate),\n metadata: {\n marketplace: entry,\n },\n },\n };\n });\n}\n\nasync function fetchIndex(): Promise<MarketplaceIndex> {\n const ghCfg = requireMarketplaceGitHubConfig();\n const registry = new GitHubMarketplaceRegistry(ghCfg);\n return await registry.fetchIndexFromPages();\n}\n\n// GET /api/marketplace/skills - Get all marketplace skills (from GitHub Pages index.json)\nrouter.get('/skills', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const { search, page = '1', pageSize = '20' } = req.query;\n const index = await fetchIndex();\n const allItems = mapIndexToMarketplaceItems(index, search as string | undefined);\n\n const p = parseInt(page as string);\n const ps = parseInt(pageSize as string);\n const total = allItems.length;\n const items = allItems.slice((p - 1) * ps, (p - 1) * ps + ps);\n\n res.json({\n success: true,\n data: {\n items,\n total,\n page: p,\n pageSize: ps,\n },\n });\n } catch (error) {\n next(error);\n }\n});\n\n// GET /api/marketplace/skills/:id - Get marketplace skill by ID\nrouter.get('/skills/:id', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const index = await fetchIndex();\n const items = mapIndexToMarketplaceItems(index);\n const marketplaceSkill = items.find((i: any) => i.id === req.params.id);\n\n if (!marketplaceSkill) {\n throw new AppError(ErrorCode.NOT_FOUND, 'Marketplace skill not found', 404);\n }\n\n res.json({\n success: true,\n data: marketplaceSkill,\n });\n } catch (error) {\n next(error);\n }\n});\n\n// GET /api/marketplace/download/:id - Download skill bundle\nrouter.get('/download/:id', async (req: Request, res: Response, next: NextFunction) => {\n try {\n // Fetch fresh index from repo to update downloads\n const ghCfg = requireMarketplaceGitHubConfig();\n const registry = new GitHubMarketplaceRegistry(ghCfg);\n\n let index: MarketplaceIndex;\n let sha: string | undefined;\n\n try {\n const result = await registry.readIndexFromRepo();\n index = result.index;\n sha = result.sha;\n } catch (e) {\n console.warn('Failed to read index from repo, falling back to cached:', e);\n index = await fetchIndex();\n }\n\n const entryIndex = (index.skills || []).findIndex(\n (s: any) => GitHubMarketplaceRegistry.stableIdForEntry(s) === req.params.id\n );\n\n const entry = entryIndex >= 0 ? index.skills[entryIndex] : undefined;\n\n if (!entry) throw new AppError(ErrorCode.NOT_FOUND, 'Marketplace skill not found', 404);\n\n // Increment downloads\n if (sha) {\n try {\n entry.downloads = (entry.downloads || 0) + 1;\n index.skills[entryIndex] = entry;\n await registry.upsertIndexToRepo(index, sha);\n } catch (e) {\n console.warn('Failed to update download count:', e);\n // non-fatal\n }\n }\n\n if (entry.type === 'git') {\n return res.json({\n success: true,\n data: { type: 'git', sourceUrl: entry.gitUrl },\n });\n }\n\n return res.json({\n success: true,\n data: {\n type: 'bundle',\n bundleUrl: entry.bundleUrl,\n bundleSize: entry.bundleSize,\n sha256: entry.sha256,\n skillVersion: entry.skillVersion,\n },\n });\n } catch (error) {\n next(error);\n }\n});\n\n// POST /api/marketplace/publish - Publish skill to marketplace\nrouter.post('/publish', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const { skillId, publisherName } = req.body;\n\n if (!skillId) {\n return res.status(400).json({\n success: false,\n error: 'skillId is required',\n });\n }\n\n const skill = await skillService.getSkillById(skillId);\n\n const ghCfg = requireMarketplaceGitHubConfig();\n if (!ghCfg.owner || !ghCfg.repo || !ghCfg.branch || !ghCfg.token) {\n throw new AppError(\n ErrorCode.VALIDATION_ERROR,\n 'GitHub registry config is incomplete. Please set owner/repo/branch/token in Settings -> Marketplace.',\n 400\n );\n }\n\n const registry = new GitHubMarketplaceRegistry(ghCfg);\n const { index, sha } = await registry.readIndexFromRepo();\n\n if (skill.source === 'git') {\n if (!skill.sourceUrl) {\n throw new AppError(ErrorCode.VALIDATION_ERROR, 'Git skill is missing sourceUrl', 400);\n }\n\n registry.upsertSkillEntry(index, {\n type: 'git',\n name: skill.name,\n description: skill.description || '',\n publisherName: publisherName || 'Anonymous',\n gitUrl: skill.sourceUrl,\n });\n } else {\n if (!existsSync(skill.storagePath)) {\n throw new AppError(ErrorCode.FILE_SYSTEM_ERROR, 'Skill files not found on disk', 400);\n }\n\n // Bundle local skill -> upload as GitHub Release asset\n const bundlePath = await bundleService.createBundle(skill.storagePath, skill.name);\n const parsedMeta = (() => {\n try {\n return skill.metadata ? JSON.parse(skill.metadata as any) : {};\n } catch {\n return {};\n }\n })();\n const skillVersion = String(parsedMeta.version || parsedMeta.skillVersion || '1.0.0');\n\n const uploaded = await registry.createReleaseWithAsset({\n skillName: skill.name,\n skillVersion,\n bundlePath,\n description: skill.description || '',\n });\n\n registry.upsertSkillEntry(index, {\n type: 'bundle',\n name: skill.name,\n description: skill.description || '',\n publisherName: publisherName || 'Anonymous',\n bundleUrl: uploaded.bundleUrl,\n bundleSize: uploaded.bundleSize,\n sha256: uploaded.sha256,\n skillVersion,\n });\n }\n\n\n await registry.upsertIndexToRepo(index, sha);\n\n // Update local MarketplaceSkill record\n await prisma.marketplaceSkill.upsert({\n where: { skillId: skill.id },\n create: {\n skillId: skill.id,\n publisherName: publisherName || 'Anonymous',\n downloads: 0,\n },\n update: {\n publisherName: publisherName || 'Anonymous',\n updatedAt: new Date(),\n }\n });\n\n res.status(201).json({\n success: true,\n data: { ok: true },\n message: 'Skill published to marketplace successfully',\n });\n } catch (error) {\n next(error);\n }\n});\n\n\n// POST /api/marketplace/install/:id - Install skill from marketplace\nrouter.post('/install/:id', async (req: Request, res: Response, next: NextFunction) => {\n try {\n // Fetch fresh index from repo to update downloads\n const ghCfg = requireMarketplaceGitHubConfig();\n const registry = new GitHubMarketplaceRegistry(ghCfg);\n\n let index: MarketplaceIndex;\n let sha: string | undefined;\n\n try {\n const result = await registry.readIndexFromRepo();\n index = result.index;\n sha = result.sha;\n } catch (e) {\n // Fallback to cached/pages index if repo read fails (e.g. read-only token?)\n // But we can't increment downloads then.\n console.warn('Failed to read index from repo for install count:', e);\n index = await fetchIndex();\n }\n\n const entryIndex = (index.skills || []).findIndex(\n (s: any) => GitHubMarketplaceRegistry.stableIdForEntry(s) === req.params.id\n );\n\n const entry = entryIndex >= 0 ? index.skills[entryIndex] : undefined;\n\n if (!entry) throw new AppError(ErrorCode.NOT_FOUND, 'Marketplace skill not found', 404);\n\n // Increment downloads if we have repo access\n if (sha) {\n try {\n entry.downloads = (entry.downloads || 0) + 1;\n // Update specific entry in index\n index.skills[entryIndex] = entry;\n await registry.upsertIndexToRepo(index, sha);\n } catch (e) {\n console.warn('Failed to update download count:', e);\n // Continue with install anyway\n }\n }\n\n if (entry.type === 'git') {\n const newSkill = await skillService.createSkillFromGit(entry.gitUrl, entry.description || undefined);\n\n // Link marketplace entry if it exists? We don't have local MarketplaceSkill for installed skills usually, \n // unless we published them. But maybe we should fetch it?\n // For now, normal install.\n\n return res.status(201).json({\n success: true,\n data: newSkill,\n message: 'Skill installed from marketplace successfully',\n });\n }\n\n // bundle install: download -> createSkillFromBundle\n const tempDir = process.env.TEMP_DIR || join(process.env.HOME || '', '.skillverse', 'temp');\n await mkdir(tempDir, { recursive: true });\n\n const resp = await fetch(entry.bundleUrl);\n if (!resp.ok) {\n throw new AppError(\n ErrorCode.INTERNAL_ERROR,\n `Failed to download bundle: ${resp.status} ${resp.statusText}`,\n 502\n );\n }\n\n const buf = Buffer.from(await resp.arrayBuffer());\n const tmpPath = join(tempDir, `marketplace-${entry.name}-${Date.now()}.tar.gz`);\n await writeFile(tmpPath, buf);\n\n try {\n const newSkill = await skillService.createSkillFromBundle(\n tmpPath,\n entry.name,\n entry.description || undefined\n );\n\n return res.status(201).json({\n success: true,\n data: newSkill,\n message: 'Skill installed from marketplace successfully',\n });\n } finally {\n await rm(tmpPath, { force: true }).catch(() => { });\n }\n } catch (error) {\n next(error);\n }\n});\n\n// DELETE /api/marketplace/unpublish/:id - Unpublish skill from marketplace\nrouter.delete('/unpublish/:skillId', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const skill = await skillService.getSkillById(req.params.skillId);\n\n const ghCfg = requireMarketplaceGitHubConfig();\n if (!ghCfg.owner || !ghCfg.repo || !ghCfg.branch || !ghCfg.token) {\n throw new AppError(\n ErrorCode.VALIDATION_ERROR,\n 'GitHub registry config is incomplete. Please set owner/repo/branch/token in Settings -> Marketplace.',\n 400\n );\n }\n const registry = new GitHubMarketplaceRegistry(ghCfg);\n const { index, sha } = await registry.readIndexFromRepo();\n\n const before = index.skills.length;\n\n // Find entry to remove\n const entryToRemove = index.skills.find((s: any) => {\n if (s?.name !== skill.name) return false;\n // Match type based on skill source\n if (skill.source === 'git') return s.type === 'git';\n return s.type === 'bundle';\n });\n\n if (entryToRemove) {\n // If bundle, try to delete release\n if (entryToRemove.type === 'bundle' && entryToRemove.bundleUrl) {\n // 从 bundleUrl 中提取 tag\n // URL 格式: .../releases/download/<TAG_WITH_SLASHES>/<ASSET_FILENAME>\n // tag 格式: skillverse-marketplace/<name>/v<ver>/<timestamp>\n try {\n const match = entryToRemove.bundleUrl.match(/\\/releases\\/download\\/(.+)\\/[^/]+$/);\n if (match && match[1]) {\n const tag = decodeURIComponent(match[1]);\n console.log(`Deleting release tag: ${tag}`);\n await registry.deleteReleaseByTag(tag);\n }\n } catch (e) {\n console.warn('Failed to delete GitHub release:', e);\n // Continue to remove from index\n }\n }\n\n // Remove from index\n index.skills = index.skills.filter(s => s !== entryToRemove);\n }\n\n const after = index.skills.length;\n\n if (before === after) {\n throw new AppError(ErrorCode.NOT_FOUND, 'Skill is not published to marketplace', 404);\n }\n\n await registry.upsertIndexToRepo(index, sha);\n\n // Remove local MarketplaceSkill record\n try {\n await prisma.marketplaceSkill.delete({\n where: { skillId: skill.id }\n });\n } catch (e) {\n // Ignore if not found locally\n }\n\n res.json({\n success: true,\n message: 'Skill unpublished from marketplace successfully',\n });\n } catch (error) {\n next(error);\n }\n});\n\nexport default router;\n","import { createWriteStream, existsSync, createReadStream } from 'fs';\nimport { mkdir, rm, readdir, stat } from 'fs/promises';\nimport { join, basename } from 'path';\nimport { pipeline } from 'stream/promises';\nimport archiver from 'archiver';\nimport { createGunzip } from 'zlib';\nimport { extract } from 'tar';\n\nconst BUNDLES_DIR = join(\n process.env.SKILLVERSE_HOME || join(process.env.HOME || '', '.skillverse'),\n 'bundles'\n);\n\n/**\n * Ensures the bundles directory exists\n */\nasync function ensureBundlesDir(): Promise<void> {\n if (!existsSync(BUNDLES_DIR)) {\n await mkdir(BUNDLES_DIR, { recursive: true });\n }\n}\n\n/**\n * Creates a .tar.gz bundle from a skill directory\n * @param skillPath - Path to the skill directory\n * @param skillName - Name of the skill (used for bundle filename)\n * @returns Path to the created bundle\n */\nexport async function createBundle(skillPath: string, skillName: string): Promise<string> {\n await ensureBundlesDir();\n\n const bundleName = `${skillName}-${Date.now()}.tar.gz`;\n const bundlePath = join(BUNDLES_DIR, bundleName);\n\n return new Promise((resolve, reject) => {\n const output = createWriteStream(bundlePath);\n const archive = archiver('tar', {\n gzip: true,\n gzipOptions: { level: 9 },\n });\n\n output.on('close', () => {\n console.log(`📦 Bundle created: ${bundlePath} (${archive.pointer()} bytes)`);\n resolve(bundlePath);\n });\n\n archive.on('error', (err) => {\n reject(err);\n });\n\n archive.pipe(output);\n\n // Add all files from the skill directory\n archive.directory(skillPath, false);\n\n archive.finalize();\n });\n}\n\n/**\n * Extracts a bundle to a target directory\n * @param bundlePath - Path to the .tar.gz bundle\n * @param targetDir - Directory to extract to\n */\nexport async function extractBundle(bundlePath: string, targetDir: string): Promise<void> {\n if (!existsSync(bundlePath)) {\n throw new Error(`Bundle not found: ${bundlePath}`);\n }\n\n // Create target directory if it doesn't exist\n if (!existsSync(targetDir)) {\n await mkdir(targetDir, { recursive: true });\n }\n\n await pipeline(\n createReadStream(bundlePath),\n createGunzip(),\n extract({ cwd: targetDir })\n );\n\n console.log(`📂 Bundle extracted to: ${targetDir}`);\n}\n\n/**\n * Deletes a bundle file\n * @param bundlePath - Path to the bundle to delete\n */\nexport async function deleteBundle(bundlePath: string): Promise<void> {\n if (existsSync(bundlePath)) {\n await rm(bundlePath);\n console.log(`🗑️ Bundle deleted: ${bundlePath}`);\n }\n}\n\n/**\n * Gets the size of a bundle in bytes\n * @param bundlePath - Path to the bundle\n */\nexport async function getBundleSize(bundlePath: string): Promise<number> {\n if (!existsSync(bundlePath)) {\n return 0;\n }\n const stats = await stat(bundlePath);\n return stats.size;\n}\n\n/**\n * Lists all bundles in the bundles directory\n */\nexport async function listBundles(): Promise<string[]> {\n await ensureBundlesDir();\n const files = await readdir(BUNDLES_DIR);\n return files.filter((f) => f.endsWith('.tar.gz')).map((f) => join(BUNDLES_DIR, f));\n}\n\nexport const bundleService = {\n createBundle,\n extractBundle,\n deleteBundle,\n getBundleSize,\n listBundles,\n BUNDLES_DIR,\n};\n","import { Buffer } from 'buffer';\nimport { createHash } from 'crypto';\nimport { readFile } from 'fs/promises';\n\ntype MarketplaceIndexSkill =\n | {\n type: 'git';\n name: string;\n description?: string;\n publisherName?: string;\n gitUrl: string;\n createdAt?: string;\n updatedAt?: string;\n downloads?: number;\n }\n | {\n type: 'bundle';\n name: string;\n description?: string;\n publisherName?: string;\n bundleUrl: string;\n bundleSize?: number;\n sha256?: string;\n skillVersion?: string;\n createdAt?: string;\n updatedAt?: string;\n downloads?: number;\n };\n\nexport type MarketplaceIndex = {\n version: number;\n updatedAt: string;\n skills: MarketplaceIndexSkill[];\n};\n\nexport type MarketplaceGitHubConfig = {\n indexUrl: string; // GitHub Pages URL to index.json (read path)\n owner: string;\n repo: string;\n branch: string;\n token: string;\n indexPath?: string; // file path in repo, default: index.json\n};\n\nfunction sha256Hex(buf: Buffer) {\n return createHash('sha256').update(buf).digest('hex');\n}\n\nfunction nowIso() {\n return new Date().toISOString();\n}\n\nfunction normalizeIndex(index: any): MarketplaceIndex {\n const base: MarketplaceIndex = {\n version: typeof index?.version === 'number' ? index.version : 1,\n updatedAt: typeof index?.updatedAt === 'string' ? index.updatedAt : nowIso(),\n skills: Array.isArray(index?.skills) ? index.skills : [],\n };\n return base;\n}\n\nasync function requireOctokit() {\n // Lazy import so server can still start without GitHub deps in dev paths\n const mod: any = await import('octokit');\n return mod.Octokit as any;\n}\n\nexport class GitHubMarketplaceRegistry {\n constructor(private cfg: MarketplaceGitHubConfig) { }\n\n private getIndexPath() {\n return this.cfg.indexPath || 'index.json';\n }\n\n private async octokit() {\n const Octokit = await requireOctokit();\n return new Octokit({ auth: this.cfg.token });\n }\n\n async fetchIndexFromPages(): Promise<MarketplaceIndex> {\n const resp = await fetch(this.cfg.indexUrl, { method: 'GET' });\n if (!resp.ok) {\n throw new Error(`Failed to fetch marketplace index from Pages: ${resp.status} ${resp.statusText}`);\n }\n const json = await resp.json();\n return normalizeIndex(json);\n }\n\n async readIndexFromRepo(): Promise<{ index: MarketplaceIndex; sha?: string }> {\n const octokit = await this.octokit();\n const path = this.getIndexPath();\n const res = await octokit.rest.repos.getContent({\n owner: this.cfg.owner,\n repo: this.cfg.repo,\n path,\n ref: this.cfg.branch,\n });\n\n if (Array.isArray(res.data) || res.data.type !== 'file') {\n throw new Error(`Invalid index path in repo: ${path}`);\n }\n\n const content = Buffer.from(res.data.content, res.data.encoding).toString('utf-8');\n const parsed = JSON.parse(content);\n return { index: normalizeIndex(parsed), sha: res.data.sha };\n }\n\n async upsertIndexToRepo(index: MarketplaceIndex, previousSha?: string): Promise<void> {\n const octokit = await this.octokit();\n const path = this.getIndexPath();\n const body = JSON.stringify(\n {\n ...index,\n updatedAt: nowIso(),\n },\n null,\n 2\n );\n const contentBase64 = Buffer.from(body, 'utf-8').toString('base64');\n\n await octokit.rest.repos.createOrUpdateFileContents({\n owner: this.cfg.owner,\n repo: this.cfg.repo,\n branch: this.cfg.branch,\n path,\n message: `chore(marketplace): update ${path}`,\n content: contentBase64,\n ...(previousSha ? { sha: previousSha } : {}),\n });\n }\n\n async createReleaseWithAsset(params: {\n skillName: string;\n skillVersion: string;\n bundlePath: string;\n description?: string;\n }): Promise<{ bundleUrl: string; bundleSize: number; sha256: string; tag: string }> {\n const octokit = await this.octokit();\n\n const bundleBuf = await readFile(params.bundlePath);\n const sha256 = sha256Hex(bundleBuf);\n const bundleSize = bundleBuf.byteLength;\n\n // Ensure unique tag\n const safeName = params.skillName.replace(/[^a-zA-Z0-9._-]/g, '-');\n const safeVer = params.skillVersion.replace(/[^a-zA-Z0-9._-]/g, '-');\n const tag = `skillverse-marketplace/${safeName}/v${safeVer}/${Date.now()}`;\n\n const release = await octokit.rest.repos.createRelease({\n owner: this.cfg.owner,\n repo: this.cfg.repo,\n tag_name: tag,\n name: `SkillVerse Marketplace: ${params.skillName}@${params.skillVersion}`,\n body: params.description || '',\n draft: false,\n prerelease: false,\n target_commitish: this.cfg.branch,\n });\n\n const assetName = `${safeName}-${safeVer}.tar.gz`;\n const uploadRes = await octokit.rest.repos.uploadReleaseAsset({\n owner: this.cfg.owner,\n repo: this.cfg.repo,\n release_id: release.data.id,\n name: assetName,\n data: bundleBuf,\n headers: {\n 'content-type': 'application/gzip',\n 'content-length': bundleSize,\n },\n });\n\n return {\n bundleUrl: uploadRes.data.browser_download_url,\n bundleSize,\n sha256,\n tag,\n };\n }\n\n upsertSkillEntry(index: MarketplaceIndex, entry: MarketplaceIndexSkill): MarketplaceIndex {\n const createdAt = nowIso();\n\n const existingIdx = index.skills.findIndex((s: any) => s?.name === entry.name && s?.type === entry.type);\n if (existingIdx >= 0) {\n const prev: any = index.skills[existingIdx];\n index.skills[existingIdx] = {\n ...prev,\n ...entry,\n updatedAt: nowIso(),\n createdAt: prev.createdAt || createdAt,\n } as any;\n } else {\n index.skills.push({\n ...entry,\n createdAt,\n updatedAt: nowIso(),\n } as any);\n }\n return index;\n }\n\n static stableIdForEntry(entry: MarketplaceIndexSkill): string {\n const key =\n entry.type === 'git'\n ? `git:${entry.name}:${entry.gitUrl}`\n : `bundle:${entry.name}:${entry.skillVersion || ''}:${entry.bundleUrl}`;\n return createHash('sha256').update(key).digest('hex').slice(0, 24);\n }\n async deleteReleaseByTag(tag: string): Promise<void> {\n const octokit = await this.octokit();\n\n // getReleaseByTag 无法处理含斜杠的 tag,改用 listReleases 遍历匹配\n let releaseId: number | undefined;\n let page = 1;\n const perPage = 30;\n\n while (!releaseId) {\n const { data: releases } = await octokit.rest.repos.listReleases({\n owner: this.cfg.owner,\n repo: this.cfg.repo,\n page,\n per_page: perPage,\n });\n\n if (releases.length === 0) break; // 无更多 release\n\n const found = releases.find((r: any) => r.tag_name === tag);\n if (found) {\n releaseId = found.id;\n break;\n }\n page++;\n }\n\n if (!releaseId) {\n console.warn(`Release with tag \"${tag}\" not found, skipping deletion.`);\n return;\n }\n\n // 删除 release\n await octokit.rest.repos.deleteRelease({\n owner: this.cfg.owner,\n repo: this.cfg.repo,\n release_id: releaseId,\n });\n\n // 尝试删除对应的 git tag ref\n try {\n await octokit.rest.git.deleteRef({\n owner: this.cfg.owner,\n repo: this.cfg.repo,\n ref: `tags/${tag}`,\n });\n } catch (e: any) {\n // tag ref 删除失败不影响整体流程\n console.warn(`Failed to delete git tag ref \"tags/${tag}\":`, e.message);\n }\n }\n}\n\n","export const marketplaceConfig = {\n indexUrl: 'https://fdksd.github.io/skillverse-marketplace/index.json',\n owner: 'fdksd',\n repo: 'skillverse-marketplace',\n branch: 'main',\n token: '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',\n};\n","import { Router, Request, Response, NextFunction } from 'express';\nimport { prisma } from '../lib/db.js';\n\nconst router = Router();\n\n// GET /api/dashboard/stats - Get dashboard statistics\nrouter.get('/stats', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const [totalSkills, totalWorkspaces, totalLinks, marketplaceSkills, recentSkills] =\n await Promise.all([\n prisma.skill.count(),\n prisma.workspace.count(),\n prisma.skillWorkspace.count(),\n prisma.marketplaceSkill.count(),\n prisma.skill.findMany({\n orderBy: { installDate: 'desc' },\n take: 5,\n include: {\n linkedWorkspaces: {\n include: {\n workspace: true,\n },\n },\n },\n }),\n ]);\n\n res.json({\n success: true,\n data: {\n totalSkills,\n totalWorkspaces,\n totalLinks,\n marketplaceSkills,\n recentSkills,\n },\n });\n } catch (error) {\n next(error);\n }\n});\n\n// GET /api/dashboard/activity - Get recent activity\nrouter.get('/activity', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const [recentSkills, recentLinks, recentPublished] = await Promise.all([\n prisma.skill.findMany({\n orderBy: { createdAt: 'desc' },\n take: 10,\n select: {\n id: true,\n name: true,\n source: true,\n createdAt: true,\n },\n }),\n prisma.skillWorkspace.findMany({\n orderBy: { linkedAt: 'desc' },\n take: 10,\n include: {\n skill: { select: { name: true } },\n workspace: { select: { name: true } },\n },\n }),\n prisma.marketplaceSkill.findMany({\n orderBy: { publishDate: 'desc' },\n take: 10,\n include: {\n skill: { select: { name: true } },\n },\n }),\n ]);\n\n // Combine and sort by date\n const activities = [\n ...recentSkills.map((s) => ({\n type: 'skill_added' as const,\n date: s.createdAt,\n data: { skillName: s.name, source: s.source },\n })),\n ...recentLinks.map((l) => ({\n type: 'skill_linked' as const,\n date: l.linkedAt,\n data: { skillName: l.skill.name, workspaceName: l.workspace.name },\n })),\n ...recentPublished.map((p) => ({\n type: 'skill_published' as const,\n date: p.publishDate,\n data: { skillName: p.skill.name },\n })),\n ].sort((a, b) => b.date.getTime() - a.date.getTime());\n\n res.json({\n success: true,\n data: activities.slice(0, 20),\n });\n } catch (error) {\n next(error);\n }\n});\n\nexport default router;\n","import { Router, Request, Response, NextFunction } from 'express';\nimport { join } from 'path';\nimport { existsSync, readFileSync, writeFileSync } from 'fs';\n\nconst router = Router();\n\n// Path to config.json\n// We ALWAYS read/write to the bootstrap location to ensure persistence works\nconst HOME = process.env.HOME || process.env.USERPROFILE || '';\nconst BOOTSTRAP_HOME = join(HOME, '.skillverse');\nconst CONFIG_FILE = join(BOOTSTRAP_HOME, 'config.json');\n\ntype FileConfig = {\n skillverseHome?: string;\n registryUrl?: string;\n marketplace?: {\n indexUrl?: string;\n github?: {\n owner?: string;\n repo?: string;\n branch?: string;\n token?: string;\n };\n };\n};\n\n// Helper to read config\nfunction readConfig() {\n if (existsSync(CONFIG_FILE)) {\n try {\n return JSON.parse(readFileSync(CONFIG_FILE, 'utf-8')) as FileConfig;\n } catch (e) {\n console.error('Failed to read config.json:', e);\n return {};\n }\n }\n return {};\n}\n\n// GET /api/config - Get current configuration\nrouter.get('/', (req: Request, res: Response, next: NextFunction) => {\n try {\n const fileConfig = readConfig();\n\n // Combine env vars with file config\n // logic: File config represents \"User Preference\" (potentially pending restart)\n // Env vars represent \"Current Runtime State\" or \"System Defaults\"\n // We prioritize File Config for editable fields so the UI shows what is saved.\n\n const config = {\n // Show saved preference if available, otherwise current env/default\n skillverseHome: fileConfig.skillverseHome || process.env.SKILLVERSE_HOME || BOOTSTRAP_HOME,\n // registryUrl is potentially in config.json already\n registryUrl: fileConfig.registryUrl || process.env.SKILLVERSE_REGISTRY || 'http://localhost:4000',\n // Marketplace is now hardcoded\n marketplace: {\n indexUrl: '',\n github: {\n owner: '',\n repo: '',\n branch: '',\n tokenConfigured: false,\n },\n },\n };\n\n res.json({\n success: true,\n data: config,\n });\n } catch (error) {\n next(error);\n }\n});\n\n// POST /api/config - Update configuration\nrouter.post('/', async (req: Request, res: Response, next: NextFunction) => {\n try {\n const { skillverseHome, registryUrl, migrate, marketplace } = req.body;\n\n const currentConfig = readConfig();\n const oldHome = process.env.SKILLVERSE_HOME || BOOTSTRAP_HOME;\n\n if (migrate && skillverseHome && skillverseHome !== oldHome) {\n console.log(`Migrating data from ${oldHome} to ${skillverseHome}...`);\n const { cp } = await import('fs/promises');\n\n // Ensure new directory exists\n if (!existsSync(skillverseHome)) {\n const { mkdir } = await import('fs/promises');\n await mkdir(skillverseHome, { recursive: true });\n }\n\n // Helper to copy if source exists\n const copyDir = async (srcName: string) => {\n const src = join(oldHome, srcName);\n const dest = join(skillverseHome, srcName);\n if (existsSync(src)) {\n console.log(`Copying ${srcName}...`);\n await cp(src, dest, { recursive: true, force: true });\n }\n };\n\n await copyDir('skills');\n await copyDir('marketplace');\n\n // Copy Database\n const dbSrc = join(oldHome, 'skillverse.db');\n const dbDest = join(skillverseHome, 'skillverse.db');\n if (existsSync(dbSrc)) {\n console.log('Copying database...');\n // Try to copy main DB file\n await cp(dbSrc, dbDest, { force: true });\n\n // Try to copy WAL/SHM files if they exist (for SQLite safety)\n const walSrc = dbSrc + '-wal';\n if (existsSync(walSrc)) await cp(walSrc, dbDest + '-wal', { force: true });\n\n const shmSrc = dbSrc + '-shm';\n if (existsSync(shmSrc)) await cp(shmSrc, dbDest + '-shm', { force: true });\n\n // CRITICAL: Update storagePath in the NEW database to point to the new home\n // We need to use a direct SQLite update since Prisma is connected to the old DB\n console.log('Updating skill paths in new database...');\n const { execSync } = await import('child_process');\n const oldSkillsPath = join(oldHome, 'skills');\n const newSkillsPath = join(skillverseHome, 'skills');\n\n // Use SQLite to update all storagePath values\n const updateQuery = `UPDATE Skill SET storagePath = replace(storagePath, '${oldSkillsPath}', '${newSkillsPath}') WHERE storagePath LIKE '${oldSkillsPath}%';`;\n try {\n execSync(`sqlite3 \"${dbDest}\" \"${updateQuery}\"`, { encoding: 'utf-8' });\n console.log('✅ Updated skill paths in new database');\n } catch (sqlErr) {\n console.error('Failed to update skill paths:', sqlErr);\n }\n }\n }\n\n const nextConfig: FileConfig = {\n ...currentConfig,\n ...(skillverseHome && { skillverseHome }),\n ...(registryUrl && { registryUrl }),\n };\n\n // Marketplace config is immutable via API now\n\n\n // Write to config.json\n writeFileSync(CONFIG_FILE, JSON.stringify(nextConfig, null, 2));\n\n res.json({\n success: true,\n data: {\n ...nextConfig,\n // Never return token\n marketplace: {\n indexUrl: nextConfig.marketplace?.indexUrl || '',\n github: {\n owner: nextConfig.marketplace?.github?.owner || '',\n repo: nextConfig.marketplace?.github?.repo || '',\n branch: nextConfig.marketplace?.github?.branch || 'main',\n tokenConfigured: Boolean(nextConfig.marketplace?.github?.token),\n },\n },\n },\n message: 'Configuration saved. Restart server for changes to take effect.',\n });\n } catch (error) {\n next(error);\n }\n});\n\n// GET /api/config/version - Check for newer version on npm\nrouter.get('/version', async (req: Request, res: Response, next: NextFunction) => {\n try {\n // Read current version from package.json\n const { dirname, join: pathJoin } = await import('path');\n const { fileURLToPath } = await import('url');\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = dirname(__filename);\n\n // Find package.json relative to dist/routes/config.js -> ../.. is dist, then .. is server root\n const packageJsonPath = pathJoin(__dirname, '..', '..', 'package.json');\n let currentVersion = '0.0.0';\n\n if (existsSync(packageJsonPath)) {\n const pkg = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n currentVersion = pkg.version || '0.0.0';\n }\n\n // Fetch latest version from npm registry\n let latestVersion = currentVersion;\n let hasUpdate = false;\n\n try {\n const response = await fetch('https://registry.npmjs.org/skillverse/latest');\n if (response.ok) {\n const data = await response.json() as { version?: string };\n latestVersion = data.version || currentVersion;\n\n // Compare versions (simple semver comparison)\n const parseVersion = (v: string) => v.split('.').map(n => parseInt(n, 10) || 0);\n const current = parseVersion(currentVersion);\n const latest = parseVersion(latestVersion);\n\n for (let i = 0; i < 3; i++) {\n if (latest[i] > current[i]) {\n hasUpdate = true;\n break;\n } else if (latest[i] < current[i]) {\n break;\n }\n }\n }\n } catch (fetchError) {\n console.warn('Failed to check npm registry for updates:', fetchError);\n }\n\n res.json({\n success: true,\n data: {\n currentVersion,\n latestVersion,\n hasUpdate,\n },\n });\n } catch (error) {\n next(error);\n }\n});\n\nexport default router;\n","import { Request, Response, NextFunction } from 'express';\n\nexport function requestLogger(req: Request, res: Response, next: NextFunction) {\n const start = Date.now();\n \n res.on('finish', () => {\n const duration = Date.now() - start;\n console.log(`${req.method} ${req.path} - ${res.statusCode} - ${duration}ms`);\n });\n \n next();\n}\n","import { existsSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\nimport { prisma } from './db.js';\nimport { spawnSync } from 'child_process';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n// Find schema.prisma\n// Dev: server/src/lib/initDb.ts -> server/prisma/schema.prisma\n// Prod: server/dist/lib/initDb.js -> server/prisma/schema.prisma (copied via package.json files)\n// Or: server/node_modules/skillverse/prisma/schema.prisma\nfunction getSchemaPath(): string | null {\n const possiblePaths = [\n // Prod: dist/bin.js -> dist/../prisma/schema.prisma (i.e. ROOT/prisma/schema.prisma)\n join(__dirname, '../prisma/schema.prisma'),\n // Dev: src/lib/initDb.ts -> src/prisma/schema.prisma ? No, src/../prisma -> server/prisma\n // If __dirname is src/lib: ../../prisma/schema.prisma\n join(__dirname, '../../prisma/schema.prisma'),\n\n // Fallbacks\n join(process.cwd(), 'prisma/schema.prisma'),\n join(process.cwd(), 'server/prisma/schema.prisma'),\n ];\n\n return possiblePaths.find(p => existsSync(p)) || null;\n}\n\nexport async function ensureDatabaseInitialized() {\n try {\n // Check if we can query the database (e.g. check if Skill table exists)\n // We can try a simple count. If it fails with \"table not found\", we need to init.\n try {\n await prisma.skill.count();\n // If successful, DB is initialized\n return;\n } catch (error: any) {\n if (error.code === 'P2021' || error.message.includes('table') || error.message.includes('does not exist')) {\n console.log('📦 Initializing database...');\n await initializeDatabase();\n } else {\n throw error;\n }\n }\n } catch (error: any) {\n // console.error('ensureDatabaseInitialized error:', error);\n throw error;\n }\n}\n\nasync function initializeDatabase() {\n const schemaPath = getSchemaPath();\n if (!schemaPath) {\n throw new Error('Could not find schema.prisma');\n }\n\n // We need to run \"prisma db push\"\n // But \"prisma\" might not be in the global path.\n // In the installed package, it should be in node_modules/.bin/prisma\n\n // Try to find local prisma binary\n // Prod: dist/bin.js -> ../node_modules/.bin/prisma\n // Dev: src/lib/initDb.ts -> ../../node_modules/.bin/prisma\n const possiblePrismaBins = [\n join(__dirname, '../node_modules/.bin/prisma'),\n join(__dirname, '../../node_modules/.bin/prisma'),\n join(__dirname, '../../../node_modules/.bin/prisma'),\n join(process.cwd(), 'node_modules/.bin/prisma'),\n ];\n\n const prismaBin = possiblePrismaBins.find(p => existsSync(p)) || 'prisma';\n\n console.log(` Using schema: ${schemaPath}`);\n\n const result = spawnSync(prismaBin, ['db', 'push', '--schema', schemaPath], {\n stdio: 'inherit',\n env: { ...process.env }, // Ensure env vars (DATABASE_URL) are passed\n });\n\n if (result.error) {\n throw result.error;\n }\n\n if (result.status !== 0) {\n throw new Error(`Database initialization failed with status ${result.status}`);\n }\n\n console.log('✅ Database initialized successfully');\n}\n"],"mappings":"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","names":["config","config","join","existsSync","readdir","stat","createReadStream","createGunzip","pipeline","dotenv","fileURLToPath","dirname","join","mkdir","existsSync","join","existsSync","mkdir","rm","join","unlink","rm","mkdir","readFile","existsSync","readdir","stat","cp","matter","join","existsSync","mkdir","rm","readFile","Router","router","Router","Router","existsSync","mkdir","rm","join","existsSync","join","mkdir","rm","Buffer","readFile","router","Router","existsSync","join","mkdir","rm","Router","router","Router","join","existsSync","readFileSync","router","config","cp","mkdir","dirname","fileURLToPath","__filename","__dirname","existsSync","join","dirname","fileURLToPath","__filename","__dirname","dotenv","__filename","fileURLToPath","__dirname","dirname","join","existsSync","mkdir","skillService"]}