mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-21 14:03:35 +08:00
fix: collect only user skills for market state
Tested: bun test src/server/__tests__/skill-market.test.ts Tested: bun test src/server/__tests__/skill-market-install.test.ts Tested: git diff --check Confidence: high Scope-risk: narrow
This commit is contained in:
parent
da37f4b1ed
commit
f5f4ff9858
@ -1,4 +1,7 @@
|
|||||||
import { afterEach, describe, expect, it, mock } from 'bun:test'
|
import { afterEach, describe, expect, it, mock } from 'bun:test'
|
||||||
|
import * as fs from 'node:fs/promises'
|
||||||
|
import * as os from 'node:os'
|
||||||
|
import * as path from 'node:path'
|
||||||
import {
|
import {
|
||||||
handleSkillMarketApi,
|
handleSkillMarketApi,
|
||||||
resetSkillMarketServiceFactoryForTests,
|
resetSkillMarketServiceFactoryForTests,
|
||||||
@ -818,44 +821,80 @@ describe('skill market API', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('lists through the service with validated query params', async () => {
|
it('lists through the service with validated query params', async () => {
|
||||||
|
const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'skill-market-api-'))
|
||||||
|
const originalConfigDir = process.env.CLAUDE_CONFIG_DIR
|
||||||
let capturedParams: unknown
|
let capturedParams: unknown
|
||||||
let hasInstalledProvider = false
|
let installedNamesFromProvider: string[] = []
|
||||||
setSkillMarketServiceFactoryForTests((options) => {
|
|
||||||
hasInstalledProvider = typeof options.installedSkillNames === 'function'
|
try {
|
||||||
return {
|
const configDir = path.join(tmpDir, '.claude')
|
||||||
list: async (params) => {
|
const userSkillDir = path.join(configDir, 'skills', 'skill-vetter')
|
||||||
capturedParams = params
|
await fs.mkdir(userSkillDir, { recursive: true })
|
||||||
return {
|
await fs.writeFile(
|
||||||
items: [],
|
path.join(userSkillDir, 'SKILL.md'),
|
||||||
nextCursor: null,
|
[
|
||||||
source: 'skillhub',
|
'---',
|
||||||
sourceStatus: 'ok',
|
'name: Skill Vetter',
|
||||||
}
|
'description: Reviews skill packages before install.',
|
||||||
},
|
'---',
|
||||||
listSkills: async (params) => {
|
'',
|
||||||
capturedParams = params
|
'Review skills before installing them.',
|
||||||
return {
|
].join('\n'),
|
||||||
items: [],
|
'utf-8',
|
||||||
nextCursor: null,
|
)
|
||||||
source: 'skillhub',
|
process.env.CLAUDE_CONFIG_DIR = configDir
|
||||||
sourceStatus: 'ok',
|
|
||||||
}
|
setSkillMarketServiceFactoryForTests((options) => {
|
||||||
},
|
return {
|
||||||
|
list: async (params) => {
|
||||||
|
capturedParams = params
|
||||||
|
const installedSkillNames = await (
|
||||||
|
options.installedSkillNames as (() => Set<string> | Promise<Set<string>>) | undefined
|
||||||
|
)?.()
|
||||||
|
installedNamesFromProvider = [...(installedSkillNames ?? new Set<string>())]
|
||||||
|
return {
|
||||||
|
items: [],
|
||||||
|
nextCursor: null,
|
||||||
|
source: 'skillhub',
|
||||||
|
sourceStatus: 'ok',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
listSkills: async (params) => {
|
||||||
|
capturedParams = params
|
||||||
|
const installedSkillNames = await (
|
||||||
|
options.installedSkillNames as (() => Set<string> | Promise<Set<string>>) | undefined
|
||||||
|
)?.()
|
||||||
|
installedNamesFromProvider = [...(installedSkillNames ?? new Set<string>())]
|
||||||
|
return {
|
||||||
|
items: [],
|
||||||
|
nextCursor: null,
|
||||||
|
source: 'skillhub',
|
||||||
|
sourceStatus: 'ok',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const url = new URL('/api/skill-market?source=skillhub&sort=updated&q=vetter&cursor=abc&limit=12', 'http://localhost:3456')
|
||||||
|
const req = new Request(url, { method: 'GET' })
|
||||||
|
|
||||||
|
const res = await handleSkillMarketApi(req, url, ['api', 'skill-market'])
|
||||||
|
|
||||||
|
expect(res.status).toBe(200)
|
||||||
|
expect(installedNamesFromProvider).toContain('skill-vetter')
|
||||||
|
expect(capturedParams).toEqual({
|
||||||
|
source: 'skillhub',
|
||||||
|
sort: 'updated',
|
||||||
|
query: 'vetter',
|
||||||
|
cursor: 'abc',
|
||||||
|
limit: 12,
|
||||||
|
})
|
||||||
|
} finally {
|
||||||
|
if (originalConfigDir === undefined) {
|
||||||
|
delete process.env.CLAUDE_CONFIG_DIR
|
||||||
|
} else {
|
||||||
|
process.env.CLAUDE_CONFIG_DIR = originalConfigDir
|
||||||
}
|
}
|
||||||
})
|
await fs.rm(tmpDir, { recursive: true, force: true })
|
||||||
const url = new URL('/api/skill-market?source=skillhub&sort=updated&q=vetter&cursor=abc&limit=12', 'http://localhost:3456')
|
}
|
||||||
const req = new Request(url, { method: 'GET' })
|
|
||||||
|
|
||||||
const res = await handleSkillMarketApi(req, url, ['api', 'skill-market'])
|
|
||||||
|
|
||||||
expect(res.status).toBe(200)
|
|
||||||
expect(hasInstalledProvider).toBe(true)
|
|
||||||
expect(capturedParams).toEqual({
|
|
||||||
source: 'skillhub',
|
|
||||||
sort: 'updated',
|
|
||||||
query: 'vetter',
|
|
||||||
cursor: 'abc',
|
|
||||||
limit: 12,
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -404,8 +404,8 @@ async function collectAllSkills(cwd?: string): Promise<SkillMeta[]> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function collectUserSkillNames(): Promise<Set<string>> {
|
export async function collectUserSkillNames(): Promise<Set<string>> {
|
||||||
const skills = await collectAllSkills(undefined)
|
const skills = await collectSkillsFromRoots([getUserSkillsDir()], 'user')
|
||||||
return new Set(skills.filter((skill) => skill.source === 'user').map((skill) => skill.name))
|
return new Set(skills.map((skill) => skill.name))
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function listSkillSlashCommands(cwd?: string): Promise<SkillSlashCommand[]> {
|
export async function listSkillSlashCommands(cwd?: string): Promise<SkillSlashCommand[]> {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user