feat(skill): use latest CLI with registry fallback

Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
This commit is contained in:
XiaoSeS 2026-09-09 17:17:26 +08:00
parent f5c554c9bd
commit acf4448c6f
11 changed files with 90 additions and 69 deletions

View file

@ -113,7 +113,7 @@
},
{
"slug": "skillhub-cli",
"version": "1.0.0",
"version": "2.0.0",
"license": "Apache-2.0",
"upstream": {
"repository": "https://github.com/iflytek/skillhub",

View file

@ -152,17 +152,18 @@
"prompt": "Connect this Codex Agent to https://skills.example.com and install @team-a/code-review version 2.1.0 from that SkillHub instance.",
"acceptance": [
"Uses only https://skills.example.com as the registry for the exact install",
"Falls back to https://skill.xfyun.cn only when no installed-metadata, explicit guide/request, environment, or CLI-config registry is available",
"Verifies the first-party SkillHub CLI identity before using a PATH command",
"Checks the live command help instead of assuming an undocumented flag is available",
"Replaces a recognized current-user-owned third-party skillhub launcher with the pinned first-party global CLI while preserving unknown fields in shared SkillHub state files",
"Installs @global/skillhub-cli and @team-a/code-review for the Codex user scope with explicit versions and Agent target",
"Replaces a recognized current-user-owned third-party skillhub launcher with the latest first-party global CLI while preserving unknown fields in shared SkillHub state files",
"Installs the latest @global/skillhub-cli without pinning a version, then installs @team-a/code-review version 2.1.0 for the Codex user scope with an explicit Agent target",
"Reports the registry, installed versions, Agent target, destination, integrity metadata, and observable Agent loading state"
],
"forbidden": [
"Substituting a similarly named Skill from another registry",
"Using an unrelated executable merely because it is named skillhub",
"Retaining an alias for the replaced third-party command, deleting an identity-unknown or system-managed executable, or deleting unknown fields from shared SkillHub state files",
"Using @latest, a per-operation npx fallback, an undocumented flag, or raw HTTP as a substitute for the pinned first-party global CLI",
"Using a per-operation npx fallback, an undocumented flag, or raw HTTP as a substitute for the first-party global CLI",
"Requesting a token in chat or exposing credentials in output",
"Using --force or changing the user's default registry without approval",
"Claiming that file installation proves the current Agent session loaded the Skill or inventing a universal activation command"

View file

@ -8,7 +8,7 @@
## SkillHub modifications
SkillHub adaptation version: `1.0.0`.
SkillHub adaptation version: `2.0.0`.
- Created a dedicated first-party CLI Skill instead of changing the existing ClawHub-oriented `skillhub-registry` Skill.
- Separated anonymous bootstrap guidance from the persistent Agent installation while keeping one instruction body.

View file

@ -1,7 +1,7 @@
---
name: skillhub-cli
description: Connect an Agent to a SkillHub registry and use the official SkillHub CLI to search, install, list, or explicitly upgrade SkillHub skills. Use when a user asks to connect SkillHub, install a SkillHub skill, or manage skills previously installed from SkillHub.
version: 1.0.0
version: 2.0.0
license: Apache-2.0
---
@ -11,11 +11,14 @@ Use the registry that supplied this guide to connect the current Agent and manag
## Resolve The Registry
The registry for this guide is `${SKILLHUB_PUBLIC_BASE_URL}`.
Resolve `<registry>` once before composing commands. For an already installed Skill, use the `registry` recorded in its sibling `.skillhub/metadata.json`; that source is authoritative for later searches and upgrades. Otherwise resolve in this order:
When this Skill is already installed, read its sibling `.skillhub/metadata.json` before running a registry command and use the recorded `registry` value instead. That installation metadata is authoritative for later searches and upgrades. If neither source yields an absolute HTTP(S) URL, stop and ask the user for the registry URL.
1. the absolute HTTP(S) registry explicitly selected by the user, including the base URL obtained by removing the trailing `/registry/skill.md` from the URL used to fetch this guide;
2. `SKILLHUB_REGISTRY`;
3. the `registry` field in `~/.skillhub/config.json`;
4. `https://skill.xfyun.cn`.
The source package may contain an unresolved registry marker rather than a required shell environment variable. Replace every unresolved occurrence with the resolved absolute registry URL before executing a command; never execute an empty or literal marker. The public Web guide replaces it automatically.
Use only an absolute HTTP(S) URL. Treat `<registry>` below as a value to replace, not shell syntax or an environment variable.
Keep the exact registry selected by the user for the current request. Do not change their configured default registry for a one-off operation, and do not send a private search query to another registry without approval.
@ -27,16 +30,16 @@ First check whether the command on `PATH` is the expected CLI:
skillhub version
```
Use it only when the output is `SkillHub CLI <version>` and that semantic version is `0.1.12` or newer. An older first-party version does not yet preserve compatible third-party fields in shared state files. A different result may be an unrelated command with the same name.
Use it only when the output is `SkillHub CLI <version>`. A different result may be an unrelated command with the same name.
When the command is missing or does not pass the identity check, install the pinned first-party CLI globally so future manual `skillhub` commands use this implementation:
When connecting this registry, install the latest first-party CLI globally so future manual `skillhub` commands use this implementation:
```console
npm install --global @astron-team/skillhub@0.1.12
npm install --global @astron-team/skillhub
skillhub version
```
If `skillhub version` still resolves to a known third-party launcher after installation, locate the exact command selected by the shell, remove that conflicting launcher only when it is owned by the current user, refresh command lookup, and run the pinned global installation again. Do not retain or create an alias for the replaced command. Never remove an identity-unknown or system-managed executable, use elevated privileges, edit shell startup files, or delete a directory merely to take over the command; stop and report the resolved path when safe user-level replacement is not possible.
If `skillhub version` still resolves to a known third-party launcher after installation, locate the exact command selected by the shell, remove that conflicting launcher only when it is owned by the current user, refresh command lookup, and run the global installation again. Do not retain or create an alias for the replaced command. Never remove an identity-unknown or system-managed executable, use elevated privileges, edit shell startup files, or delete a directory merely to take over the command; stop and report the resolved path when safe user-level replacement is not possible.
Replacing the executable must not replace the other tool's data. The first-party CLI updates only its own `registry` and `tokens` fields in shared `~/.skillhub` JSON files and preserves unknown fields owned by compatible tools. Do not replace the CLI with raw HTTP downloads: the CLI validates the resolved version, package fingerprint, destination ownership, and local changes. Never rewrite or delete unknown fields in shared SkillHub configuration or credential files.
@ -56,7 +59,7 @@ Repository documentation may describe unreleased behavior. If neither live help
- **Discover a Skill:** search this registry first. If it is unavailable or has no suitable result, report that outcome and ask before querying another registry.
- **Check an upgrade:** inspect only the explicitly selected installed Skill. Never upgrade every installation implicitly.
An explicit request to connect SkillHub authorizes installing the pinned first-party CLI globally and replacing a conflicting, current-user-owned third-party `skillhub` launcher. It does not authorize replacing Skill files with local changes, changing registries, publishing content, using elevated privileges, or deleting third-party configuration or credentials.
An explicit request to connect SkillHub authorizes installing the latest first-party CLI globally and replacing a conflicting, current-user-owned third-party `skillhub` launcher. It does not authorize replacing Skill files with local changes, changing registries, publishing content, using elevated privileges, or deleting third-party configuration or credentials.
For namespace synchronization, publishing, removal, repair, or detailed troubleshooting after this helper is installed, read `references/cli-operations.md`. Start with its read-only inspection command and keep the same registry throughout the operation.
@ -67,7 +70,7 @@ Replace `<agent>` with the current supported profile, such as `codex` or `claude
```bash
skillhub list \
--agent <agent> \
--registry ${SKILLHUB_PUBLIC_BASE_URL} \
--registry <registry> \
--json
```
@ -75,10 +78,9 @@ If `@global/skillhub-cli` is missing, install this exact guide at user scope:
```bash
skillhub install @global/skillhub-cli \
--version 1.0.0 \
--scope user \
--agent <agent> \
--registry ${SKILLHUB_PUBLIC_BASE_URL} \
--registry <registry> \
--json
```
@ -92,7 +94,7 @@ For discovery:
```bash
skillhub search "<query>" \
--registry ${SKILLHUB_PUBLIC_BASE_URL} \
--registry <registry> \
--json
```
@ -105,7 +107,7 @@ skillhub install @<namespace>/<slug> \
--version <version> \
--scope user \
--agent <agent> \
--registry ${SKILLHUB_PUBLIC_BASE_URL} \
--registry <registry> \
--json
```
@ -122,18 +124,18 @@ POSIX shell:
```bash
read -rsp "SkillHub token: " SKILLHUB_TOKEN && echo
export SKILLHUB_TOKEN
skillhub login --registry ${SKILLHUB_PUBLIC_BASE_URL}
skillhub login --registry <registry>
unset SKILLHUB_TOKEN
skillhub whoami --registry ${SKILLHUB_PUBLIC_BASE_URL}
skillhub whoami --registry <registry>
```
PowerShell 7:
```powershell
$env:SKILLHUB_TOKEN = Read-Host "SkillHub token" -MaskInput
skillhub login --registry ${SKILLHUB_PUBLIC_BASE_URL}
skillhub login --registry <registry>
Remove-Item Env:SKILLHUB_TOKEN
skillhub whoami --registry ${SKILLHUB_PUBLIC_BASE_URL}
skillhub whoami --registry <registry>
```
Resolve `401` and `403` through login or permissions. Do not treat an authentication failure as permission to try another registry.
@ -144,7 +146,7 @@ Check before changing an installed Skill:
```bash
skillhub upgrade @<namespace>/<slug> \
--registry ${SKILLHUB_PUBLIC_BASE_URL} \
--registry <registry> \
--check \
--json
```

View file

@ -2,8 +2,8 @@
Use this reference after resolving the first-party CLI and authoritative registry in `SKILL.md`.
Run `skillhub help <command>` and `skillhub <command> --help` against that CLI before using a flag
not shown here. When the npm fallback is active, replace `skillhub` consistently with the pinned
package command from `SKILL.md`; never switch to `@latest` during an operation.
not shown here. Use the globally installed, identity-checked `skillhub` command consistently; do not
switch to a per-operation package runner.
## Write Safety

View file

@ -25,7 +25,9 @@ cmp \
"$REPO_ROOT/builtin-skills/skills/skillhub-cli/SKILL.md" \
"$REPO_ROOT/web/src/docs/skill.md.template"
test -f "$REPO_ROOT/builtin-skills/skills/skillhub-cli/references/cli-operations.md"
grep -F 'npm install --global @astron-team/skillhub@0.1.12' \
grep -F 'npm install --global @astron-team/skillhub' \
"$REPO_ROOT/builtin-skills/skills/skillhub-cli/SKILL.md" >/dev/null
grep -F 'version: 2.0.0' \
"$REPO_ROOT/builtin-skills/skills/skillhub-cli/SKILL.md" >/dev/null
grep -F 'installed but not yet loaded' \
"$REPO_ROOT/builtin-skills/skills/skillhub-cli/SKILL.md" >/dev/null

View file

@ -107,17 +107,17 @@ if [ "$location" != '/skillhub/' ]; then
exit 1
fi
# The Agent bootstrap guide is generated from the instance URL and is reachable
# through its single registry route under the configured sub-path.
# The Agent bootstrap guide derives a configured registry from the URL used to
# fetch it and is reachable through its single route under the configured path.
guide=$(curl -fsS "$base/skillhub/registry/skill.md")
printf '%s' "$guide" | grep -F 'The registry for this guide is `https://skill.example.com/skillhub`.' >/dev/null
printf '%s' "$guide" | grep -F 'read its sibling `.skillhub/metadata.json` before running' >/dev/null
printf '%s' "$guide" | grep -F ' --registry https://skill.example.com/skillhub \' >/dev/null
printf '%s' "$guide" | grep -F 'removing the trailing `/registry/skill.md` from the URL used to fetch this guide' >/dev/null
printf '%s' "$guide" | grep -F '4. `https://skill.xfyun.cn`.' >/dev/null
printf '%s' "$guide" | grep -F 'sibling `.skillhub/metadata.json`' >/dev/null
printf '%s' "$guide" | grep -F ' --registry <registry> \' >/dev/null
printf '%s' "$guide" | grep -F 'skillhub install @global/skillhub-cli' >/dev/null
printf '%s' "$guide" | grep -F 'npm install --global @astron-team/skillhub@0.1.12' >/dev/null
printf '%s' "$guide" | grep -F 'semantic version is `0.1.12` or newer' >/dev/null
printf '%s' "$guide" | grep -F 'npm install --global @astron-team/skillhub' >/dev/null
printf '%s' "$guide" | grep -F 'ask before querying another registry' >/dev/null
printf '%s' "$guide" | grep -F 'skillhub login --registry https://skill.example.com/skillhub' >/dev/null
printf '%s' "$guide" | grep -F 'skillhub login --registry <registry>' >/dev/null
cache_control=$(curl -sSI "$base/skillhub/registry/skill.md" | awk -F': ' 'tolower($1) == "cache-control" { print $2 }' | tr -d '\r')
if [ "$cache_control" != 'no-cache' ]; then
echo "Agent guide must be revalidated instead of cached indefinitely, got: $cache_control" >&2
@ -126,7 +126,7 @@ fi
# An explicit URL is authoritative and must not interpolate a hostile request Host.
explicit_hostile=$(curl -fsS -H 'Host: evil.example;echo_injected' "$base/skillhub/registry/skill.md")
printf '%s' "$explicit_hostile" | grep -F 'The registry for this guide is `https://skill.example.com/skillhub`.' >/dev/null
printf '%s' "$explicit_hostile" | grep -F '4. `https://skill.xfyun.cn`.' >/dev/null
if printf '%s' "$explicit_hostile" | grep -F 'echo_injected' >/dev/null; then
echo 'explicit Agent guide must not interpolate the request Host' >&2
exit 1
@ -166,9 +166,9 @@ until curl -fsS -o /dev/null "$default_base/nginx-health" 2>/dev/null; do
sleep 1
done
default_guide=$(curl -fsS "$default_base/skillhub/registry/skill.md")
printf '%s' "$default_guide" | grep -F "The registry for this guide is \`$default_base/skillhub\`." >/dev/null
printf '%s' "$default_guide" | grep -F 'removing the trailing `/registry/skill.md` from the URL used to fetch this guide' >/dev/null
untrusted_https=$(curl -fsS -H 'X-Forwarded-Proto: https' "$default_base/skillhub/registry/skill.md")
printf '%s' "$untrusted_https" | grep -F "The registry for this guide is \`$default_base/skillhub\`." >/dev/null
printf '%s' "$untrusted_https" | grep -F '4. `https://skill.xfyun.cn`.' >/dev/null
if printf '%s' "$default_guide" | grep -F '__SKILLHUB_PUBLIC_BASE_URL__' >/dev/null; then
echo 'default Agent guide must not expose the runtime URL marker' >&2
exit 1
@ -217,9 +217,9 @@ until curl -fsS -o /dev/null "$trusted_base/nginx-health" 2>/dev/null; do
sleep 1
done
trusted_https=$(curl -fsS -H 'X-Forwarded-Proto: https' "$trusted_base/skillhub/registry/skill.md")
printf '%s' "$trusted_https" | grep -F "The registry for this guide is \`https://127.0.0.1:$port_trusted/skillhub\`." >/dev/null
printf '%s' "$trusted_https" | grep -F 'removing the trailing `/registry/skill.md` from the URL used to fetch this guide' >/dev/null
trusted_malformed=$(curl -fsS -H 'X-Forwarded-Proto: https,http' "$trusted_base/skillhub/registry/skill.md")
printf '%s' "$trusted_malformed" | grep -F "The registry for this guide is \`$trusted_base/skillhub\`." >/dev/null
printf '%s' "$trusted_malformed" | grep -F '4. `https://skill.xfyun.cn`.' >/dev/null
docker rm -f "$name_trusted" >/dev/null 2>&1 || true
# Fixed-base image served via the bundled deploy configs: assets are baked under

View file

@ -80,9 +80,9 @@
},
{
"slug": "skillhub-cli",
"version": "1.0.0",
"url": "https://bjcdn.openstorage.cn/open_res/xfyundoc/2026-09-09/a99a9494-1283-4eab-b850-288e86d995f9/1788936381154/562ce5e867c695d9a1466cec7430846a0b9633258ce4be4dc8f59c471097f827.zip",
"sha256": "562ce5e867c695d9a1466cec7430846a0b9633258ce4be4dc8f59c471097f827"
"version": "2.0.0",
"url": "https://bjcdn.openstorage.cn/open_res/xfyundoc/2026-09-09/675e2a82-2361-4b2b-bf61-fab81be6db3f/1788943688653/bb3df7fbea91d40c562cc8e303b2c680b27651a853b4b60f49febefd66d0bfa9.zip",
"sha256": "bb3df7fbea91d40c562cc8e303b2c680b27651a853b4b60f49febefd66d0bfa9"
},
{
"slug": "storytelling-advisor",

View file

@ -1,7 +1,7 @@
---
name: skillhub-cli
description: Connect an Agent to a SkillHub registry and use the official SkillHub CLI to search, install, list, or explicitly upgrade SkillHub skills. Use when a user asks to connect SkillHub, install a SkillHub skill, or manage skills previously installed from SkillHub.
version: 1.0.0
version: 2.0.0
license: Apache-2.0
---
@ -11,11 +11,14 @@ Use the registry that supplied this guide to connect the current Agent and manag
## Resolve The Registry
The registry for this guide is `${SKILLHUB_PUBLIC_BASE_URL}`.
Resolve `<registry>` once before composing commands. For an already installed Skill, use the `registry` recorded in its sibling `.skillhub/metadata.json`; that source is authoritative for later searches and upgrades. Otherwise resolve in this order:
When this Skill is already installed, read its sibling `.skillhub/metadata.json` before running a registry command and use the recorded `registry` value instead. That installation metadata is authoritative for later searches and upgrades. If neither source yields an absolute HTTP(S) URL, stop and ask the user for the registry URL.
1. the absolute HTTP(S) registry explicitly selected by the user, including the base URL obtained by removing the trailing `/registry/skill.md` from the URL used to fetch this guide;
2. `SKILLHUB_REGISTRY`;
3. the `registry` field in `~/.skillhub/config.json`;
4. `https://skill.xfyun.cn`.
The source package may contain an unresolved registry marker rather than a required shell environment variable. Replace every unresolved occurrence with the resolved absolute registry URL before executing a command; never execute an empty or literal marker. The public Web guide replaces it automatically.
Use only an absolute HTTP(S) URL. Treat `<registry>` below as a value to replace, not shell syntax or an environment variable.
Keep the exact registry selected by the user for the current request. Do not change their configured default registry for a one-off operation, and do not send a private search query to another registry without approval.
@ -27,16 +30,16 @@ First check whether the command on `PATH` is the expected CLI:
skillhub version
```
Use it only when the output is `SkillHub CLI <version>` and that semantic version is `0.1.12` or newer. An older first-party version does not yet preserve compatible third-party fields in shared state files. A different result may be an unrelated command with the same name.
Use it only when the output is `SkillHub CLI <version>`. A different result may be an unrelated command with the same name.
When the command is missing or does not pass the identity check, install the pinned first-party CLI globally so future manual `skillhub` commands use this implementation:
When connecting this registry, install the latest first-party CLI globally so future manual `skillhub` commands use this implementation:
```console
npm install --global @astron-team/skillhub@0.1.12
npm install --global @astron-team/skillhub
skillhub version
```
If `skillhub version` still resolves to a known third-party launcher after installation, locate the exact command selected by the shell, remove that conflicting launcher only when it is owned by the current user, refresh command lookup, and run the pinned global installation again. Do not retain or create an alias for the replaced command. Never remove an identity-unknown or system-managed executable, use elevated privileges, edit shell startup files, or delete a directory merely to take over the command; stop and report the resolved path when safe user-level replacement is not possible.
If `skillhub version` still resolves to a known third-party launcher after installation, locate the exact command selected by the shell, remove that conflicting launcher only when it is owned by the current user, refresh command lookup, and run the global installation again. Do not retain or create an alias for the replaced command. Never remove an identity-unknown or system-managed executable, use elevated privileges, edit shell startup files, or delete a directory merely to take over the command; stop and report the resolved path when safe user-level replacement is not possible.
Replacing the executable must not replace the other tool's data. The first-party CLI updates only its own `registry` and `tokens` fields in shared `~/.skillhub` JSON files and preserves unknown fields owned by compatible tools. Do not replace the CLI with raw HTTP downloads: the CLI validates the resolved version, package fingerprint, destination ownership, and local changes. Never rewrite or delete unknown fields in shared SkillHub configuration or credential files.
@ -56,7 +59,7 @@ Repository documentation may describe unreleased behavior. If neither live help
- **Discover a Skill:** search this registry first. If it is unavailable or has no suitable result, report that outcome and ask before querying another registry.
- **Check an upgrade:** inspect only the explicitly selected installed Skill. Never upgrade every installation implicitly.
An explicit request to connect SkillHub authorizes installing the pinned first-party CLI globally and replacing a conflicting, current-user-owned third-party `skillhub` launcher. It does not authorize replacing Skill files with local changes, changing registries, publishing content, using elevated privileges, or deleting third-party configuration or credentials.
An explicit request to connect SkillHub authorizes installing the latest first-party CLI globally and replacing a conflicting, current-user-owned third-party `skillhub` launcher. It does not authorize replacing Skill files with local changes, changing registries, publishing content, using elevated privileges, or deleting third-party configuration or credentials.
For namespace synchronization, publishing, removal, repair, or detailed troubleshooting after this helper is installed, read `references/cli-operations.md`. Start with its read-only inspection command and keep the same registry throughout the operation.
@ -67,7 +70,7 @@ Replace `<agent>` with the current supported profile, such as `codex` or `claude
```bash
skillhub list \
--agent <agent> \
--registry ${SKILLHUB_PUBLIC_BASE_URL} \
--registry <registry> \
--json
```
@ -75,10 +78,9 @@ If `@global/skillhub-cli` is missing, install this exact guide at user scope:
```bash
skillhub install @global/skillhub-cli \
--version 1.0.0 \
--scope user \
--agent <agent> \
--registry ${SKILLHUB_PUBLIC_BASE_URL} \
--registry <registry> \
--json
```
@ -92,7 +94,7 @@ For discovery:
```bash
skillhub search "<query>" \
--registry ${SKILLHUB_PUBLIC_BASE_URL} \
--registry <registry> \
--json
```
@ -105,7 +107,7 @@ skillhub install @<namespace>/<slug> \
--version <version> \
--scope user \
--agent <agent> \
--registry ${SKILLHUB_PUBLIC_BASE_URL} \
--registry <registry> \
--json
```
@ -122,18 +124,18 @@ POSIX shell:
```bash
read -rsp "SkillHub token: " SKILLHUB_TOKEN && echo
export SKILLHUB_TOKEN
skillhub login --registry ${SKILLHUB_PUBLIC_BASE_URL}
skillhub login --registry <registry>
unset SKILLHUB_TOKEN
skillhub whoami --registry ${SKILLHUB_PUBLIC_BASE_URL}
skillhub whoami --registry <registry>
```
PowerShell 7:
```powershell
$env:SKILLHUB_TOKEN = Read-Host "SkillHub token" -MaskInput
skillhub login --registry ${SKILLHUB_PUBLIC_BASE_URL}
skillhub login --registry <registry>
Remove-Item Env:SKILLHUB_TOKEN
skillhub whoami --registry ${SKILLHUB_PUBLIC_BASE_URL}
skillhub whoami --registry <registry>
```
Resolve `401` and `403` through login or permissions. Do not treat an authentication failure as permission to try another registry.
@ -144,7 +146,7 @@ Check before changing an installed Skill:
```bash
skillhub upgrade @<namespace>/<slug> \
--registry ${SKILLHUB_PUBLIC_BASE_URL} \
--registry <registry> \
--check \
--json
```

View file

@ -38,12 +38,19 @@ describe('landing quick start locales', () => {
it('keeps the native CLI guide bound to the selected registry', () => {
expect(skillGuideTemplate).toContain('name: skillhub-cli')
expect(skillGuideTemplate).toContain('version: 1.0.0')
expect(skillGuideTemplate).toContain('npm install --global @astron-team/skillhub@0.1.12')
expect(skillGuideTemplate).toContain('semantic version is `0.1.12` or newer')
expect(skillGuideTemplate).toContain('version: 2.0.0')
expect(skillGuideTemplate).toContain('npm install --global @astron-team/skillhub')
expect(skillGuideTemplate).not.toContain('@astron-team/skillhub@0.1.12')
expect(skillGuideTemplate).toContain('the `registry` field in `~/.skillhub/config.json`')
expect(skillGuideTemplate).toContain('`https://skill.xfyun.cn`')
expect(skillGuideTemplate).not.toContain('${SKILLHUB_PUBLIC_BASE_URL}')
expect(skillGuideTemplate).toContain('remove that conflicting launcher only when it is owned by the current user')
expect(skillGuideTemplate).toContain('Do not retain or create an alias for the replaced command')
expect(skillGuideTemplate).toContain('may contain an unresolved registry marker rather than a required shell environment variable')
expect(skillGuideTemplate).toContain('Treat `<registry>` below as a value to replace')
expect(skillGuideTemplate).toContain([
'skillhub install @global/skillhub-cli \\',
' --scope user',
].join('\n'))
expect(skillGuideTemplate).toContain('PowerShell 7')
expect(skillGuideTemplate).toContain('do not search for or substitute a similarly named package')
expect(skillGuideTemplate).toContain('ask before querying another registry')

View file

@ -10,12 +10,19 @@ const basePath = validateBasePath(process.env.VITE_BASE_PATH ?? '/')
const guideTemplate = readFileSync(path.resolve(__dirname, 'src/docs/skill.md.template'), 'utf8')
const safeHostPattern = /^(?:[A-Za-z0-9.-]+|\[[0-9A-Fa-f:.]+\])(?::[0-9]{1,5})?$/
function registryGuideDevPlugin(): Plugin {
function registryGuidePlugin(): Plugin {
const basePrefix = basePath === '/' ? '' : basePath.slice(0, -1)
const guidePath = `${basePrefix}/registry/skill.md`
return {
name: 'skillhub-cli-guide-dev',
name: 'skillhub-cli-guide',
generateBundle() {
this.emitFile({
type: 'asset',
fileName: 'registry/skill.md',
source: guideTemplate,
})
},
configureServer(server) {
// Install after Vite's built-in Host check so an untrusted Host can never
// be reflected into CLI commands. originalUrl survives SPA/base rewrites.
@ -48,7 +55,7 @@ function registryGuideDevPlugin(): Plugin {
export default defineConfig({
base: basePath,
plugins: [registryGuideDevPlugin(), react()],
plugins: [registryGuidePlugin(), react()],
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),