diff --git a/.gitignore b/.gitignore index 2563c091b..32f405cc1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ # OS files .DS_Store Thumbs.db +.nfs* # Editors / IDEs / local tooling .claude/ @@ -14,6 +15,7 @@ Thumbs.db *.iml *.swp *.swo +*.code-workspace # Logs *.log diff --git a/skillhub-cli/package.json b/skillhub-cli/package.json index eb0a95440..57f1a5820 100644 --- a/skillhub-cli/package.json +++ b/skillhub-cli/package.json @@ -1,6 +1,6 @@ { "name": "motovis-skillhub", - "version": "1.2.6", + "version": "1.2.8", "type": "module", "description": "SkillHub CLI - 企业级 Agent Skill 管理工具,支持命名空间", "bin": { diff --git a/skillhub-cli/src/cli.ts b/skillhub-cli/src/cli.ts index 11ba70314..3fa890755 100644 --- a/skillhub-cli/src/cli.ts +++ b/skillhub-cli/src/cli.ts @@ -30,14 +30,12 @@ interface HelpEntry { } function formatSection(header: string, entries: HelpEntry[]): string { - const displayWidth = (e: HelpEntry) => e.cmd.length + (e.alias ? e.alias.length + 3 : 0); - const maxW = entries.reduce((max, e) => Math.max(max, displayWidth(e)), 0); - const col = Math.max(maxW + 4, 28); const lines = [bold(header)]; + for (const e of entries) { const aliasPart = e.alias ? dim(` (${e.alias})`) : ""; - const pad = " ".repeat(Math.max(col - displayWidth(e), 2)); - lines.push(` ${cyan(e.cmd)}${aliasPart}${pad}${e.desc}`); + lines.push(` ${cyan(e.cmd)}${aliasPart}`); + lines.push(` ${e.desc}`); } return lines.join("\n"); } @@ -51,8 +49,8 @@ function buildTopLevelHelp(version: string): string { sections.push(formatSection("Configuration", [ { cmd: "config list", desc: "Show current registry configuration" }, - { cmd: "config set ", desc: "Set configuration (e.g., registry URL)" }, - { cmd: "config get ", desc: "Get configuration value" }, + { cmd: "config set ", desc: "Set registry URL" }, + { cmd: "config get", desc: "Get current registry configuration" }, { cmd: "config show-env-instructions", desc: "Show environment variable setup guide" }, ])); sections.push(""); @@ -64,37 +62,37 @@ function buildTopLevelHelp(version: string): string { ])); sections.push(""); - sections.push(formatSection("Discover & Info", [ + sections.push(formatSection("Discovery", [ { cmd: "explore", desc: "Browse or search skills from the registry", alias: "find, find-skills, search" }, - { cmd: "inspect ", desc: "View skill metadata and versions", alias: "info, view" }, - { cmd: "resolve ", desc: "Resolve the latest version of a skill" }, - ])); - sections.push(""); - - sections.push(formatSection("Social & Reviews", [ - { cmd: "star ", desc: "Star or unstar a skill" }, - { cmd: "rating ", desc: "View your rating for a skill" }, - { cmd: "rate ", desc: "Rate a skill (1-5)" }, - { cmd: "report ", desc: "Report a skill for review" }, + { cmd: "inspect ", desc: "View skill metadata and versions", alias: "info, view" }, + { cmd: "resolve ", desc: "Resolve the latest version of a skill" }, ])); sections.push(""); sections.push(formatSection("Install & Manage", [ - { cmd: "install ", desc: "Install from registry, git, or local path", alias: "i" }, - { cmd: "download ", desc: "Download a skill package to local directory" }, - { cmd: "update [slug]", desc: "Update installed skills from their source", alias: "up" }, - { cmd: "uninstall [name]", desc: "Uninstall a skill from local agent", alias: "un" }, + { cmd: "install ", desc: "Install from registry, git, or local path", alias: "i" }, + { cmd: "download ", desc: "Download a skill package to local directory" }, + { cmd: "update [skill]", desc: "Update installed skills from their source", alias: "up" }, + { cmd: "uninstall [skill]", desc: "Uninstall a skill from local agent", alias: "un" }, { cmd: "list", desc: "List installed skills", alias: "ls" }, { cmd: "check", desc: "Check installed skills against lock file" }, ])); sections.push(""); - sections.push(formatSection("Publish", [ + sections.push(formatSection("Social", [ + { cmd: "star ", desc: "Star or unstar a skill" }, + { cmd: "rating ", desc: "View your rating for a skill" }, + { cmd: "rate ", desc: "Rate a skill (1-5)" }, + { cmd: "report ", desc: "Report a skill for review" }, + ])); + sections.push(""); + + sections.push(formatSection("Publish & Manage", [ { cmd: "init [name]", desc: "Create a new SKILL.md template" }, { cmd: "publish [path]", desc: "Publish a skill to SkillHub registry" }, { cmd: "sync [path]", desc: "Scan and publish all skills from a directory" }, - { cmd: "delete ", desc: "Delete a skill you own", alias: "del, unpublish" }, - { cmd: "archive ", desc: "Archive a skill you own" }, + { cmd: "delete ", desc: "Delete a skill you own", alias: "del, unpublish" }, + { cmd: "archive ", desc: "Archive a skill you own" }, ])); sections.push(""); @@ -108,8 +106,8 @@ function buildTopLevelHelp(version: string): string { sections.push(""); sections.push(formatSection("Admin", [ - { cmd: "hide ", desc: "Hide a skill (admin only)" }, - { cmd: "unhide ", desc: "Unhide a skill (admin only)" }, + { cmd: "hide ", desc: "Hide a skill (admin only)" }, + { cmd: "unhide ", desc: "Unhide a skill (admin only)" }, { cmd: "transfer ", desc: "Transfer namespace ownership" }, ])); sections.push(""); diff --git a/skillhub-cli/src/commands/archive.ts b/skillhub-cli/src/commands/archive.ts index c720b962d..4d9c0c568 100644 --- a/skillhub-cli/src/commands/archive.ts +++ b/skillhub-cli/src/commands/archive.ts @@ -7,8 +7,9 @@ import { parseSkillName } from "../core/skill-name.js"; export function registerArchive(program: Command) { program - .command("archive ") + .command("archive") .description("Archive a skill you own") + .argument("", "Skill name or namespace/skill-name") .option("-y, --yes", "Skip confirmation") .action(async (slug: string, opts: { yes?: boolean }) => { const { namespace, slug: skillSlug } = parseSkillName(slug); diff --git a/skillhub-cli/src/commands/config.ts b/skillhub-cli/src/commands/config.ts index f620adfef..ef0287319 100644 --- a/skillhub-cli/src/commands/config.ts +++ b/skillhub-cli/src/commands/config.ts @@ -20,7 +20,7 @@ export function registerConfig(program: Command) { configCmd .command("list") - .description("List all configuration sources and their values") + .description("Show all config values and their sources") .action(() => { const env = process.env.SKILLHUB_REGISTRY; let fileConfig: { registry?: string } = {}; @@ -56,7 +56,7 @@ export function registerConfig(program: Command) { configCmd .command("set ") - .description("Set registry URL in ~/.skillhub/config.json") + .description("Set registry URL (e.g., https://api.example.com)") .action((value: string) => { if (!existsSync(CONFIG_DIR)) { mkdirSync(CONFIG_DIR, { recursive: true }); @@ -79,7 +79,7 @@ export function registerConfig(program: Command) { configCmd .command("get") - .description("Get registry configuration value") + .description("Show the current registry URL") .option("--source ", "Source: env, file, or resolved (default)") .action((opts: { source?: string }) => { const source = opts.source || "resolved"; diff --git a/skillhub-cli/src/commands/delete.ts b/skillhub-cli/src/commands/delete.ts index 94c534337..9911243e0 100644 --- a/skillhub-cli/src/commands/delete.ts +++ b/skillhub-cli/src/commands/delete.ts @@ -7,9 +7,9 @@ import { parseSkillName } from "../core/skill-name.js"; export function registerDelete(program: Command) { program - .command("delete ") - .aliases(["del", "unpublish"]) + .command("delete") .description("Delete a skill you own") + .argument("", "Skill name or namespace/skill-name") .option("-y, --yes", "Skip confirmation") .action(async (slug: string, opts: { yes?: boolean }) => { const { namespace, slug: skillSlug } = parseSkillName(slug); diff --git a/skillhub-cli/src/commands/download.ts b/skillhub-cli/src/commands/download.ts index d3d389ca3..bf40f4657 100644 --- a/skillhub-cli/src/commands/download.ts +++ b/skillhub-cli/src/commands/download.ts @@ -12,8 +12,9 @@ import ora from "ora"; export function registerDownload(program: Command) { program - .command("download ") + .command("download") .description("Download a skill package to local directory") + .argument("", "Skill name or namespace/skill-name") .option("-v, --skill-version ", "Specific version") .option("--tag ", "Tag to download", "latest") .option("--output ", "Output directory") diff --git a/skillhub-cli/src/commands/explore.ts b/skillhub-cli/src/commands/explore.ts index 7b81ebed9..898fd27c3 100644 --- a/skillhub-cli/src/commands/explore.ts +++ b/skillhub-cli/src/commands/explore.ts @@ -214,20 +214,60 @@ async function runInteractiveSearch( }); } +function buildExploreHelp(cmd: Command): string { + const lines: string[] = []; + + lines.push(`${BOLD}Usage:${RESET} skillhub explore [options] [query]`); + lines.push(""); + lines.push("Browse or search skills from the registry"); + lines.push(""); + + lines.push(`${BOLD}Arguments:${RESET}`); + lines.push(` ${CYAN}[query]${RESET} Search query for finding skills`); + lines.push(""); + + lines.push(`${BOLD}Search Options:${RESET}`); + lines.push(` ${CYAN}-n, --limit ${RESET} Max results (default: "20")`); + lines.push(""); + + lines.push(`${BOLD}Sorting Options:${RESET}`); + lines.push(` ${CYAN}-s, --sort ${RESET} Sort by: hot, newest, downloads, stars, rating`); + lines.push(` ${CYAN}--hot${RESET} Sort by comprehensive popularity (downloads + stars)`); + lines.push(` ${CYAN}--newest${RESET} Sort by newest first`); + lines.push(` ${CYAN}--downloads${RESET} Sort by download count`); + lines.push(` ${CYAN}--stars${RESET} Sort by star count`); + lines.push(` ${CYAN}--rating${RESET} Sort by average rating`); + lines.push(""); + + lines.push(`${BOLD}Other Options:${RESET}`); + lines.push(` ${CYAN}-h, --help${RESET} Display help for command`); + lines.push(""); + + lines.push(`${BOLD}Examples:${RESET}`); + lines.push(`${DIM} skillhub explore Interactive skill search${RESET}`); + lines.push(`${DIM} skillhub explore --hot Browse popular skills${RESET}`); + lines.push(`${DIM} skillhub explore ai-assistant Search for skills${RESET}`); + lines.push(`${DIM} skillhub explore --sort newest --limit 10 Show 10 newest skills${RESET}`); + + return lines.join("\n"); +} + export function registerExplore(program: Command) { - program + const exploreCmd = program .command("explore") - .aliases(["find", "find-skills", "search"]) .description("Browse or search skills from the registry") .argument("[query]", "Search query for finding skills") .option("-n, --limit ", "Max results", "20") - .option("-s, --sort ", "Sort by: hot, newest, downloads, stars, rating (default: interactive mode)") + .option("-s, --sort ", "Sort by: hot, newest, downloads, stars, rating (browse mode)") .option("--hot", "Sort by comprehensive popularity (downloads + stars)") .option("--newest", "Sort by newest first (shorthand for --sort newest)") .option("--downloads", "Sort by download count (shorthand for --sort downloads)") .option("--stars", "Sort by star count (shorthand for --sort stars)") - .option("--rating", "Sort by average rating (shorthand for --sort rating)") - .action(async (query: string | undefined, opts: { limit: string; sort?: string; hot?: boolean; newest?: boolean; downloads?: boolean; stars?: boolean; rating?: boolean }) => { + .option("--rating", "Sort by average rating (shorthand for --sort rating)"); + + exploreCmd.helpInformation = () => buildExploreHelp(exploreCmd); + + exploreCmd.action(async (query: string | undefined, opts: { limit: string; sort?: string; hot?: boolean; newest?: boolean; downloads?: boolean; stars?: boolean; rating?: boolean }) => { const config = loadConfigFromProgram(program); const token = await readToken(); const client = new ApiClient({ baseUrl: config.registry, token: token || undefined }); diff --git a/skillhub-cli/src/commands/hide.ts b/skillhub-cli/src/commands/hide.ts index dd1373b89..8b98fc3a4 100644 --- a/skillhub-cli/src/commands/hide.ts +++ b/skillhub-cli/src/commands/hide.ts @@ -7,8 +7,9 @@ import { parseSkillName } from "../core/skill-name.js"; export function registerHide(program: Command) { const hideCmd = program - .command("hide ") + .command("hide") .description("Hide a skill (admin only)") + .argument("", "Skill name or namespace/skill-name") .option("-y, --yes", "Skip confirmation") .action(async (slug: string, opts: { yes?: boolean }) => { const { namespace, slug: skillSlug } = parseSkillName(slug); @@ -47,8 +48,9 @@ export function registerHide(program: Command) { }); hideCmd - .command("unhide ") + .command("unhide") .description("Unhide a skill (admin only)") + .argument("", "Skill name or namespace/skill-name") .option("-y, --yes", "Skip confirmation") .action(async (slug: string, opts: { yes?: boolean }) => { const { namespace, slug: skillSlug } = parseSkillName(slug); diff --git a/skillhub-cli/src/commands/inspect.ts b/skillhub-cli/src/commands/inspect.ts index e5f7d0ca8..63d8bf004 100644 --- a/skillhub-cli/src/commands/inspect.ts +++ b/skillhub-cli/src/commands/inspect.ts @@ -137,12 +137,13 @@ function printInspectHeader(detail: SkillDetailResponse, versions?: SkillVersion export function registerInspect(program: Command) { program - .command("inspect ") - .aliases(["info", "view"]) + .command("inspect") .description("View skill metadata without installing") + .argument("", "Skill name or namespace/skill-name") .option("--namespace ", "Search in specific namespace (searches all if not specified)") .option("--details", "Show all versions with tags") - .action(async (slug: string, opts: { namespace?: string; details?: boolean }) => { + .option("-v, --version ", "Inspect specific version") + .action(async (slug: string, opts: { namespace?: string; details?: boolean; version?: string }) => { const config = loadConfigFromProgram(program); const token = await readToken(); const client = new ApiClient({ baseUrl: config.registry, token: token || undefined }); @@ -152,7 +153,6 @@ export function registerInspect(program: Command) { const targetNamespace = opts.namespace || defaultNs; async function fetchVersionsAndTags(ns: string, skillSlug: string) { - if (!opts.details) return { versions: undefined, tags: undefined }; try { const [versionsResp, tagsResp] = await Promise.all([ client.get(`/api/v1/skills/${ns}/${skillSlug}/versions`), @@ -164,21 +164,91 @@ export function registerInspect(program: Command) { } } - async function displaySkillDetail(ns: string, skillSlug: string) { - const detail = await client.get( - `${ApiRoutes.skillDetail.replace("{namespace}", ns).replace("{slug}", skillSlug)}` - ); - const { versions, tags } = await fetchVersionsAndTags(ns, skillSlug); - if (isJson) { - const output = opts.details ? { ...detail, versions, tags } : detail; - console.log(JSON.stringify(output, null, 2)); - } else { - printSkillDetail(detail, versions, tags); + async function displaySkillDetail(ns: string, skillSlug: string, version?: string) { + try { + const detail = await client.get( + `${ApiRoutes.skillDetail.replace("{namespace}", ns).replace("{slug}", skillSlug)}` + ); + + const { versions, tags } = await fetchVersionsAndTags(ns, skillSlug); + + if (version && versions) { + const selectedVersion = versions.find(v => v.version === version); + if (selectedVersion) { + detail.publishedVersion = { version: selectedVersion.version }; + } + } + + if (isJson) { + const output = opts.details ? { ...detail, versions, tags } : detail; + console.log(JSON.stringify(output, null, 2)); + } else { + printSkillDetail(detail, opts.details ? versions : undefined, opts.details ? tags : undefined); + } + } catch (e: any) { + if (e.statusCode === 403) { + error(`Access denied: ${ns}/${skillSlug}`); + dim("Run 'skillhub login' to authenticate."); + } else if (e.statusCode === 404) { + error(`Skill not found: ${ns}/${skillSlug}`); + } else { + error(`Failed to fetch skill details: ${e.message}`); + } + process.exitCode = 1; } } + async function inspectWithVersionSelection(ns: string, skillSlug: string) { + const { versions, tags } = await fetchVersionsAndTags(ns, skillSlug); + + if (!versions || versions.length === 0) { + await displaySkillDetail(ns, skillSlug); + return; + } + + if (opts.details) { + await displaySkillDetail(ns, skillSlug); + return; + } + + if (versions.length === 1) { + await displaySkillDetail(ns, skillSlug); + return; + } + + const versionTagsMap = new Map(); + if (tags) { + for (const tag of tags) { + if (!versionTagsMap.has(tag.versionId)) { + versionTagsMap.set(tag.versionId, []); + } + versionTagsMap.get(tag.versionId)!.push(tag.tagName); + } + } + + const selected = await p.select({ + message: "Select version to inspect", + options: versions.map((v) => ({ + value: v.version, + label: `v${v.version}`, + hint: versionTagsMap.get(v.id)?.join(", ") || "", + })), + }); + + if (p.isCancel(selected)) { + console.log("Cancelled."); + return; + } + + await displaySkillDetail(ns, skillSlug, selected as string); + } + if (targetNamespace) { - await displaySkillDetail(targetNamespace, parsedSlug); + if (opts.version) { + await displaySkillDetail(targetNamespace, parsedSlug, opts.version); + } else { + await inspectWithVersionSelection(targetNamespace, parsedSlug); + } return; } @@ -207,7 +277,11 @@ export function registerInspect(program: Command) { spinner.stop(); const ns = uniqueResults[0].namespace; const name = uniqueResults[0].name; - await displaySkillDetail(ns, name); + if (opts.version) { + await displaySkillDetail(ns, name, opts.version); + } else { + await inspectWithVersionSelection(ns, name); + } return; } @@ -228,7 +302,11 @@ export function registerInspect(program: Command) { } const [selectedNs, selectedName] = (selected as string).split("/", 2); - await displaySkillDetail(selectedNs, selectedName); + if (opts.version) { + await displaySkillDetail(selectedNs, selectedName, opts.version); + } else { + await inspectWithVersionSelection(selectedNs, selectedName); + } } catch (e: any) { spinner.fail(e.message); process.exitCode = 1; diff --git a/skillhub-cli/src/commands/install.ts b/skillhub-cli/src/commands/install.ts index bb48ae2c4..a5ec716c7 100644 --- a/skillhub-cli/src/commands/install.ts +++ b/skillhub-cli/src/commands/install.ts @@ -200,13 +200,13 @@ function buildAgentSummary(targetAgents: AgentInfo[], mode: "symlink" | "copy", function buildInstallHelp(cmd: Command): string { const lines: string[] = []; - lines.push(`${chalk.bold("Usage:")} skillhub install|i [options] ${chalk.cyan("")}`); + lines.push(`${chalk.bold("Usage:")} skillhub install [options] ${chalk.cyan("")}`); lines.push(""); lines.push("Install skills from registry, git repositories, or local paths"); lines.push(""); lines.push(chalk.bold("Arguments:")); - lines.push(` ${chalk.cyan("skill-name")} Skill name or namespace/skill-name from registry`); + lines.push(` ${chalk.cyan("skill")} Skill name or namespace/skill-name from registry`); lines.push(""); lines.push(chalk.bold("Source Options:")); @@ -246,9 +246,10 @@ function buildInstallHelp(cmd: Command): string { export function registerInstall(program: Command) { const installCmd = program - .command("install ") + .command("install") .alias("i") .description("Install skills from registry, git repositories, or local paths") + .argument("", "Skill name or namespace/skill-name from registry") .option("-a, --add ", "Install from GitHub or local path (alias for --from)") .option("--from ", "Install from GitHub or local path (alias for -a)") .option("--agent ", "Target specific agents") diff --git a/skillhub-cli/src/commands/list.ts b/skillhub-cli/src/commands/list.ts index c9cf1fc58..6205dc0fc 100644 --- a/skillhub-cli/src/commands/list.ts +++ b/skillhub-cli/src/commands/list.ts @@ -18,7 +18,6 @@ interface ListOptions { export function registerList(program: Command) { program .command("list") - .alias("ls") .description("List installed skills") .option("-g, --global", "List global skills only") .option("-p, --project", "List project skills only") diff --git a/skillhub-cli/src/commands/me.ts b/skillhub-cli/src/commands/me.ts index b1fce52d2..a0b3a9113 100644 --- a/skillhub-cli/src/commands/me.ts +++ b/skillhub-cli/src/commands/me.ts @@ -28,7 +28,6 @@ export function registerMe(program: Command) { me .command("skills") - .alias("ls") .description("List your published skills") .action(async () => { try { diff --git a/skillhub-cli/src/commands/notifications.ts b/skillhub-cli/src/commands/notifications.ts index 7b02675b2..f2929c0ab 100644 --- a/skillhub-cli/src/commands/notifications.ts +++ b/skillhub-cli/src/commands/notifications.ts @@ -15,12 +15,10 @@ export interface Notification { export function registerNotifications(program: Command) { const cmd = program .command("notifications") - .alias("notif") .description("Manage notifications"); cmd .command("list") - .alias("ls") .description("List notifications") .option("--unread", "Show unread only") .action(async (opts: { unread?: boolean }) => { diff --git a/skillhub-cli/src/commands/rating.ts b/skillhub-cli/src/commands/rating.ts index 12c825761..9df10fa2c 100644 --- a/skillhub-cli/src/commands/rating.ts +++ b/skillhub-cli/src/commands/rating.ts @@ -7,8 +7,9 @@ import { parseSkillName } from "../core/skill-name.js"; export function registerRating(program: Command) { program - .command("rating ") + .command("rating") .description("View your rating for a skill") + .argument("", "Skill name or namespace/skill-name") .action(async (slug: string) => { try { const { namespace, slug: skillSlug } = parseSkillName(slug); @@ -28,7 +29,7 @@ export function registerRating(program: Command) { info(`${skillSlug}: ${"★".repeat(rating.score)}${"☆".repeat(5 - rating.score)} (${rating.score}/5)`); } else { info(`${skillSlug}: Not rated yet`); - dim("Use: skillhub rate "); + dim("Use: skillhub rate "); } } catch (e: any) { error(`Failed: ${e.message}`); @@ -39,8 +40,10 @@ export function registerRating(program: Command) { export function registerRate(program: Command) { program - .command("rate ") + .command("rate") .description("Rate a skill (1-5)") + .argument("", "Skill name or namespace/skill-name") + .argument("", "Rating score (1-5)") .action(async (slug: string, scoreStr: string) => { const score = parseInt(scoreStr, 10); if (isNaN(score) || score < 1 || score > 5) { diff --git a/skillhub-cli/src/commands/report.ts b/skillhub-cli/src/commands/report.ts index 52da128d6..873682307 100644 --- a/skillhub-cli/src/commands/report.ts +++ b/skillhub-cli/src/commands/report.ts @@ -8,8 +8,9 @@ import { parseSkillName } from "../core/skill-name.js"; export function registerReport(program: Command) { program - .command("report ") + .command("report") .description("Report a skill for review") + .argument("", "Skill name or namespace/skill-name") .option("--reason ", "Report reason") .action(async (slug: string, opts: { reason?: string }) => { try { diff --git a/skillhub-cli/src/commands/resolve.ts b/skillhub-cli/src/commands/resolve.ts index 3f14c9e57..3d44935c2 100644 --- a/skillhub-cli/src/commands/resolve.ts +++ b/skillhub-cli/src/commands/resolve.ts @@ -43,8 +43,9 @@ async function resolveWithVersion( export function registerResolve(program: Command) { program - .command("resolve ") + .command("resolve") .description("Resolve the latest version of a skill") + .argument("", "Skill name or namespace/skill-name") .option("-v, --skill-version ", "Specific version") .option("--tag ", "Tag to resolve (default: latest, ignored if --skill-version)") .option("--hash ", "Content hash") diff --git a/skillhub-cli/src/commands/reviews.ts b/skillhub-cli/src/commands/reviews.ts index 745c6113d..ca6ee1c02 100644 --- a/skillhub-cli/src/commands/reviews.ts +++ b/skillhub-cli/src/commands/reviews.ts @@ -19,7 +19,6 @@ export function registerReviews(program: Command) { reviews .command("my") - .alias("submissions") .description("List your review submissions") .action(async () => { try { diff --git a/skillhub-cli/src/commands/star.ts b/skillhub-cli/src/commands/star.ts index 2ff16ea4e..fbd06599f 100644 --- a/skillhub-cli/src/commands/star.ts +++ b/skillhub-cli/src/commands/star.ts @@ -8,8 +8,9 @@ import { parseSkillName } from "../core/skill-name.js"; export function registerStar(program: Command) { program - .command("star ") + .command("star") .description("Star a skill") + .argument("", "Skill name or namespace/skill-name") .option("--unstar", "Remove star") .action(async (slug: string, opts: { unstar: boolean }) => { try { diff --git a/skillhub-cli/src/commands/uninstall.ts b/skillhub-cli/src/commands/uninstall.ts index 88541177a..a3e78883b 100644 --- a/skillhub-cli/src/commands/uninstall.ts +++ b/skillhub-cli/src/commands/uninstall.ts @@ -110,8 +110,7 @@ function findAgentsWithSkill(skillName: string, scope: "global" | "local", agent export function registerUninstall(program: Command) { program - .command("uninstall [name]") - .alias("un") + .command("uninstall [skill]") .description("Uninstall a skill or all skills from local agent") .option("-g, --global", "Uninstall from global scope") .option("-a, --agent ", "Uninstall from specific agents") diff --git a/skillhub-cli/src/commands/update.ts b/skillhub-cli/src/commands/update.ts index 8fbbf3766..1082cff41 100644 --- a/skillhub-cli/src/commands/update.ts +++ b/skillhub-cli/src/commands/update.ts @@ -12,8 +12,7 @@ function getCliCommand(): string { export function registerUpdate(program: Command) { program - .command("update [slug]") - .alias("up") + .command("update [skill]") .description("Update installed skills from their source") .option("-a, --all", "Update all installed skills") .option("-g, --global", "Update global scope skills")