mirror of
https://github.com/iflytek/skillhub.git
synced 2026-09-25 01:04:14 +00:00
127 lines
4.6 KiB
TypeScript
127 lines
4.6 KiB
TypeScript
import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises'
|
|
import { tmpdir } from 'node:os'
|
|
import { join } from 'node:path'
|
|
import { describe, expect, test } from 'bun:test'
|
|
import { allProfiles, profileMap } from '../../../src/agents/detector'
|
|
|
|
describe('agent profiles', () => {
|
|
test('has 16 tier 1 profiles', () => {
|
|
expect(allProfiles).toHaveLength(16)
|
|
})
|
|
|
|
test('all profiles have unique ids', () => {
|
|
const ids = allProfiles.map(p => p.id)
|
|
expect(new Set(ids).size).toBe(ids.length)
|
|
})
|
|
|
|
test('profileMap contains all profiles', () => {
|
|
expect(profileMap.size).toBe(16)
|
|
expect(profileMap.has('astudio')).toBe(true)
|
|
expect(profileMap.has('claude-code')).toBe(true)
|
|
expect(profileMap.has('codex')).toBe(true)
|
|
expect(profileMap.has('cursor')).toBe(true)
|
|
expect(profileMap.has('kilo')).toBe(true)
|
|
expect(profileMap.has('pi')).toBe(true)
|
|
})
|
|
|
|
test('claude-code profile returns correct roots', () => {
|
|
const profile = profileMap.get('claude-code')!
|
|
expect(profile.projectRoots('/repo')).toEqual(['/repo/.claude/skills'])
|
|
expect(profile.userRoots('/home/user')).toEqual(['/home/user/.claude/skills'])
|
|
})
|
|
|
|
test('codex profile returns correct roots', () => {
|
|
const profile = profileMap.get('codex')!
|
|
expect(profile.projectRoots('/repo')).toEqual(['/repo/.codex/skills'])
|
|
expect(profile.userRoots('/home/user')).toEqual(['/home/user/.codex/skills'])
|
|
})
|
|
|
|
test('cursor profile returns correct roots', () => {
|
|
const profile = profileMap.get('cursor')!
|
|
expect(profile.projectRoots('/repo')).toEqual(['/repo/.cursor/skills'])
|
|
})
|
|
|
|
test('Pi exposes and detects its project and user skills directories', async () => {
|
|
const base = await mkdtemp(join(tmpdir(), 'skillhub-pi-profile-'))
|
|
const cwd = join(base, 'repo')
|
|
const home = join(base, 'home')
|
|
const projectRoot = `${cwd}/.pi/skills`
|
|
const userRoot = `${home}/.pi/agent/skills`
|
|
const profile = profileMap.get('pi')!
|
|
|
|
try {
|
|
await mkdir(cwd, { recursive: true })
|
|
await mkdir(home, { recursive: true })
|
|
|
|
expect(profile.displayName).toBe('Pi')
|
|
expect(profile.projectRoots(cwd)).toEqual([projectRoot])
|
|
expect(profile.userRoots(home)).toEqual([userRoot])
|
|
expect(await profile.detectInstalled(cwd, home)).toEqual([])
|
|
|
|
await mkdir(join(cwd, '.pi'), { recursive: true })
|
|
await mkdir(join(home, '.pi', 'agent'), { recursive: true })
|
|
await writeFile(projectRoot, 'not a directory')
|
|
await writeFile(userRoot, 'not a directory')
|
|
expect(await profile.detectInstalled(cwd, home)).toEqual([])
|
|
|
|
await rm(projectRoot)
|
|
await rm(userRoot)
|
|
await mkdir(projectRoot, { recursive: true })
|
|
await mkdir(userRoot, { recursive: true })
|
|
|
|
expect(await profile.detectInstalled(cwd, home)).toEqual([
|
|
{
|
|
agent: 'pi',
|
|
rootDir: projectRoot,
|
|
scope: 'project',
|
|
source: 'detected'
|
|
},
|
|
{
|
|
agent: 'pi',
|
|
rootDir: userRoot,
|
|
scope: 'user',
|
|
source: 'detected'
|
|
}
|
|
])
|
|
} finally {
|
|
await rm(base, { recursive: true, force: true })
|
|
}
|
|
})
|
|
|
|
test('AStudio exposes only its fixed user-level directory on Linux, macOS, and Windows', () => {
|
|
const profile = profileMap.get('astudio')!
|
|
|
|
expect(profile.displayName).toBe('AStudio')
|
|
expect(profile.projectRoots('/repo')).toEqual([])
|
|
expect(profile.userRoots('/home/alice')).toEqual(['/home/alice/.acode/skills'])
|
|
expect(profile.userRoots('/Users/alice')).toEqual(['/Users/alice/.acode/skills'])
|
|
expect(profile.userRoots('C:\\Users\\alice')).toEqual(['C:/Users/alice/.acode/skills'])
|
|
})
|
|
|
|
test('AStudio is detected only when the user .acode skills directory exists', async () => {
|
|
const home = await mkdtemp(join(tmpdir(), 'skillhub-astudio-home-'))
|
|
const profile = profileMap.get('astudio')!
|
|
const nativeRootDir = join(home, '.acode', 'skills')
|
|
const profileRootDir = nativeRootDir.replace(/\\/g, '/')
|
|
|
|
try {
|
|
expect(await profile.detectInstalled('/repo', home)).toEqual([])
|
|
|
|
await mkdir(join(home, '.acode'), { recursive: true })
|
|
await writeFile(nativeRootDir, 'not a directory')
|
|
expect(await profile.detectInstalled('/repo', home)).toEqual([])
|
|
|
|
await rm(nativeRootDir)
|
|
await mkdir(nativeRootDir, { recursive: true })
|
|
|
|
expect(await profile.detectInstalled('/repo', home)).toEqual([{
|
|
agent: 'astudio',
|
|
rootDir: profileRootDir,
|
|
scope: 'user',
|
|
source: 'detected'
|
|
}])
|
|
} finally {
|
|
await rm(home, { recursive: true, force: true })
|
|
}
|
|
})
|
|
})
|