skillhub/cli/test/integration/help-command.test.ts
XiaoSeS a062c8f34a docs(cli): clarify suite registry compatibility
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-09-09 19:19:40 +08:00

124 lines
5 KiB
TypeScript

import { describe, expect, test } from 'bun:test'
import { runCli } from '../helpers/run-cli'
describe('help command', () => {
test('prints detailed help for install', async () => {
const result = await runCli(['help', 'install'])
expect(result.exitCode).toBe(0)
expect(result.stdout).toContain('Usage: skillhub install <coordinate>')
expect(result.stdout).toContain('--agent <profile>')
expect(result.stdout).toContain('--version <v>')
expect(result.stdout).toContain('--registry <url>')
expect(result.stdout).toContain('@team/my-skill')
expect(result.stdout).toContain('team/my-skill')
expect(result.stdout).toContain('team--my-skill')
})
test('prints namespaced local remove contract in command help', async () => {
const result = await runCli(['help', 'remove'])
expect(result.exitCode).toBe(0)
expect(result.stdout).toContain('Usage: skillhub remove <coordinate>')
expect(result.stdout).toContain('skillhub remove team/my-skill')
expect(result.stdout).toContain('skillhub remove my-skill --namespace team')
expect(result.stdout).toContain('--registry <url>')
})
test('prints namespaced local remove contract in --help', async () => {
const result = await runCli(['remove', '--help'])
expect(result.exitCode).toBe(0)
expect(result.stdout).toContain('remove <coordinate>')
expect(result.stdout).toContain('Namespace for local or remote delete')
})
test('prints search help with optional query', async () => {
const result = await runCli(['help', 'search'])
expect(result.exitCode).toBe(0)
expect(result.stdout).toContain('Usage: skillhub search [query]')
expect(result.stdout).toContain('skillhub search')
})
test('states that Suite commands require a compatible registry', async () => {
const topic = await runCli(['help', 'suite'])
expect(topic.exitCode).toBe(0)
expect(topic.stdout).toContain('Manage Skill Suites on compatible registries')
const root = await runCli(['--help'])
expect(root.exitCode).toBe(0)
expect(root.stdout).toContain('Manage Skill Suites on compatible registries')
})
test('distinguishes skill upgrade from CLI self-update and namespace sync', async () => {
const upgrade = await runCli(['help', 'upgrade'])
expect(upgrade.exitCode).toBe(0)
expect(upgrade.stdout).toContain('Upgrade explicitly selected installed skills')
expect(upgrade.stdout).toContain('skillhub upgrade <coordinate...>')
expect(upgrade.stdout).toContain('--check')
expect(upgrade.stdout).toContain('--force')
const update = await runCli(['help', 'update'])
expect(update.exitCode).toBe(0)
expect(update.stdout).toContain('Check or update CLI itself')
const sync = await runCli(['help', 'sync'])
expect(sync.exitCode).toBe(0)
expect(sync.stdout).toContain('namespace workspaces')
expect(sync.stdout).toContain('--namespace <slug>')
expect(sync.stdout).toContain('--skill <slug>')
const publish = await runCli(['help', 'publish'])
expect(publish.exitCode).toBe(0)
expect(publish.stdout).toContain('--dry-run')
expect(publish.stdout).toContain('--registry <url>')
})
// P1: bare `skillhub help` (no topic) prints the directory of all commands
test('bare help lists all commands in human format', async () => {
const result = await runCli(['help'])
expect(result.exitCode).toBe(0)
// Sample at least 6 of the 12 known commands appear in the output
for (const name of ['login', 'logout', 'search', 'install', 'list', 'publish']) {
expect(result.stdout).toContain(name)
}
})
test('help --json returns a parseable command directory', async () => {
const result = await runCli(['help', '--json'])
expect(result.exitCode).toBe(0)
expect(result.stderr).toBe('')
expect(JSON.parse(result.stdout)).toMatchObject({
ok: true,
commands: expect.arrayContaining([
{ name: 'install', description: 'Install a skill locally' }
])
})
})
test('help <topic> --json returns parseable command detail', async () => {
const result = await runCli(['help', 'install', '--json'])
expect(result.exitCode).toBe(0)
expect(result.stderr).toBe('')
expect(JSON.parse(result.stdout)).toMatchObject({
ok: true,
command: 'install',
summary: 'Install a skill locally'
})
})
test('help <unknown-topic> returns a clear usage error', async () => {
const result = await runCli(['help', 'definitely-not-a-command'])
expect(result.exitCode).toBe(5)
expect(result.stderr).toContain('unknown help topic: definitely-not-a-command')
expect(result.stderr).not.toContain('TypeError')
})
test('help <unknown-topic> --json returns a structured error only on stderr', async () => {
const result = await runCli(['help', 'definitely-not-a-command', '--json'])
expect(result.exitCode).toBe(5)
expect(result.stdout).toBe('')
expect(JSON.parse(result.stderr)).toMatchObject({
ok: false,
message: 'unknown help topic: definitely-not-a-command',
exitCode: 5
})
})
})