@anytio/pspm 0.13.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -1
- package/CLI_GUIDE.md +7 -2
- package/README.md +3 -1
- package/dist/add-CcgUlOLa.js +755 -0
- package/dist/add-CcgUlOLa.js.map +1 -0
- package/dist/add-Cnn-OR9g.js +2 -0
- package/dist/api-client-CBTk37gh.js +2 -0
- package/dist/api-client-DBXUpGoX.js +452 -0
- package/dist/api-client-DBXUpGoX.js.map +1 -0
- package/dist/config-BQy_Rjip.js +470 -0
- package/dist/config-BQy_Rjip.js.map +1 -0
- package/dist/config-BZJ6_GsC.js +2 -0
- package/dist/index.js +2782 -7018
- package/dist/index.js.map +1 -1
- package/dist/install-gcvbBeWi.js +2 -0
- package/dist/install-lNvqIk5c.js +479 -0
- package/dist/install-lNvqIk5c.js.map +1 -0
- package/dist/symlinks-BTw8X0GG.js +1834 -0
- package/dist/symlinks-BTw8X0GG.js.map +1 -0
- package/package.json +14 -12
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add-CcgUlOLa.js","names":[],"sources":["../src/wellknown.ts","../src/commands/add-helpers.ts","../src/commands/add-github.ts","../src/commands/add-local.ts","../src/commands/add-registry.ts","../src/commands/add-wellknown.ts","../src/commands/add.ts"],"sourcesContent":["/**\n * Well-Known Skills Discovery (RFC 8615)\n *\n * Fetches skills from any HTTPS domain that serves a\n * /.well-known/skills/index.json endpoint.\n */\n\nimport { mkdir, rm, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { calculateIntegrity } from \"./lib/index\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * A single skill entry in the well-known index.json\n */\nexport interface WellKnownSkillEntry {\n /** Skill identifier (directory name). Lowercase alphanumeric + hyphens, 1-64 chars. */\n name: string;\n /** Brief description */\n description: string;\n /** List of files in the skill directory. Must include SKILL.md. */\n files: string[];\n}\n\n/**\n * The /.well-known/skills/index.json structure\n */\nexport interface WellKnownIndex {\n skills: WellKnownSkillEntry[];\n}\n\n/**\n * A fetched well-known skill with all its file contents\n */\nexport interface WellKnownSkill {\n /** Skill name from index */\n name: string;\n /** Description from index */\n description: string;\n /** SKILL.md content */\n content: string;\n /** All files keyed by relative path */\n files: Map<string, string>;\n /** Source URL for this skill */\n sourceUrl: string;\n /** The index entry */\n indexEntry: WellKnownSkillEntry;\n}\n\n/**\n * Result of extracting a well-known skill to disk\n */\nexport interface WellKnownDownloadResult {\n /** All skills fetched from the endpoint */\n skills: WellKnownSkill[];\n /** The resolved base URL where the index was found */\n resolvedBaseUrl: string;\n /** Hostname for identification */\n hostname: string;\n}\n\n// =============================================================================\n// Constants\n// =============================================================================\n\nconst WELL_KNOWN_PATH = \".well-known/skills\";\nconst INDEX_FILE = \"index.json\";\nconst SKILL_NAME_PATTERN = /^[a-z0-9]([a-z0-9-]{0,62}[a-z0-9])?$/;\n\n/** Hosts that should NOT be treated as well-known (they have dedicated providers) */\nconst EXCLUDED_HOSTS = [\n \"github.com\",\n \"gitlab.com\",\n \"raw.githubusercontent.com\",\n];\n\n// =============================================================================\n// Detection\n// =============================================================================\n\n/**\n * Check if a string looks like a well-known skills URL.\n * Must be HTTP(S) and not a known git host.\n */\nexport function isWellKnownSpecifier(input: string): boolean {\n if (!input.startsWith(\"http://\") && !input.startsWith(\"https://\")) {\n return false;\n }\n\n try {\n const parsed = new URL(input);\n if (EXCLUDED_HOSTS.includes(parsed.hostname)) {\n return false;\n }\n if (input.endsWith(\".git\")) {\n return false;\n }\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Extract hostname from a well-known URL (strips www. prefix).\n */\nexport function getWellKnownHostname(url: string): string {\n try {\n const parsed = new URL(url);\n return parsed.hostname.replace(/^www\\./, \"\");\n } catch {\n return url;\n }\n}\n\n// =============================================================================\n// Validation\n// =============================================================================\n\n/**\n * Validate a single skill entry from the index.\n */\nfunction isValidSkillEntry(entry: unknown): entry is WellKnownSkillEntry {\n if (!entry || typeof entry !== \"object\") return false;\n\n const e = entry as Record<string, unknown>;\n\n // Required string fields\n if (typeof e.name !== \"string\" || e.name.length === 0) return false;\n if (typeof e.description !== \"string\" || e.description.length === 0)\n return false;\n\n // Name must match pattern\n if (!SKILL_NAME_PATTERN.test(e.name)) return false;\n\n // Files must be a non-empty array of strings\n if (!Array.isArray(e.files) || e.files.length === 0) return false;\n\n let hasSkillMd = false;\n for (const file of e.files) {\n if (typeof file !== \"string\") return false;\n // No absolute paths\n if (file.startsWith(\"/\") || file.startsWith(\"\\\\\")) return false;\n // No path traversal\n if (file.includes(\"..\")) return false;\n // Check for SKILL.md\n if (file.toLowerCase() === \"skill.md\") hasSkillMd = true;\n }\n\n if (!hasSkillMd) return false;\n\n return true;\n}\n\n/**\n * Validate a well-known index structure.\n */\nfunction isValidIndex(data: unknown): data is WellKnownIndex {\n if (!data || typeof data !== \"object\") return false;\n const d = data as Record<string, unknown>;\n if (!Array.isArray(d.skills)) return false;\n return d.skills.every(isValidSkillEntry);\n}\n\n// =============================================================================\n// Fetching\n// =============================================================================\n\n/**\n * Fetch the well-known index from a URL.\n *\n * Tries path-relative first, then root:\n * 1. {baseUrl}/.well-known/skills/index.json\n * 2. {protocol}://{host}/.well-known/skills/index.json\n */\nexport async function fetchWellKnownIndex(\n baseUrl: string,\n): Promise<{ index: WellKnownIndex; resolvedBaseUrl: string } | null> {\n const parsed = new URL(baseUrl);\n\n // Try 1: path-relative\n const pathRelativeUrl = `${baseUrl.replace(/\\/$/, \"\")}/${WELL_KNOWN_PATH}/${INDEX_FILE}`;\n const pathRelativeBase = `${baseUrl.replace(/\\/$/, \"\")}/${WELL_KNOWN_PATH}`;\n\n try {\n const response = await fetch(pathRelativeUrl, {\n signal: AbortSignal.timeout(10000),\n });\n if (response.ok) {\n const data = await response.json();\n if (isValidIndex(data)) {\n return { index: data, resolvedBaseUrl: pathRelativeBase };\n }\n }\n } catch {\n // Try next\n }\n\n // Try 2: root well-known (skip if URL has no path)\n const rootUrl = `${parsed.protocol}//${parsed.host}/${WELL_KNOWN_PATH}/${INDEX_FILE}`;\n const rootBase = `${parsed.protocol}//${parsed.host}/${WELL_KNOWN_PATH}`;\n\n // Avoid duplicate request if path-relative already tried the root\n if (rootUrl !== pathRelativeUrl) {\n try {\n const response = await fetch(rootUrl, {\n signal: AbortSignal.timeout(10000),\n });\n if (response.ok) {\n const data = await response.json();\n if (isValidIndex(data)) {\n return { index: data, resolvedBaseUrl: rootBase };\n }\n }\n } catch {\n // No index found\n }\n }\n\n return null;\n}\n\n/**\n * Fetch a single skill's files from a well-known endpoint.\n */\nasync function fetchSkillFiles(\n baseUrl: string,\n entry: WellKnownSkillEntry,\n): Promise<WellKnownSkill | null> {\n const skillBaseUrl = `${baseUrl}/${entry.name}`;\n const files = new Map<string, string>();\n let skillMdContent = \"\";\n\n // Fetch all files in parallel\n const results = await Promise.allSettled(\n entry.files.map(async (filePath) => {\n const fileUrl = `${skillBaseUrl}/${filePath}`;\n const response = await fetch(fileUrl, {\n signal: AbortSignal.timeout(10000),\n });\n if (!response.ok) {\n throw new Error(`Failed to fetch ${fileUrl}: ${response.status}`);\n }\n const content = await response.text();\n return { filePath, content };\n }),\n );\n\n for (const result of results) {\n if (result.status === \"fulfilled\") {\n files.set(result.value.filePath, result.value.content);\n if (result.value.filePath.toLowerCase() === \"skill.md\") {\n skillMdContent = result.value.content;\n }\n }\n // Skip failed files (non-fatal except SKILL.md)\n }\n\n // SKILL.md is required\n if (!skillMdContent) {\n return null;\n }\n\n return {\n name: entry.name,\n description: entry.description,\n content: skillMdContent,\n files,\n sourceUrl: `${skillBaseUrl}/SKILL.md`,\n indexEntry: entry,\n };\n}\n\n/**\n * Fetch all skills from a well-known endpoint.\n */\nexport async function fetchWellKnownSkills(\n url: string,\n): Promise<WellKnownDownloadResult | null> {\n const result = await fetchWellKnownIndex(url);\n if (!result) return null;\n\n const { index, resolvedBaseUrl } = result;\n const hostname = getWellKnownHostname(url);\n\n // Fetch all skills in parallel\n const skillResults = await Promise.allSettled(\n index.skills.map((entry) => fetchSkillFiles(resolvedBaseUrl, entry)),\n );\n\n const skills: WellKnownSkill[] = [];\n for (const r of skillResults) {\n if (r.status === \"fulfilled\" && r.value) {\n skills.push(r.value);\n }\n }\n\n if (skills.length === 0) return null;\n\n return { skills, resolvedBaseUrl, hostname };\n}\n\n// =============================================================================\n// Extraction\n// =============================================================================\n\n/**\n * Extract a well-known skill to the .pspm/skills/_wellknown/ directory.\n *\n * @param skill - The fetched skill\n * @param hostname - Source hostname (for directory namespacing)\n * @param skillsDir - Base skills directory (.pspm/skills)\n * @returns Path to extracted skill (relative to project root)\n */\nexport async function extractWellKnownSkill(\n skill: WellKnownSkill,\n hostname: string,\n skillsDir: string,\n): Promise<string> {\n const destPath = join(skillsDir, \"_wellknown\", hostname, skill.name);\n\n // Clean and recreate\n await rm(destPath, { recursive: true, force: true });\n await mkdir(destPath, { recursive: true });\n\n // Write all files\n for (const [filePath, content] of skill.files) {\n // Security: validate path doesn't escape\n const fullPath = join(destPath, filePath);\n if (!fullPath.startsWith(destPath)) {\n continue; // Skip files that would escape the directory\n }\n\n // Create parent directories\n const { dirname } = await import(\"node:path\");\n await mkdir(dirname(fullPath), { recursive: true });\n await writeFile(fullPath, content, \"utf-8\");\n }\n\n return `.pspm/skills/_wellknown/${hostname}/${skill.name}`;\n}\n\n/**\n * Calculate integrity hash for a well-known skill (hash of all file contents).\n */\nexport function calculateWellKnownIntegrity(skill: WellKnownSkill): string {\n // Sort files by path for deterministic hashing\n const sortedEntries = [...skill.files.entries()].sort(([a], [b]) =>\n a.localeCompare(b),\n );\n const combined = sortedEntries\n .map(([path, content]) => `${path}:${content}`)\n .join(\"\\n\");\n return calculateIntegrity(Buffer.from(combined, \"utf-8\"));\n}\n\n/**\n * Get display name for a well-known skill.\n */\nexport function getWellKnownDisplayName(\n hostname: string,\n skillName: string,\n): string {\n return `${hostname}/${skillName} (well-known)`;\n}\n","import { homedir } from \"node:os\";\nimport { isGlobalMode } from \"@/config\";\nimport {\n isGitHubShorthand,\n isGitHubSpecifier,\n isGitHubUrl,\n type NamespaceType,\n parseGitHubShorthand,\n parseGitHubSpecifier,\n parseGitHubUrl,\n} from \"@/lib/index\";\nimport type { WellKnownSkill } from \"@/wellknown\";\n\nexport interface AddOptions {\n save?: boolean;\n agent?: string;\n yes?: boolean;\n /** Install globally (to ~/.pspm/ with global agent paths) */\n global?: boolean;\n}\n\nexport interface InternalAddOptions extends AddOptions {\n resolvedAgents: string[];\n}\n\nexport interface InternalAddOptionsWithDirect extends InternalAddOptions {\n /** Whether this is a direct dependency (from command line) */\n isDirect: boolean;\n}\n\n/** Resolved package info from validation phase */\nexport interface ResolvedRegistryPackage {\n type: \"registry\";\n specifier: string;\n namespace: NamespaceType;\n owner: string;\n name: string;\n /** Skill name within repo (only for @github namespace) */\n subname?: string;\n versionRange: string | undefined;\n resolvedVersion: string;\n versionInfo: {\n downloadUrl: string;\n checksum: string;\n };\n}\n\nexport interface ResolvedGitHubPackage {\n type: \"github\";\n specifier: string;\n parsed: ReturnType<typeof parseGitHubSpecifier> & object;\n ref: string;\n downloadResult: {\n buffer: Buffer;\n commit: string;\n integrity: string;\n };\n}\n\nexport interface ResolvedLocalPackage {\n type: \"local\";\n /** Original specifier (e.g., \"file:../my-skill\" or \"../my-skill\") */\n specifier: string;\n /** Normalized specifier with file: prefix */\n normalizedSpecifier: string;\n /** Original path from specifier */\n path: string;\n /** Resolved absolute path */\n resolvedPath: string;\n /** Skill name (last segment of path) */\n name: string;\n}\n\nexport interface ResolvedWellKnownPackage {\n type: \"wellknown\";\n specifier: string;\n hostname: string;\n skills: WellKnownSkill[];\n resolvedBaseUrl: string;\n}\n\nexport type ResolvedPackage =\n | ResolvedRegistryPackage\n | ResolvedGitHubPackage\n | ResolvedLocalPackage\n | ResolvedWellKnownPackage;\n\n/**\n * Check if a specifier is a local file reference.\n */\nexport function isLocalSpecifier(specifier: string): boolean {\n return (\n specifier.startsWith(\"file:\") ||\n specifier.startsWith(\"./\") ||\n specifier.startsWith(\"../\")\n );\n}\n\n/**\n * Parse a local specifier and return the path.\n */\nexport function parseLocalPath(specifier: string): string {\n if (specifier.startsWith(\"file:\")) {\n return specifier.slice(5);\n }\n return specifier;\n}\n\n/**\n * Normalize a path to a file: specifier.\n */\nexport function normalizeToFileSpecifier(path: string): string {\n if (path.startsWith(\"file:\")) {\n return path;\n }\n return `file:${path}`;\n}\n\n/**\n * Get the root directory for symlink creation.\n * Global: home directory. Project: current working directory.\n */\nexport function getSymlinkRoot(): string {\n return isGlobalMode() ? homedir() : process.cwd();\n}\n\n/**\n * Parse any GitHub input format into a GitHubSpecifier.\n *\n * Accepts:\n * - github:owner/repo[/path][@ref] (canonical prefix format)\n * - https://github.com/owner/repo (full URL)\n * - https://github.com/owner/repo/tree/branch/path (tree URL)\n * - owner/repo[/path] (shorthand)\n */\nexport function parseAnyGitHubFormat(\n specifier: string,\n): ReturnType<typeof parseGitHubSpecifier> {\n if (isGitHubSpecifier(specifier)) {\n return parseGitHubSpecifier(specifier);\n }\n if (isGitHubUrl(specifier)) {\n return parseGitHubUrl(specifier);\n }\n if (isGitHubShorthand(specifier)) {\n return parseGitHubShorthand(specifier);\n }\n return null;\n}\n","import { getSkillsDir, isGlobalMode } from \"@/config\";\nimport {\n downloadGitHubPackage,\n extractGitHubPackage,\n getGitHubDisplayName,\n} from \"@/github\";\nimport {\n formatGitHubSpecifier,\n type GitHubLockfileEntry,\n getGitHubSkillName,\n} from \"@/lib/index\";\nimport { addGitHubToLockfile } from \"@/lockfile\";\nimport { addGitHubDependency, readManifest } from \"@/manifest\";\nimport {\n createAgentSymlinks,\n getGitHubSkillPath,\n type SkillInfo,\n} from \"@/symlinks\";\nimport {\n getSymlinkRoot,\n type InternalAddOptions,\n parseAnyGitHubFormat,\n type ResolvedGitHubPackage,\n} from \"./add-helpers\";\n\n/**\n * Validate and download a GitHub package.\n */\nexport async function validateGitHubPackage(\n specifier: string,\n): Promise<ResolvedGitHubPackage> {\n const parsed = parseAnyGitHubFormat(specifier);\n if (!parsed) {\n throw new Error(\n `Invalid GitHub specifier \"${specifier}\". Supported formats:\\n` +\n ` github:owner/repo[/path][@ref]\\n` +\n ` https://github.com/owner/repo[/tree/branch/path]\\n` +\n ` owner/repo[/path]`,\n );\n }\n\n const ref = parsed.ref || \"HEAD\";\n console.log(`Resolving ${getGitHubDisplayName(parsed)}...`);\n\n const result = await downloadGitHubPackage(parsed);\n\n console.log(`Resolved ${specifier} (${ref}@${result.commit.slice(0, 7)})`);\n\n return {\n type: \"github\",\n specifier,\n parsed,\n ref,\n downloadResult: result,\n };\n}\n\n/**\n * Install a pre-validated GitHub package.\n */\nexport async function installGitHubPackage(\n resolved: ResolvedGitHubPackage,\n options: InternalAddOptions,\n): Promise<void> {\n const { specifier, parsed, ref, downloadResult } = resolved;\n\n console.log(\n `Installing ${specifier} (${ref}@${downloadResult.commit.slice(0, 7)})...`,\n );\n\n const skillsDir = getSkillsDir();\n const destPath = await extractGitHubPackage(\n parsed,\n downloadResult.buffer,\n skillsDir,\n );\n\n const lockfileSpecifier = formatGitHubSpecifier({\n owner: parsed.owner,\n repo: parsed.repo,\n path: parsed.path,\n });\n\n const entry: GitHubLockfileEntry = {\n version: downloadResult.commit.slice(0, 7),\n resolved: `https://github.com/${parsed.owner}/${parsed.repo}`,\n integrity: downloadResult.integrity,\n gitCommit: downloadResult.commit,\n gitRef: ref,\n };\n\n await addGitHubToLockfile(lockfileSpecifier, entry);\n await addGitHubDependency(lockfileSpecifier, ref);\n\n const agents = options.resolvedAgents;\n if (agents[0] !== \"none\") {\n const manifest = await readManifest();\n const skillName = getGitHubSkillName(parsed);\n const skillInfo: SkillInfo = {\n name: skillName,\n sourcePath: getGitHubSkillPath(parsed.owner, parsed.repo, parsed.path),\n };\n\n await createAgentSymlinks([skillInfo], {\n agents,\n projectRoot: getSymlinkRoot(),\n agentConfigs: manifest?.agents,\n global: isGlobalMode(),\n });\n }\n\n console.log(\n `Installed ${specifier} (${ref}@${downloadResult.commit.slice(0, 7)})`,\n );\n console.log(`Location: ${destPath}`);\n}\n","import { mkdir, rm, stat, symlink } from \"node:fs/promises\";\nimport { basename, dirname, join, relative, resolve } from \"node:path\";\nimport { getSkillsDir, isGlobalMode } from \"@/config\";\nimport type { LocalLockfileEntry } from \"@/lib/index\";\nimport { addLocalToLockfile } from \"@/lockfile\";\nimport { addLocalDependency, readManifest } from \"@/manifest\";\nimport {\n createAgentSymlinks,\n getLocalSkillPath,\n type SkillInfo,\n} from \"@/symlinks\";\nimport {\n getSymlinkRoot,\n type InternalAddOptions,\n normalizeToFileSpecifier,\n parseLocalPath,\n type ResolvedLocalPackage,\n} from \"./add-helpers\";\n\n/**\n * Validate a local package path exists and contains a valid skill.\n */\nexport async function validateLocalPackage(\n specifier: string,\n): Promise<ResolvedLocalPackage> {\n const path = parseLocalPath(specifier);\n const resolvedPath = resolve(process.cwd(), path);\n const normalizedSpecifier = normalizeToFileSpecifier(path);\n\n console.log(`Resolving ${specifier}...`);\n\n try {\n const stats = await stat(resolvedPath);\n if (!stats.isDirectory()) {\n throw new Error(`Path is not a directory: ${resolvedPath}`);\n }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n throw new Error(\n `Directory not found: ${resolvedPath}\\n Check that the path exists and is accessible.`,\n );\n }\n throw error;\n }\n\n let hasSkillMd = false;\n let hasPspmJson = false;\n\n try {\n await stat(join(resolvedPath, \"SKILL.md\"));\n hasSkillMd = true;\n } catch {\n // SKILL.md not found\n }\n\n try {\n await stat(join(resolvedPath, \"pspm.json\"));\n hasPspmJson = true;\n } catch {\n // pspm.json not found\n }\n\n if (!hasSkillMd && !hasPspmJson) {\n throw new Error(\n `Not a valid skill directory: ${resolvedPath}\\n Missing both SKILL.md and pspm.json. At least one is required.`,\n );\n }\n\n const name = basename(resolvedPath);\n\n console.log(`Resolved ${specifier} -> ${resolvedPath}`);\n\n return {\n type: \"local\",\n specifier,\n normalizedSpecifier,\n path,\n resolvedPath,\n name,\n };\n}\n\n/**\n * Install a local package by creating a symlink.\n */\nexport async function installLocalPackage(\n resolved: ResolvedLocalPackage,\n options: InternalAddOptions,\n): Promise<void> {\n const { specifier, normalizedSpecifier, path, resolvedPath, name } = resolved;\n\n console.log(`Installing ${specifier}...`);\n\n const skillsDir = getSkillsDir();\n const localSkillsDir = join(skillsDir, \"_local\");\n await mkdir(localSkillsDir, { recursive: true });\n\n const symlinkPath = join(localSkillsDir, name);\n const relativeTarget = relative(dirname(symlinkPath), resolvedPath);\n\n try {\n await rm(symlinkPath, { force: true });\n } catch {\n // Ignore errors\n }\n\n await symlink(relativeTarget, symlinkPath);\n\n const entry: LocalLockfileEntry = {\n version: \"local\",\n path,\n resolvedPath,\n name,\n };\n await addLocalToLockfile(normalizedSpecifier, entry);\n await addLocalDependency(normalizedSpecifier);\n\n const agents = options.resolvedAgents;\n if (agents[0] !== \"none\") {\n const manifest = await readManifest();\n const skillInfo: SkillInfo = {\n name,\n sourcePath: getLocalSkillPath(name),\n };\n\n await createAgentSymlinks([skillInfo], {\n agents,\n projectRoot: getSymlinkRoot(),\n agentConfigs: manifest?.agents,\n global: isGlobalMode(),\n });\n }\n\n console.log(`Installed ${specifier} (local)`);\n console.log(`Location: ${symlinkPath} -> ${resolvedPath}`);\n}\n","import { mkdir, rm } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport {\n configure,\n getGithubSkillVersion,\n getSkillVersion,\n listGithubSkillVersions,\n listSkillVersions,\n} from \"@/api-client\";\nimport {\n getSkillsDir,\n getTokenForRegistry,\n isGlobalMode,\n resolveConfig,\n} from \"@/config\";\nimport { extractApiErrorMessage } from \"@/errors\";\nimport {\n calculateIntegrity,\n type DependencyNode,\n generateRegistryIdentifier,\n parseRegistrySpecifier,\n resolveVersion,\n} from \"@/lib/index\";\nimport { addToLockfileWithDeps } from \"@/lockfile\";\nimport { addDependency, readManifest } from \"@/manifest\";\nimport {\n createAgentSymlinks,\n getRegistrySkillPath,\n type SkillInfo,\n} from \"@/symlinks\";\nimport {\n getSymlinkRoot,\n type InternalAddOptionsWithDirect,\n type ResolvedRegistryPackage,\n} from \"./add-helpers\";\n\n/**\n * Validate and resolve a registry package (without downloading).\n */\nexport async function validateRegistryPackage(\n specifier: string,\n): Promise<ResolvedRegistryPackage> {\n const config = await resolveConfig();\n const registryUrl = config.registryUrl;\n const apiKey = getTokenForRegistry(config, registryUrl);\n\n const parsed = parseRegistrySpecifier(specifier);\n if (!parsed) {\n throw new Error(\n `Invalid skill specifier \"${specifier}\". Use format: @user/{username}/{name}[@{version}] or @org/{orgname}/{name}[@{version}]`,\n );\n }\n\n const { namespace, owner, name, subname, versionRange } = parsed;\n const fullName = generateRegistryIdentifier({\n namespace,\n owner,\n name,\n subname,\n });\n\n configure({ registryUrl, apiKey });\n\n console.log(`Resolving ${specifier}...`);\n\n const versions = await fetchRegistryVersions(\n namespace,\n owner,\n name,\n subname,\n fullName,\n apiKey,\n );\n\n const versionStrings = versions.map((v: { version: string }) => v.version);\n const resolvedVersion = resolveVersion(versionRange || \"*\", versionStrings);\n\n if (!resolvedVersion) {\n throw new Error(\n `No version matching \"${versionRange || \"latest\"}\" found for ${fullName}. Available versions: ${versionStrings.join(\", \")}`,\n );\n }\n\n const { downloadUrl, checksum } = await fetchRegistryVersionInfo(\n namespace,\n owner,\n name,\n subname,\n resolvedVersion,\n fullName,\n );\n\n console.log(`Resolved ${fullName}@${resolvedVersion}`);\n\n return {\n type: \"registry\",\n specifier,\n namespace,\n owner,\n name,\n subname,\n versionRange,\n resolvedVersion,\n versionInfo: { downloadUrl, checksum },\n };\n}\n\nasync function fetchRegistryVersions(\n namespace: string,\n owner: string,\n name: string,\n subname: string | undefined,\n fullName: string,\n apiKey: string | undefined,\n): Promise<{ version: string }[]> {\n if (namespace === \"github\" && subname) {\n const versionsResponse = await listGithubSkillVersions(\n owner,\n name,\n subname,\n );\n if (versionsResponse.status !== 200 || !versionsResponse.data) {\n if (versionsResponse.status === 401) {\n throw new Error(\n apiKey\n ? `Access denied to ${fullName}. You may not have permission to access this private package.`\n : `Package ${fullName} requires authentication. Please run 'pspm login' to authenticate`,\n );\n }\n throw new Error(versionsResponse.error || `Skill ${fullName} not found`);\n }\n return versionsResponse.data;\n }\n\n const versionsResponse = await listSkillVersions(owner, name);\n if (versionsResponse.status !== 200) {\n if (versionsResponse.status === 401) {\n if (!apiKey) {\n throw new Error(\n `Package ${fullName} requires authentication. Please run 'pspm login' to authenticate`,\n );\n }\n throw new Error(\n `Access denied to ${fullName}. You may not have permission to access this private package.`,\n );\n }\n const errorMessage = extractApiErrorMessage(\n versionsResponse,\n `Skill ${fullName} not found`,\n );\n throw new Error(errorMessage);\n }\n if (versionsResponse.data.length === 0) {\n throw new Error(`Skill ${fullName} not found`);\n }\n return versionsResponse.data;\n}\n\nasync function fetchRegistryVersionInfo(\n namespace: string,\n owner: string,\n name: string,\n subname: string | undefined,\n resolvedVersion: string,\n fullName: string,\n): Promise<{ downloadUrl: string; checksum: string }> {\n if (namespace === \"github\" && subname) {\n const versionResponse = await getGithubSkillVersion(\n owner,\n name,\n subname,\n resolvedVersion,\n );\n if (versionResponse.status !== 200 || !versionResponse.data) {\n throw new Error(`Version ${resolvedVersion} not found for ${fullName}`);\n }\n return {\n downloadUrl: versionResponse.data.downloadUrl,\n checksum: versionResponse.data.checksum,\n };\n }\n const versionResponse = await getSkillVersion(owner, name, resolvedVersion);\n if (versionResponse.status !== 200 || !versionResponse.data) {\n const errorMessage = extractApiErrorMessage(\n versionResponse,\n `Version ${resolvedVersion} not found`,\n );\n throw new Error(errorMessage);\n }\n return {\n downloadUrl: versionResponse.data.downloadUrl,\n checksum: versionResponse.data.checksum,\n };\n}\n\n/**\n * Install a package from a DependencyNode (resolved from resolver).\n */\nexport async function installFromNode(\n node: DependencyNode,\n options: InternalAddOptionsWithDirect,\n): Promise<void> {\n const parsed = parseRegistrySpecifier(node.name);\n if (!parsed) {\n throw new Error(`Invalid package name: ${node.name}`);\n }\n const { namespace, owner, name, subname } = parsed;\n\n console.log(`Installing ${node.name}@${node.version}...`);\n\n const config = await resolveConfig();\n const apiKey = getTokenForRegistry(config, config.registryUrl);\n\n const tarballBuffer = await downloadNodeTarball(node, apiKey);\n const integrity = calculateIntegrity(tarballBuffer);\n if (integrity !== node.integrity) {\n throw new Error(\"Checksum verification failed\");\n }\n\n const skillsDir = getSkillsDir();\n const effectiveSkillName = subname ?? name;\n const destDir = resolveRegistryDestDir(\n namespace,\n owner,\n name,\n subname,\n effectiveSkillName,\n skillsDir,\n );\n await extractRegistryTarball(destDir, tarballBuffer);\n\n const resolvedDeps: Record<string, string> = {};\n for (const [depName, range] of Object.entries(node.dependencies)) {\n resolvedDeps[depName] = range;\n }\n\n await addToLockfileWithDeps(\n node.name,\n {\n version: node.version,\n resolved: node.downloadUrl,\n integrity,\n deprecated: node.deprecated,\n },\n Object.keys(resolvedDeps).length > 0 ? resolvedDeps : undefined,\n );\n\n if (options.isDirect) {\n const dependencyRange = node.versionRange || `^${node.version}`;\n await addDependency(node.name, dependencyRange);\n }\n\n const agents = options.resolvedAgents;\n if (agents[0] !== \"none\") {\n const skillManifest = await readManifest();\n const pathSkillName =\n namespace === \"github\" && subname ? `${name}/${subname}` : name;\n const skillInfo: SkillInfo = {\n name: effectiveSkillName,\n sourcePath: getRegistrySkillPath(namespace, owner, pathSkillName),\n };\n\n await createAgentSymlinks([skillInfo], {\n agents,\n projectRoot: getSymlinkRoot(),\n agentConfigs: skillManifest?.agents,\n global: isGlobalMode(),\n });\n }\n\n console.log(`Installed ${node.name}@${node.version}`);\n console.log(`Location: ${destDir}`);\n}\n\nasync function downloadNodeTarball(\n node: DependencyNode,\n apiKey: string | undefined,\n): Promise<Buffer> {\n const isPresignedUrl =\n node.downloadUrl.includes(\".r2.cloudflarestorage.com\") ||\n node.downloadUrl.includes(\"X-Amz-Signature\");\n\n const downloadHeaders: Record<string, string> = {};\n if (!isPresignedUrl && apiKey) {\n downloadHeaders.Authorization = `Bearer ${apiKey}`;\n }\n\n const tarballResponse = await fetch(node.downloadUrl, {\n headers: downloadHeaders,\n redirect: \"follow\",\n });\n\n if (!tarballResponse.ok) {\n throw new Error(`Failed to download tarball (${tarballResponse.status})`);\n }\n\n return Buffer.from(await tarballResponse.arrayBuffer());\n}\n\nfunction resolveRegistryDestDir(\n namespace: string,\n owner: string,\n name: string,\n subname: string | undefined,\n effectiveSkillName: string,\n skillsDir: string,\n): string {\n if (namespace === \"org\") {\n return join(skillsDir, \"_org\", owner, effectiveSkillName);\n }\n if (namespace === \"github\" && subname) {\n return join(skillsDir, \"_github-registry\", owner, name, subname);\n }\n return join(skillsDir, owner, effectiveSkillName);\n}\n\nasync function extractRegistryTarball(\n destDir: string,\n tarballBuffer: Buffer,\n): Promise<void> {\n await rm(destDir, { recursive: true, force: true });\n await mkdir(destDir, { recursive: true });\n\n const { writeFile } = await import(\"node:fs/promises\");\n const tempFile = join(destDir, \".temp.tgz\");\n await writeFile(tempFile, tarballBuffer);\n\n const { exec } = await import(\"node:child_process\");\n const { promisify } = await import(\"node:util\");\n const execAsync = promisify(exec);\n\n try {\n await execAsync(\n `tar -xzf \"${tempFile}\" -C \"${destDir}\" --strip-components=1`,\n );\n } finally {\n await rm(tempFile, { force: true });\n }\n}\n","import { getSkillsDir } from \"@/config\";\nimport type { WellKnownLockfileEntry } from \"@/lib/index\";\nimport { addWellKnownToLockfile } from \"@/lockfile\";\nimport { addWellKnownDependency, readManifest } from \"@/manifest\";\nimport {\n createAgentSymlinks,\n getWellKnownSkillPath,\n type SkillInfo,\n} from \"@/symlinks\";\nimport {\n calculateWellKnownIntegrity,\n extractWellKnownSkill,\n fetchWellKnownSkills,\n getWellKnownDisplayName,\n getWellKnownHostname,\n} from \"@/wellknown\";\nimport type {\n InternalAddOptions,\n ResolvedWellKnownPackage,\n} from \"./add-helpers\";\n\n/**\n * Validate and fetch skills from a well-known endpoint.\n */\nexport async function validateWellKnownPackage(\n specifier: string,\n): Promise<ResolvedWellKnownPackage> {\n const hostname = getWellKnownHostname(specifier);\n console.log(`Discovering skills from ${hostname}...`);\n\n const result = await fetchWellKnownSkills(specifier);\n if (!result) {\n throw new Error(\n `No well-known skills found at ${specifier}\\n Expected: ${specifier}/.well-known/skills/index.json`,\n );\n }\n\n console.log(\n `Found ${result.skills.length} skill(s) from ${hostname}: ${result.skills.map((s) => s.name).join(\", \")}`,\n );\n\n return {\n type: \"wellknown\",\n specifier,\n hostname: result.hostname,\n skills: result.skills,\n resolvedBaseUrl: result.resolvedBaseUrl,\n };\n}\n\n/**\n * Install pre-validated well-known skills.\n */\nexport async function installWellKnownPackage(\n resolved: ResolvedWellKnownPackage,\n options: InternalAddOptions,\n): Promise<void> {\n const { specifier, hostname, skills } = resolved;\n const skillsDir = getSkillsDir();\n\n for (const skill of skills) {\n console.log(\n `Installing ${getWellKnownDisplayName(hostname, skill.name)}...`,\n );\n\n const destPath = await extractWellKnownSkill(skill, hostname, skillsDir);\n const integrity = calculateWellKnownIntegrity(skill);\n\n const lockfileKey = `${specifier}#${skill.name}`;\n const entry: WellKnownLockfileEntry = {\n version: \"well-known\",\n resolved: skill.sourceUrl,\n integrity,\n hostname,\n name: skill.name,\n files: [...skill.files.keys()],\n };\n await addWellKnownToLockfile(lockfileKey, entry);\n await addWellKnownDependency(specifier, [skill.name]);\n\n const agents = options.resolvedAgents;\n if (agents[0] !== \"none\") {\n const manifest = await readManifest();\n const skillInfo: SkillInfo = {\n name: skill.name,\n sourcePath: getWellKnownSkillPath(hostname, skill.name),\n };\n\n await createAgentSymlinks([skillInfo], {\n agents,\n projectRoot: process.cwd(),\n agentConfigs: manifest?.agents,\n });\n }\n\n console.log(`Installed ${getWellKnownDisplayName(hostname, skill.name)}`);\n console.log(`Location: ${destPath}`);\n }\n}\n","import { parseAgentArg, promptForAgents } from \"@/agents\";\nimport { getTokenForRegistry, resolveConfig, setGlobalMode } from \"@/config\";\nimport {\n generateRegistryIdentifier,\n isGitHubShorthand,\n isGitHubSpecifier,\n isGitHubUrl,\n isRegistrySpecifier,\n MAX_DEPENDENCY_DEPTH,\n printResolutionErrors,\n resolveRecursive,\n} from \"@/lib/index\";\nimport { readManifest } from \"@/manifest\";\nimport { isWellKnownSpecifier } from \"@/wellknown\";\nimport { installGitHubPackage, validateGitHubPackage } from \"./add-github\";\nimport {\n type AddOptions,\n isLocalSpecifier,\n type ResolvedGitHubPackage,\n type ResolvedLocalPackage,\n type ResolvedPackage,\n type ResolvedRegistryPackage,\n type ResolvedWellKnownPackage,\n} from \"./add-helpers\";\nimport { installLocalPackage, validateLocalPackage } from \"./add-local\";\nimport { installFromNode, validateRegistryPackage } from \"./add-registry\";\nimport {\n installWellKnownPackage,\n validateWellKnownPackage,\n} from \"./add-wellknown\";\n\nexport type { AddOptions };\n\nexport async function add(\n specifiers: string[],\n options: AddOptions,\n): Promise<void> {\n if (options.global) {\n setGlobalMode(true);\n console.log(\"Installing globally to ~/.pspm/\\n\");\n }\n\n console.log(\"Resolving packages...\\n\");\n\n const { resolvedPackages, validationErrors } =\n await validateAllPackages(specifiers);\n\n if (resolvedPackages.length === 0) {\n console.error(\"No packages could be resolved.\");\n process.exit(1);\n }\n\n if (validationErrors.length > 0) {\n console.log(\n `Resolved ${resolvedPackages.length} of ${specifiers.length} packages.\\n`,\n );\n }\n\n const config = await resolveConfig();\n const apiKey = getTokenForRegistry(config, config.registryUrl);\n\n const registryPackages = resolvedPackages.filter(\n (p): p is ResolvedRegistryPackage => p.type === \"registry\",\n );\n const githubPackages = resolvedPackages.filter(\n (p): p is ResolvedGitHubPackage => p.type === \"github\",\n );\n const localPackages = resolvedPackages.filter(\n (p): p is ResolvedLocalPackage => p.type === \"local\",\n );\n const wellKnownPackages = resolvedPackages.filter(\n (p): p is ResolvedWellKnownPackage => p.type === \"wellknown\",\n );\n\n let resolutionResult: Awaited<ReturnType<typeof resolveRecursive>> | null =\n null;\n\n if (registryPackages.length > 0) {\n const rootDeps: Record<string, string> = {};\n for (const pkg of registryPackages) {\n const fullName = generateRegistryIdentifier({\n namespace: pkg.namespace,\n owner: pkg.owner,\n name: pkg.name,\n subname: pkg.subname,\n });\n rootDeps[fullName] = pkg.versionRange || `^${pkg.resolvedVersion}`;\n }\n\n console.log(\"Resolving dependencies...\");\n resolutionResult = await resolveRecursive(rootDeps, {\n maxDepth: MAX_DEPENDENCY_DEPTH,\n registryUrl: config.registryUrl,\n apiKey,\n });\n\n if (!resolutionResult.success) {\n printResolutionErrors(\n resolutionResult.graph.errors,\n resolutionResult.graph.conflicts,\n );\n process.exit(1);\n }\n\n const transitiveDeps = resolutionResult.installOrder.filter(\n (name) => !rootDeps[name],\n );\n if (transitiveDeps.length > 0) {\n console.log(\n `Resolved ${transitiveDeps.length} transitive dependencies.\\n`,\n );\n } else {\n console.log();\n }\n }\n\n const agents = await resolveAgents(options);\n\n const results: { specifier: string; success: boolean; error?: string }[] = [];\n\n if (resolutionResult) {\n for (const name of resolutionResult.installOrder) {\n const node = resolutionResult.graph.nodes.get(name);\n if (!node) continue;\n\n try {\n await installFromNode(node, {\n ...options,\n resolvedAgents: agents,\n isDirect: node.isDirect,\n });\n results.push({ specifier: name, success: true });\n } catch (error) {\n const message =\n error instanceof Error ? error.message : \"Unknown error\";\n results.push({ specifier: name, success: false, error: message });\n console.error(`Failed to install ${name}: ${message}\\n`);\n }\n }\n }\n\n for (const resolved of githubPackages) {\n try {\n await installGitHubPackage(resolved, {\n ...options,\n resolvedAgents: agents,\n });\n results.push({ specifier: resolved.specifier, success: true });\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n results.push({\n specifier: resolved.specifier,\n success: false,\n error: message,\n });\n console.error(`Failed to install ${resolved.specifier}: ${message}\\n`);\n }\n }\n\n for (const resolved of localPackages) {\n try {\n await installLocalPackage(resolved, {\n ...options,\n resolvedAgents: agents,\n });\n results.push({ specifier: resolved.specifier, success: true });\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n results.push({\n specifier: resolved.specifier,\n success: false,\n error: message,\n });\n console.error(`Failed to install ${resolved.specifier}: ${message}\\n`);\n }\n }\n\n for (const resolved of wellKnownPackages) {\n try {\n await installWellKnownPackage(resolved, {\n ...options,\n resolvedAgents: agents,\n });\n results.push({ specifier: resolved.specifier, success: true });\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n results.push({\n specifier: resolved.specifier,\n success: false,\n error: message,\n });\n console.error(`Failed to install ${resolved.specifier}: ${message}\\n`);\n }\n }\n\n if (specifiers.length > 1) {\n const succeeded = results.filter((r) => r.success).length;\n const failed =\n results.filter((r) => !r.success).length + validationErrors.length;\n console.log(`\\nSummary: ${succeeded} added, ${failed} failed`);\n\n if (failed > 0) {\n process.exit(1);\n }\n }\n}\n\nasync function validateAllPackages(specifiers: string[]): Promise<{\n resolvedPackages: ResolvedPackage[];\n validationErrors: { specifier: string; error: string }[];\n}> {\n const resolvedPackages: ResolvedPackage[] = [];\n const validationErrors: { specifier: string; error: string }[] = [];\n\n for (const specifier of specifiers) {\n try {\n if (isLocalSpecifier(specifier)) {\n resolvedPackages.push(await validateLocalPackage(specifier));\n } else if (\n isGitHubSpecifier(specifier) ||\n isGitHubUrl(specifier) ||\n isGitHubShorthand(specifier)\n ) {\n resolvedPackages.push(await validateGitHubPackage(specifier));\n } else if (isWellKnownSpecifier(specifier)) {\n resolvedPackages.push(await validateWellKnownPackage(specifier));\n } else if (isRegistrySpecifier(specifier)) {\n resolvedPackages.push(await validateRegistryPackage(specifier));\n } else {\n throw new Error(\n `Unknown specifier format \"${specifier}\". Supported formats:\\n` +\n ` @user/{username}/{name}[@version] (registry)\\n` +\n ` @org/{orgname}/{name}[@version] (organization)\\n` +\n ` github:owner/repo[/path][@ref] (github)\\n` +\n ` file:./path/to/skill (local)\\n` +\n ` owner/repo (github shorthand)`,\n );\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n validationErrors.push({ specifier, error: message });\n console.error(`Failed to resolve ${specifier}: ${message}\\n`);\n }\n }\n\n return { resolvedPackages, validationErrors };\n}\n\nasync function resolveAgents(options: AddOptions): Promise<string[]> {\n const manifest = await readManifest();\n if (options.agent) {\n return parseAgentArg(options.agent);\n }\n if (manifest) {\n return parseAgentArg(undefined);\n }\n if (options.yes) {\n return parseAgentArg(undefined);\n }\n console.log(\"No pspm.json found. Let's set up your project.\\n\");\n const agents = await promptForAgents();\n console.log();\n return agents;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,452 @@
|
|
|
1
|
+
//#region src/sdk/fetcher.ts
|
|
2
|
+
let config = null;
|
|
3
|
+
/**
|
|
4
|
+
* Configure the SDK with base URL and API key.
|
|
5
|
+
* Must be called before making any API requests.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { configure } from "./sdk/fetcher";
|
|
10
|
+
*
|
|
11
|
+
* configure({
|
|
12
|
+
* baseUrl: "http://localhost:5600",
|
|
13
|
+
* apiKey: "your-api-key"
|
|
14
|
+
* });
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
function configure$1(options) {
|
|
18
|
+
config = options;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Get the current SDK configuration.
|
|
22
|
+
* @throws Error if not configured
|
|
23
|
+
*/
|
|
24
|
+
function getConfig() {
|
|
25
|
+
if (!config) throw new Error("SDK not configured. Call configure() first.");
|
|
26
|
+
return config;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Custom fetch function for Orval
|
|
30
|
+
*
|
|
31
|
+
* This is used by all generated API functions to make HTTP requests.
|
|
32
|
+
* It handles authentication, error handling, and response parsing.
|
|
33
|
+
*
|
|
34
|
+
* Returns { data, status, headers } structure expected by Orval v8.
|
|
35
|
+
*/
|
|
36
|
+
async function customFetch(url, options) {
|
|
37
|
+
const { baseUrl, apiKey } = getConfig();
|
|
38
|
+
const fullUrl = `${baseUrl}${url}`;
|
|
39
|
+
const headers = {
|
|
40
|
+
...options.headers ?? {},
|
|
41
|
+
"Content-Type": "application/json"
|
|
42
|
+
};
|
|
43
|
+
if (apiKey) headers.Authorization = `Bearer ${apiKey}`;
|
|
44
|
+
const response = await fetch(fullUrl, {
|
|
45
|
+
...options,
|
|
46
|
+
headers
|
|
47
|
+
});
|
|
48
|
+
const text = await response.text();
|
|
49
|
+
let data = null;
|
|
50
|
+
if (text) try {
|
|
51
|
+
data = JSON.parse(text);
|
|
52
|
+
} catch {
|
|
53
|
+
data = text;
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
data,
|
|
57
|
+
status: response.status,
|
|
58
|
+
headers: response.headers
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
//#endregion
|
|
62
|
+
//#region src/sdk/generated/index.ts
|
|
63
|
+
/**
|
|
64
|
+
* Generated by orval v8.5.3 🍺
|
|
65
|
+
* Do not edit manually.
|
|
66
|
+
* PSPM API
|
|
67
|
+
* Backend API for PSPM - Performant Skill Package Manager for AI Agents
|
|
68
|
+
* OpenAPI spec version: 1.0.0
|
|
69
|
+
*/
|
|
70
|
+
const getMeUrl = () => {
|
|
71
|
+
return `/api/skills/-/me`;
|
|
72
|
+
};
|
|
73
|
+
const me = async (options) => {
|
|
74
|
+
return customFetch(getMeUrl(), {
|
|
75
|
+
...options,
|
|
76
|
+
method: "GET"
|
|
77
|
+
});
|
|
78
|
+
};
|
|
79
|
+
const getExplorePublicSkillsUrl = (params) => {
|
|
80
|
+
const normalizedParams = new URLSearchParams();
|
|
81
|
+
Object.entries(params || {}).forEach(([key, value]) => {
|
|
82
|
+
if (value !== void 0) normalizedParams.append(key, value === null ? "null" : value.toString());
|
|
83
|
+
});
|
|
84
|
+
const stringifiedParams = normalizedParams.toString();
|
|
85
|
+
return stringifiedParams.length > 0 ? `/api/skills/-/explore?${stringifiedParams}` : `/api/skills/-/explore`;
|
|
86
|
+
};
|
|
87
|
+
const explorePublicSkills = async (params, options) => {
|
|
88
|
+
return customFetch(getExplorePublicSkillsUrl(params), {
|
|
89
|
+
...options,
|
|
90
|
+
method: "GET"
|
|
91
|
+
});
|
|
92
|
+
};
|
|
93
|
+
const getDeleteSkillUrl = (username, name) => {
|
|
94
|
+
return `/api/skills/@user/${username}/${name}`;
|
|
95
|
+
};
|
|
96
|
+
const deleteSkill = async (username, name, options) => {
|
|
97
|
+
return customFetch(getDeleteSkillUrl(username, name), {
|
|
98
|
+
...options,
|
|
99
|
+
method: "DELETE"
|
|
100
|
+
});
|
|
101
|
+
};
|
|
102
|
+
const getListSkillVersionsUrl = (username, name) => {
|
|
103
|
+
return `/api/skills/@user/${username}/${name}/versions`;
|
|
104
|
+
};
|
|
105
|
+
const listSkillVersions = async (username, name, options) => {
|
|
106
|
+
return customFetch(getListSkillVersionsUrl(username, name), {
|
|
107
|
+
...options,
|
|
108
|
+
method: "GET"
|
|
109
|
+
});
|
|
110
|
+
};
|
|
111
|
+
const getGetSkillVersionUrl = (username, name, version) => {
|
|
112
|
+
return `/api/skills/@user/${username}/${name}/versions/${version}`;
|
|
113
|
+
};
|
|
114
|
+
const getSkillVersion = async (username, name, version, options) => {
|
|
115
|
+
return customFetch(getGetSkillVersionUrl(username, name, version), {
|
|
116
|
+
...options,
|
|
117
|
+
method: "GET"
|
|
118
|
+
});
|
|
119
|
+
};
|
|
120
|
+
const getDeleteSkillVersionUrl = (username, name, version) => {
|
|
121
|
+
return `/api/skills/@user/${username}/${name}/versions/${version}`;
|
|
122
|
+
};
|
|
123
|
+
const deleteSkillVersion = async (username, name, version, options) => {
|
|
124
|
+
return customFetch(getDeleteSkillVersionUrl(username, name, version), {
|
|
125
|
+
...options,
|
|
126
|
+
method: "DELETE"
|
|
127
|
+
});
|
|
128
|
+
};
|
|
129
|
+
const getPublishSkillUrl = () => {
|
|
130
|
+
return `/api/skills/-/publish`;
|
|
131
|
+
};
|
|
132
|
+
const publishSkill = async (publishSkillInput, options) => {
|
|
133
|
+
return customFetch(getPublishSkillUrl(), {
|
|
134
|
+
...options,
|
|
135
|
+
method: "POST",
|
|
136
|
+
headers: {
|
|
137
|
+
"Content-Type": "application/json",
|
|
138
|
+
...options?.headers
|
|
139
|
+
},
|
|
140
|
+
body: JSON.stringify(publishSkillInput)
|
|
141
|
+
});
|
|
142
|
+
};
|
|
143
|
+
const getDeleteOrgSkillUrl = (orgname, name) => {
|
|
144
|
+
return `/api/skills/@org/${orgname}/${name}`;
|
|
145
|
+
};
|
|
146
|
+
const deleteOrgSkill = async (orgname, name, options) => {
|
|
147
|
+
return customFetch(getDeleteOrgSkillUrl(orgname, name), {
|
|
148
|
+
...options,
|
|
149
|
+
method: "DELETE"
|
|
150
|
+
});
|
|
151
|
+
};
|
|
152
|
+
const getListOrgSkillVersionsUrl = (orgname, name) => {
|
|
153
|
+
return `/api/skills/@org/${orgname}/${name}/versions`;
|
|
154
|
+
};
|
|
155
|
+
const listOrgSkillVersions = async (orgname, name, options) => {
|
|
156
|
+
return customFetch(getListOrgSkillVersionsUrl(orgname, name), {
|
|
157
|
+
...options,
|
|
158
|
+
method: "GET"
|
|
159
|
+
});
|
|
160
|
+
};
|
|
161
|
+
const getGetOrgSkillVersionUrl = (orgname, name, version) => {
|
|
162
|
+
return `/api/skills/@org/${orgname}/${name}/versions/${version}`;
|
|
163
|
+
};
|
|
164
|
+
const getOrgSkillVersion = async (orgname, name, version, options) => {
|
|
165
|
+
return customFetch(getGetOrgSkillVersionUrl(orgname, name, version), {
|
|
166
|
+
...options,
|
|
167
|
+
method: "GET"
|
|
168
|
+
});
|
|
169
|
+
};
|
|
170
|
+
const getPublishOrgSkillUrl = (orgname) => {
|
|
171
|
+
return `/api/skills/@org/${orgname}/publish`;
|
|
172
|
+
};
|
|
173
|
+
const publishOrgSkill = async (orgname, publishSkillInput, options) => {
|
|
174
|
+
return customFetch(getPublishOrgSkillUrl(orgname), {
|
|
175
|
+
...options,
|
|
176
|
+
method: "POST",
|
|
177
|
+
headers: {
|
|
178
|
+
"Content-Type": "application/json",
|
|
179
|
+
...options?.headers
|
|
180
|
+
},
|
|
181
|
+
body: JSON.stringify(publishSkillInput)
|
|
182
|
+
});
|
|
183
|
+
};
|
|
184
|
+
//#endregion
|
|
185
|
+
//#region src/api-client.ts
|
|
186
|
+
/**
|
|
187
|
+
* API Client for PSPM CLI
|
|
188
|
+
*
|
|
189
|
+
* This module re-exports the SDK functions and provides the
|
|
190
|
+
* initialization logic for the CLI.
|
|
191
|
+
*/
|
|
192
|
+
/**
|
|
193
|
+
* Convert a registry URL to the base server URL for the SDK.
|
|
194
|
+
*
|
|
195
|
+
* The CLI stores registry URLs like "https://pspm.dev". This function
|
|
196
|
+
* normalizes the URL by removing any trailing /api/skills path if present
|
|
197
|
+
* (for backwards compatibility with older configs).
|
|
198
|
+
*/
|
|
199
|
+
function registryUrlToBaseUrl(registryUrl) {
|
|
200
|
+
return registryUrl.replace(/\/api\/skills\/?$/, "");
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Configure the SDK with registry URL and API key.
|
|
204
|
+
*
|
|
205
|
+
* This wrapper handles converting the CLI's registry URL format to the
|
|
206
|
+
* base URL format expected by the SDK.
|
|
207
|
+
*/
|
|
208
|
+
function configure(options) {
|
|
209
|
+
configure$1({
|
|
210
|
+
baseUrl: registryUrlToBaseUrl(options.registryUrl),
|
|
211
|
+
apiKey: options.apiKey
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Get user info from the API using the /me endpoint.
|
|
216
|
+
* Returns null if not authenticated.
|
|
217
|
+
*/
|
|
218
|
+
async function whoamiRequest(registryUrl, apiKey) {
|
|
219
|
+
try {
|
|
220
|
+
configure({
|
|
221
|
+
registryUrl,
|
|
222
|
+
apiKey
|
|
223
|
+
});
|
|
224
|
+
const response = await me();
|
|
225
|
+
if (response.status !== 200 || !response.data) return null;
|
|
226
|
+
const user = response.data;
|
|
227
|
+
return {
|
|
228
|
+
username: user.username,
|
|
229
|
+
userId: user.userId
|
|
230
|
+
};
|
|
231
|
+
} catch {
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Deprecate a skill version
|
|
237
|
+
*/
|
|
238
|
+
async function deprecateSkillVersion(username, skillName, version, message) {
|
|
239
|
+
const config = getConfig();
|
|
240
|
+
if (!config) return {
|
|
241
|
+
status: 401,
|
|
242
|
+
error: "SDK not configured"
|
|
243
|
+
};
|
|
244
|
+
try {
|
|
245
|
+
const response = await fetch(`${config.baseUrl}/api/skills/@user/${username}/${skillName}/versions/${version}/deprecate`, {
|
|
246
|
+
method: "POST",
|
|
247
|
+
headers: {
|
|
248
|
+
"Content-Type": "application/json",
|
|
249
|
+
Authorization: `Bearer ${config.apiKey}`
|
|
250
|
+
},
|
|
251
|
+
body: JSON.stringify({ message })
|
|
252
|
+
});
|
|
253
|
+
if (!response.ok) {
|
|
254
|
+
const error = await response.text();
|
|
255
|
+
return {
|
|
256
|
+
status: response.status,
|
|
257
|
+
error
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
const data = await response.json();
|
|
261
|
+
return {
|
|
262
|
+
status: response.status,
|
|
263
|
+
data
|
|
264
|
+
};
|
|
265
|
+
} catch (error) {
|
|
266
|
+
return {
|
|
267
|
+
status: 500,
|
|
268
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Remove deprecation from a skill version
|
|
274
|
+
*/
|
|
275
|
+
async function undeprecateSkillVersion(username, skillName, version) {
|
|
276
|
+
const config = getConfig();
|
|
277
|
+
if (!config) return {
|
|
278
|
+
status: 401,
|
|
279
|
+
error: "SDK not configured"
|
|
280
|
+
};
|
|
281
|
+
try {
|
|
282
|
+
const response = await fetch(`${config.baseUrl}/api/skills/@user/${username}/${skillName}/versions/${version}/deprecate`, {
|
|
283
|
+
method: "DELETE",
|
|
284
|
+
headers: { Authorization: `Bearer ${config.apiKey}` }
|
|
285
|
+
});
|
|
286
|
+
if (!response.ok) {
|
|
287
|
+
const error = await response.text();
|
|
288
|
+
return {
|
|
289
|
+
status: response.status,
|
|
290
|
+
error
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
const data = await response.json();
|
|
294
|
+
return {
|
|
295
|
+
status: response.status,
|
|
296
|
+
data
|
|
297
|
+
};
|
|
298
|
+
} catch (error) {
|
|
299
|
+
return {
|
|
300
|
+
status: 500,
|
|
301
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Fetch a public skill list by owner type and name.
|
|
307
|
+
* Calls GET /api/skill-lists/lists/@{ownerType}/{ownerName}/{listName}
|
|
308
|
+
*/
|
|
309
|
+
async function fetchSkillList(ownerType, ownerName, listName) {
|
|
310
|
+
const config = getConfig();
|
|
311
|
+
try {
|
|
312
|
+
const response = await fetch(`${config.baseUrl}/api/skill-lists/lists/@${ownerType}/${ownerName}/${listName}`, {
|
|
313
|
+
method: "GET",
|
|
314
|
+
headers: {
|
|
315
|
+
"Content-Type": "application/json",
|
|
316
|
+
...config.apiKey ? { Authorization: `Bearer ${config.apiKey}` } : {}
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
if (!response.ok) {
|
|
320
|
+
const error = await response.text();
|
|
321
|
+
return {
|
|
322
|
+
status: response.status,
|
|
323
|
+
error
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
const data = await response.json();
|
|
327
|
+
return {
|
|
328
|
+
status: response.status,
|
|
329
|
+
data
|
|
330
|
+
};
|
|
331
|
+
} catch (error) {
|
|
332
|
+
return {
|
|
333
|
+
status: 500,
|
|
334
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* List versions for a @github skill.
|
|
340
|
+
* Calls GET /api/skills/@github/{owner}/{repo}/{name}/versions
|
|
341
|
+
*/
|
|
342
|
+
async function listGithubSkillVersions(owner, repo, name) {
|
|
343
|
+
const config = getConfig();
|
|
344
|
+
try {
|
|
345
|
+
const response = await fetch(`${config.baseUrl}/api/skills/@github/${owner}/${repo}/${name}/versions`, {
|
|
346
|
+
method: "GET",
|
|
347
|
+
headers: {
|
|
348
|
+
"Content-Type": "application/json",
|
|
349
|
+
...config.apiKey ? { Authorization: `Bearer ${config.apiKey}` } : {}
|
|
350
|
+
}
|
|
351
|
+
});
|
|
352
|
+
if (!response.ok) {
|
|
353
|
+
const error = await response.text();
|
|
354
|
+
return {
|
|
355
|
+
status: response.status,
|
|
356
|
+
error
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
const data = await response.json();
|
|
360
|
+
return {
|
|
361
|
+
status: response.status,
|
|
362
|
+
data
|
|
363
|
+
};
|
|
364
|
+
} catch (error) {
|
|
365
|
+
return {
|
|
366
|
+
status: 500,
|
|
367
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Get a specific version of a @github skill (with download URL).
|
|
373
|
+
* Calls GET /api/skills/@github/{owner}/{repo}/{name}/versions/{version}
|
|
374
|
+
*/
|
|
375
|
+
async function getGithubSkillVersion(owner, repo, name, version) {
|
|
376
|
+
const config = getConfig();
|
|
377
|
+
try {
|
|
378
|
+
const response = await fetch(`${config.baseUrl}/api/skills/@github/${owner}/${repo}/${name}/versions/${version}`, {
|
|
379
|
+
method: "GET",
|
|
380
|
+
headers: {
|
|
381
|
+
"Content-Type": "application/json",
|
|
382
|
+
...config.apiKey ? { Authorization: `Bearer ${config.apiKey}` } : {}
|
|
383
|
+
}
|
|
384
|
+
});
|
|
385
|
+
if (!response.ok) {
|
|
386
|
+
const error = await response.text();
|
|
387
|
+
return {
|
|
388
|
+
status: response.status,
|
|
389
|
+
error
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
const data = await response.json();
|
|
393
|
+
return {
|
|
394
|
+
status: response.status,
|
|
395
|
+
data
|
|
396
|
+
};
|
|
397
|
+
} catch (error) {
|
|
398
|
+
return {
|
|
399
|
+
status: 500,
|
|
400
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Change skill visibility (public/private)
|
|
406
|
+
*/
|
|
407
|
+
async function changeSkillAccess(username, skillName, input) {
|
|
408
|
+
const config = getConfig();
|
|
409
|
+
if (!config) return {
|
|
410
|
+
status: 401,
|
|
411
|
+
error: "SDK not configured"
|
|
412
|
+
};
|
|
413
|
+
try {
|
|
414
|
+
const response = await fetch(`${config.baseUrl}/api/skills/@user/${username}/${skillName}/access`, {
|
|
415
|
+
method: "POST",
|
|
416
|
+
headers: {
|
|
417
|
+
"Content-Type": "application/json",
|
|
418
|
+
Authorization: `Bearer ${config.apiKey}`
|
|
419
|
+
},
|
|
420
|
+
body: JSON.stringify(input)
|
|
421
|
+
});
|
|
422
|
+
if (!response.ok) {
|
|
423
|
+
const error = await response.text();
|
|
424
|
+
try {
|
|
425
|
+
const errorJson = JSON.parse(error);
|
|
426
|
+
return {
|
|
427
|
+
status: response.status,
|
|
428
|
+
error: errorJson.message || errorJson.error || error
|
|
429
|
+
};
|
|
430
|
+
} catch {
|
|
431
|
+
return {
|
|
432
|
+
status: response.status,
|
|
433
|
+
error
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
const data = await response.json();
|
|
438
|
+
return {
|
|
439
|
+
status: response.status,
|
|
440
|
+
data
|
|
441
|
+
};
|
|
442
|
+
} catch (error) {
|
|
443
|
+
return {
|
|
444
|
+
status: 500,
|
|
445
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
//#endregion
|
|
450
|
+
export { me as _, getGithubSkillVersion as a, getConfig as b, whoamiRequest as c, deleteSkillVersion as d, explorePublicSkills as f, listSkillVersions as g, listOrgSkillVersions as h, fetchSkillList as i, deleteOrgSkill as l, getSkillVersion as m, configure as n, listGithubSkillVersions as o, getOrgSkillVersion as p, deprecateSkillVersion as r, undeprecateSkillVersion as s, changeSkillAccess as t, deleteSkill as u, publishOrgSkill as v, publishSkill as y };
|
|
451
|
+
|
|
452
|
+
//# sourceMappingURL=api-client-DBXUpGoX.js.map
|