From e93adaaaaa1e16b31698b006cb01d50bcbe7c4c8 Mon Sep 17 00:00:00 2001 From: eldenring_saver <49091147+Rsweater@users.noreply.github.com> Date: Thu, 16 Apr 2026 15:45:02 +0000 Subject: [PATCH] feat(web): replace clawhub with skillhub CLI in frontend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace all `npx clawhub` references with `npx motovis-skillhub` / `skillhub` - Update namespace separator from `--` to `/` in install commands - Change env var CLAWHUB_REGISTRY to SKILLHUB_REGISTRY - Add vite dev server plugin to serve /registry/skill.md - Update i18n strings (zh/en): ClawHub CLI → SkillHub CLI - Update skill.md/skill.md.template with new CLI commands - Update quick-start.tsx syntax highlighting and env config - Update e2e test assertions Co-Authored-By: Claude Opus 4.6 --- web/src/docs/skill.md | 46 ++++---- web/src/docs/skill.md.template | 46 ++++---- .../features/skill/install-command.test.ts | 6 +- web/src/features/skill/install-command.tsx | 4 +- web/src/i18n/locales/en.json | 14 +-- web/src/i18n/locales/zh.json | 14 +-- web/src/shared/components/quick-start.tsx | 16 ++- web/vite.config.ts | 105 +++++++++++++----- 8 files changed, 152 insertions(+), 99 deletions(-) diff --git a/web/src/docs/skill.md b/web/src/docs/skill.md index 18ea1e88..e692b7d2 100644 --- a/web/src/docs/skill.md +++ b/web/src/docs/skill.md @@ -1,13 +1,13 @@ --- name: skillhub-registry -description: Use this when you need to search, inspect, install, or publish agent skills against a SkillHub registry. SkillHub is a skill registry with a ClawHub-compatible API layer, so prefer the `clawhub` CLI for registry operations instead of making raw HTTP calls. +description: Use this when you need to search, inspect, install, or publish agent skills against a SkillHub registry. SkillHub is a skill registry with a ClawHub-compatible API layer, so prefer the `skillhub` CLI for registry operations instead of making raw HTTP calls. --- # SkillHub Registry Use this skill when you need to work with a SkillHub registry: search skills, inspect metadata, install a package, or publish a new version. -> Important: Prefer the `clawhub` CLI for registry workflows. SkillHub exposes a ClawHub-compatible API surface and a discovery endpoint at `/.well-known/clawhub.json`, so the CLI is the safest path for auth, resolution, and download behavior. Only fall back to raw HTTP when debugging the server itself. +> Important: Prefer the `skillhub` CLI for registry workflows. SkillHub exposes a ClawHub-compatible API surface and a discovery endpoint at `/.well-known/clawhub.json`, so the CLI is the safest path for auth, resolution, and download behavior. Only fall back to raw HTTP when debugging the server itself. ## What SkillHub Is @@ -16,8 +16,8 @@ SkillHub is an enterprise-oriented skill registry. It stores versioned skill pac Key facts: - Internal coordinates use `@{namespace}/{skill_slug}`. -- If using the clawhub CLI, the compatible format is `{namespace}--{skill_slug}`. -- ClawHub-compatible clients use a `{namespace}--{skill_slug}` slug instead. +- If using the skillhub CLI, the compatible format is `{namespace}--{skill_slug}`. +- ClawHub-compatible clients use a `{namespace}--{skill_slug}` slug format. - `latest` always means the latest published version, never draft or pending review. - Public skills in `@global` can be downloaded anonymously. - If no namespace is specified, it defaults to `@global`. @@ -26,23 +26,23 @@ Key facts: ## Configure The CLI -Point `clawhub` at the SkillHub base URL: +Point `skillhub` at the SkillHub base URL: ```bash -export CLAWHUB_REGISTRY=https://skillhub.your-company.com +export SKILLHUB_REGISTRY=https://skillhub.your-company.com ``` Alternatively, use the `--registry` parameter every time, for example: ```bash -npx clawhub install my-skill --registry https://skillhub.your-company.com +npx motovis-skillhub install my-skill --registry https://skillhub.your-company.com ``` If you need authenticated access, provide an API token: ```bash -clawhub login --token sk_your_api_token_here +skillhub login --token sk_your_api_token_here ``` Optional local check: @@ -61,23 +61,23 @@ Expected response: SkillHub has two naming forms: -| SkillHub coordinate | Canonical slug for `clawhub` | +| SkillHub coordinate | CLI format | |---|---| | `@global/my-skill` | `my-skill` | -| `@team-name/my-skill` | `team-name--my-skill` | +| `@team-name/my-skill` | `team-name/my-skill` | Rules: -- `--` is the namespace separator in the compatibility layer. -- If there is no `--`, the skill is treated as `@global/...`. +- `/` is the namespace separator in CLI commands. +- If no namespace is specified, the skill is treated as `@global/...`. - `latest` resolves to the latest published version only. Examples: ```bash -npx clawhub install my-skill -npx clawhub install my-skill@1.2.0 -npx clawhub install team-name--my-skill +npx motovis-skillhub install my-skill +npx motovis-skillhub install my-skill@1.2.0 +npx motovis-skillhub install team-name/my-skill ``` ## Common Workflows @@ -85,28 +85,28 @@ npx clawhub install team-name--my-skill ### Search ```bash -npx clawhub search email +npx motovis-skillhub search email ``` Use an empty query when you want a broad listing: ```bash -npx clawhub search "" +npx motovis-skillhub search "" ``` ### Inspect A Skill ```bash -npx clawhub info my-skill -npx clawhub info team-name--my-skill +npx motovis-skillhub info my-skill +npx motovis-skillhub info team-name/my-skill ``` ### Install ```bash -npx clawhub install my-skill -npx clawhub install my-skill@1.2.0 -npx clawhub install team-name--my-skill +npx motovis-skillhub install my-skill +npx motovis-skillhub install my-skill@1.2.0 +npx motovis-skillhub install team-name/my-skill ``` ### Publish @@ -114,7 +114,7 @@ npx clawhub install team-name--my-skill Prepare a skill package directory, then publish it: ```bash -npx clawhub publish ./my-skill +npx motovis-skillhub publish ./my-skill ``` Publishing requires authentication and sufficient permissions in the target namespace. diff --git a/web/src/docs/skill.md.template b/web/src/docs/skill.md.template index 1d13200f..c636b0a8 100644 --- a/web/src/docs/skill.md.template +++ b/web/src/docs/skill.md.template @@ -1,13 +1,13 @@ --- name: skillhub-registry -description: Use this when you need to search, inspect, install, or publish agent skills against a SkillHub registry. SkillHub is a skill registry with a ClawHub-compatible API layer, so prefer the `clawhub` CLI for registry operations instead of making raw HTTP calls. +description: Use this when you need to search, inspect, install, or publish agent skills against a SkillHub registry. SkillHub is a skill registry with a ClawHub-compatible API layer, so prefer the `skillhub` CLI for registry operations instead of making raw HTTP calls. --- # SkillHub Registry Use this skill when you need to work with a SkillHub registry: search skills, inspect metadata, install a package, or publish a new version. -> Important: Prefer the `clawhub` CLI for registry workflows. SkillHub exposes a ClawHub-compatible API surface and a discovery endpoint at `/.well-known/clawhub.json`, so the CLI is the safest path for auth, resolution, and download behavior. Only fall back to raw HTTP when debugging the server itself. +> Important: Prefer the `skillhub` CLI for registry workflows. SkillHub exposes a ClawHub-compatible API surface and a discovery endpoint at `/.well-known/clawhub.json`, so the CLI is the safest path for auth, resolution, and download behavior. Only fall back to raw HTTP when debugging the server itself. ## What SkillHub Is @@ -16,8 +16,8 @@ SkillHub is an enterprise-oriented skill registry. It stores versioned skill pac Key facts: - Internal coordinates use `@{namespace}/{skill_slug}`. -- If using the clawhub CLI, the compatible format is `{namespace}--{skill_slug}`. -- ClawHub-compatible clients use a `{namespace}--{skill_slug}` slug instead. +- If using the skillhub CLI, the compatible format is `{namespace}--{skill_slug}`. +- ClawHub-compatible clients use a `{namespace}--{skill_slug}` slug format. - `latest` always means the latest published version, never draft or pending review. - Public skills in `@global` can be downloaded anonymously. - If no namespace is specified, it defaults to `@global`. @@ -26,23 +26,23 @@ Key facts: ## Configure The CLI -Point `clawhub` at the SkillHub base URL: +Point `skillhub` at the SkillHub base URL: ```bash -export CLAWHUB_REGISTRY=${SKILLHUB_PUBLIC_BASE_URL} +export SKILLHUB_REGISTRY=${SKILLHUB_PUBLIC_BASE_URL} ``` Alternatively, use the `--registry` parameter every time, for example: ```bash -npx clawhub install my-skill --registry ${SKILLHUB_PUBLIC_BASE_URL} +npx motovis-skillhub install my-skill --registry ${SKILLHUB_PUBLIC_BASE_URL} ``` If you need authenticated access, provide an API token: ```bash -clawhub login --token sk_your_api_token_here +skillhub login --token sk_your_api_token_here ``` Optional local check: @@ -61,23 +61,23 @@ Expected response: SkillHub has two naming forms: -| SkillHub coordinate | Canonical slug for `clawhub` | +| SkillHub coordinate | CLI format | |---|---| | `@global/my-skill` | `my-skill` | -| `@team-name/my-skill` | `team-name--my-skill` | +| `@team-name/my-skill` | `team-name/my-skill` | Rules: -- `--` is the namespace separator in the compatibility layer. -- If there is no `--`, the skill is treated as `@global/...`. +- `/` is the namespace separator in CLI commands. +- If no namespace is specified, the skill is treated as `@global/...`. - `latest` resolves to the latest published version only. Examples: ```bash -npx clawhub install my-skill -npx clawhub install my-skill@1.2.0 -npx clawhub install team-name--my-skill +npx motovis-skillhub install my-skill +npx motovis-skillhub install my-skill@1.2.0 +npx motovis-skillhub install team-name/my-skill ``` ## Common Workflows @@ -85,28 +85,28 @@ npx clawhub install team-name--my-skill ### Search ```bash -npx clawhub search email +npx motovis-skillhub search email ``` Use an empty query when you want a broad listing: ```bash -npx clawhub search "" +npx motovis-skillhub search "" ``` ### Inspect A Skill ```bash -npx clawhub info my-skill -npx clawhub info team-name--my-skill +npx motovis-skillhub info my-skill +npx motovis-skillhub info team-name/my-skill ``` ### Install ```bash -npx clawhub install my-skill -npx clawhub install my-skill@1.2.0 -npx clawhub install team-name--my-skill +npx motovis-skillhub install my-skill +npx motovis-skillhub install my-skill@1.2.0 +npx motovis-skillhub install team-name/my-skill ``` ### Publish @@ -114,7 +114,7 @@ npx clawhub install team-name--my-skill Prepare a skill package directory, then publish it: ```bash -npx clawhub publish ./my-skill +npx motovis-skillhub publish ./my-skill ``` Publishing requires authentication and sufficient permissions in the target namespace. diff --git a/web/src/features/skill/install-command.test.ts b/web/src/features/skill/install-command.test.ts index 1f4daf50..cecd209c 100644 --- a/web/src/features/skill/install-command.test.ts +++ b/web/src/features/skill/install-command.test.ts @@ -51,14 +51,14 @@ describe('install-command', () => { it('uses the plain slug for the global namespace', () => { expect(buildInstallTarget('global', 'my-skill')).toBe('my-skill') expect(buildInstallCommand('global', 'my-skill', 'https://skill.xfyun.cn')).toBe( - 'npx clawhub install my-skill --registry https://skill.xfyun.cn', + 'npx motovis-skillhub install my-skill --registry https://skill.xfyun.cn', ) }) it('prefixes non-global namespaces in the install target', () => { - expect(buildInstallTarget('team-alpha', 'my-skill')).toBe('team-alpha--my-skill') + expect(buildInstallTarget('team-alpha', 'my-skill')).toBe('team-alpha/my-skill') expect(buildInstallCommand('team-alpha', 'my-skill', 'https://skill.xfyun.cn')).toBe( - 'npx clawhub install team-alpha--my-skill --registry https://skill.xfyun.cn', + 'npx motovis-skillhub install team-alpha/my-skill --registry https://skill.xfyun.cn', ) }) diff --git a/web/src/features/skill/install-command.tsx b/web/src/features/skill/install-command.tsx index f9989abb..c1330ed9 100644 --- a/web/src/features/skill/install-command.tsx +++ b/web/src/features/skill/install-command.tsx @@ -11,7 +11,7 @@ interface InstallCommandProps { } export function buildInstallTarget(namespace: string, slug: string): string { - return namespace === 'global' ? slug : `${namespace}--${slug}` + return namespace === 'global' ? slug : `${namespace}/${slug}` } export function getBaseUrl(): string { @@ -30,7 +30,7 @@ export function getBaseUrl(): string { export function buildInstallCommand(namespace: string, slug: string, baseUrl: string): string { const installTarget = buildInstallTarget(namespace, slug) - return `npx clawhub install ${installTarget} --registry ${baseUrl}` + return `npx motovis-skillhub install ${installTarget} --registry ${baseUrl}` } export function InstallCommand({ namespace, slug }: InstallCommandProps) { diff --git a/web/src/i18n/locales/en.json b/web/src/i18n/locales/en.json index 501e5781..6f095b4f 100644 --- a/web/src/i18n/locales/en.json +++ b/web/src/i18n/locales/en.json @@ -112,22 +112,22 @@ }, "human": { "description": "Use the CLI tool to install Skills", - "command": "npx clawhub search " + "command": "npx motovis-skillhub search " }, "steps": { "configureEnv": { "title": "1. Configure Environment Variables", - "description": "Configure ClawHub CLI to connect to SkillHub" + "description": "Configure SkillHub CLI to connect to Registry" }, "installSkills": { "title": "2. Install Skills", "description": "Search and install the skills you need", - "code": "# Search skills\nclawhub search \n\n# Install skill\nclawhub install " + "code": "# Search skills\nskillhub search \n\n# Install skill\nskillhub install " }, "publishSkills": { "title": "3. Publish Skills", "description": "Share your skills with the team", - "code": "# Publish skill\nclawhub publish\n\n# Or use web interface\n# Click \"Publish Skill\"" + "code": "# Publish skill\nskillhub publish\n\n# Or use web interface\n# Click \"Publish Skill\"" } } } @@ -150,17 +150,17 @@ "steps": { "configureEnv": { "title": "1. Configure Environment Variables", - "description": "Configure ClawHub CLI to connect to SkillHub" + "description": "Configure SkillHub CLI to connect to Registry" }, "installSkills": { "title": "2. Install Skills", "description": "Search and install the skills you need", - "code": "# Search skills\nclawhub search \n\n# Install skill\nclawhub install " + "code": "# Search skills\nskillhub search \n\n# Install skill\nskillhub install " }, "publishSkills": { "title": "3. Publish Skills", "description": "Share your skills with the team", - "code": "# Publish skill\nclawhub publish\n\n# Or use web interface\n# Click \"Publish Skill\"" + "code": "# Publish skill\nskillhub publish\n\n# Or use web interface\n# Click \"Publish Skill\"" } } } diff --git a/web/src/i18n/locales/zh.json b/web/src/i18n/locales/zh.json index ebdc169b..14fd66fc 100644 --- a/web/src/i18n/locales/zh.json +++ b/web/src/i18n/locales/zh.json @@ -112,22 +112,22 @@ }, "human": { "description": "使用CLI工具安装Skills", - "command": "npx clawhub search " + "command": "npx motovis-skillhub search " }, "steps": { "configureEnv": { "title": "1. 配置环境变量", - "description": "设置 ClawHub CLI 连接到 SkillHub" + "description": "设置 SkillHub CLI 连接到 Registry" }, "installSkills": { "title": "2. 安装技能", "description": "搜索并安装你需要的技能", - "code": "# 搜索技能\nclawhub search \n\n# 安装技能\nclawhub install " + "code": "# 搜索技能\nskillhub search \n\n# 安装技能\nskillhub install " }, "publishSkills": { "title": "3. 发布技能", "description": "分享你的技能给团队使用", - "code": "# 发布技能\nclawhub publish\n\n# 或使用网页界面\n# 点击\"发布技能\"" + "code": "# 发布技能\nskillhub publish\n\n# 或使用网页界面\n# 点击\"发布技能\"" } } } @@ -150,17 +150,17 @@ "steps": { "configureEnv": { "title": "1. 配置环境变量", - "description": "设置 ClawHub CLI 连接到 SkillHub" + "description": "设置 SkillHub CLI 连接到 Registry" }, "installSkills": { "title": "2. 安装技能", "description": "搜索并安装你需要的技能", - "code": "# 搜索技能\nclawhub search \n\n# 安装技能\nclawhub install " + "code": "# 搜索技能\nskillhub search \n\n# 安装技能\nskillhub install " }, "publishSkills": { "title": "3. 发布技能", "description": "分享你的技能给团队使用", - "code": "# 发布技能\nclawhub publish\n\n# 或使用网页界面\n# 点击\"发布技能\"" + "code": "# 发布技能\nskillhub publish\n\n# 或使用网页界面\n# 点击\"发布技能\"" } } } diff --git a/web/src/shared/components/quick-start.tsx b/web/src/shared/components/quick-start.tsx index daedcb05..2a0cd18c 100644 --- a/web/src/shared/components/quick-start.tsx +++ b/web/src/shared/components/quick-start.tsx @@ -64,11 +64,11 @@ function CodeLine({ line }: { line: string }) { ) } - if (line.startsWith('clawhub')) { + if (line.startsWith('skillhub')) { return ( <> - clawhub - {line.slice(7)} + skillhub + {line.slice(8)} ) } @@ -132,19 +132,17 @@ export function QuickStartSection({ variant = 'page', ns = 'landing' }: QuickSta const baseUrl = useMemo(() => getAppBaseUrl(), []) const envCode = `# Linux/macOS -export CLAWHUB_SITE=${baseUrl} -export CLAWHUB_REGISTRY=${baseUrl} +export SKILLHUB_REGISTRY=${baseUrl} # Windows PowerShell -$env:CLAWHUB_SITE = '${baseUrl}' -$env:CLAWHUB_REGISTRY = '${baseUrl}'` +$env:SKILLHUB_REGISTRY = '${baseUrl}'` const installCode = t(`${ns}.quickStart.steps.installSkills.code`, { - defaultValue: '# 搜索技能\nclawhub search \n\n# 安装技能\nclawhub install ', + defaultValue: '# 搜索技能\nskillhub search \n\n# 安装技能\nskillhub install ', }) const publishCode = t(`${ns}.quickStart.steps.publishSkills.code`, { - defaultValue: '# 发布技能\nclawhub publish\n\n# 或使用网页界面\n# 点击"发布技能"', + defaultValue: '# 发布技能\nskillhub publish\n\n# 或使用网页界面\n# 点击"发布技能"', }) const steps: CodeBlockProps[] = [ diff --git a/web/vite.config.ts b/web/vite.config.ts index aff7ad67..27d6bce5 100644 --- a/web/vite.config.ts +++ b/web/vite.config.ts @@ -1,32 +1,87 @@ -import { defineConfig } from 'vite' +import fs from 'fs' +import { defineConfig, loadEnv, type ProxyOptions } from 'vite' import react from '@vitejs/plugin-react' import path from 'path' -export default defineConfig({ - plugins: [react()], - resolve: { - alias: { - '@': path.resolve(__dirname, './src'), - }, - }, - test: { - exclude: ['**/node_modules/**', '**/e2e/**'], - }, - server: { - port: 3000, - watch: { - usePolling: true, - interval: 150, - }, - proxy: { - '/api': { - target: 'http://localhost:8080', - changeOrigin: true, +function forwardOriginalHostToBackend(): NonNullable { + return (proxy) => { + proxy.on('proxyReq', (proxyReq, req) => { + const host = req.headers.host + if (host) { + proxyReq.setHeader('X-Forwarded-Host', host) + const proto = req.headers['x-forwarded-proto'] + proxyReq.setHeader( + 'X-Forwarded-Proto', + typeof proto === 'string' ? proto : 'http', + ) + } + }) + } +} + +export default defineConfig(({ mode }) => { + const env = loadEnv(mode, process.cwd(), '') + // Override with VITE_BACKEND_URL in .env.local + const backend = env.VITE_BACKEND_URL || 'http://localhost:8080' + + return { + plugins: [ + react(), + { + name: 'serve-skill-md', + configureServer(server) { + server.middlewares.use('/registry/skill.md', (_req, res) => { + const template = fs.readFileSync( + path.resolve(__dirname, 'src/docs/skill.md.template'), + 'utf-8', + ) + const origin = `http://localhost:${server.config.server.port || 8181}` + res.setHeader('Content-Type', 'text/plain; charset=utf-8') + res.end( + template.replace(/\$\{SKILLHUB_PUBLIC_BASE_URL\}/g, origin), + ) + }) + }, }, - '/oauth2': { - target: 'http://localhost:8080', - changeOrigin: true, + ], + resolve: { + alias: { + '@': path.resolve(__dirname, './src'), }, }, - }, + test: { + exclude: ['**/node_modules/**', '**/e2e/**'], + }, + server: { + // Listen on 0.0.0.0 so LAN / other machines can reach dev (still need firewall rules for true public IP). + host: true, + port: 8181, + watch: { + usePolling: true, + interval: 150, + }, + proxy: { + '/api': { + target: backend, + changeOrigin: true, + configure: forwardOriginalHostToBackend(), + }, + '/oauth2': { + target: backend, + changeOrigin: true, + configure: forwardOriginalHostToBackend(), + }, + '/login/oauth2': { + target: backend, + changeOrigin: true, + configure: forwardOriginalHostToBackend(), + }, + '/actuator': { + target: backend, + changeOrigin: true, + configure: forwardOriginalHostToBackend(), + }, + }, + }, + } })