Ctrl K
ComunidadGuías…

scripts/__tests__/community-skills.test.ts

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
import { mkdtemp, mkdir, readFile, rm, writeFile, symlink } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { afterEach, describe, expect, it } from 'vitest'
import yaml from 'js-yaml'
import { discoverAtoms } from '../lib/atom-discovery'
import { buildMigrationSql } from '../generate-skill-bodies'
import { publicSkillFiles, stampMit, syncPublicSkills } from '../sync-public-skills'

const directories: string[] = []
async function directory() { const dir = await mkdtemp(join(tmpdir(), 'accounted-skills-test-')); directories.push(dir); return dir }
afterEach(async () => { for (const dir of directories.splice(0)) await rm(dir, { recursive: true, force: true }) })

async function fixture(root: string, slug: string, body: string, extra: Record<string, unknown> = {}) {
  await mkdir(join(root, '.claude/skills'), { recursive: true })
  await mkdir(join(root, 'registry/entries'), { recursive: true })
  await mkdir(join(root, `registry/skills/${slug}`), { recursive: true })
  await writeFile(join(root, `registry/entries/${slug}.mdx`), `---\n${yaml.dump({ slug, title: slug, description: 'Reviewed workflow', kind: 'skill', status: 'live', mcp_exposed: true, reviewedAt: '2026-09-17', ...extra })}---\n\nDescription.\n`)
  await writeFile(join(root, `registry/skills/${slug}/SKILL.md`), body)
}

describe('reviewed community generation', () => {
  it('seeds developer and firm submissions through the same generator', async () => {
    const root = await directory()
    await fixture(root, 'developer-workflow', 'Review the selected transactions.')
    await fixture(root, 'firm-workflow', 'Use the approved company mappings.', { submissionHash: 'reviewed-frozen-hash', author: 'firm-author' })
    const atoms = await discoverAtoms(root)
    expect(atoms.map((atom) => atom.id)).toEqual(['community/developer-workflow', 'community/firm-workflow'])
    expect(atoms.every((atom) => atom.mcp_exposed && atom.reviewed_at === '2026-09-17')).toBe(true)
    const sql = buildMigrationSql(atoms, Object.fromEntries(atoms.map((atom) => [atom.id, 1])))
    expect(sql).toContain('Review the selected transactions.')
    expect(sql).toContain('Use the approved company mappings.')
  })
  it('requires reviewer metadata before MCP exposure', async () => {
    const root = await directory()
    await fixture(root, 'unreviewed', 'Body', { reviewedAt: undefined })
    await expect(discoverAtoms(root)).rejects.toThrow('reviewedAt')
  })
  it('rejects raw tags in the loadable body, not only the registry description', async () => {
    const root = await directory()
    await fixture(root, 'unsafe', '<script>alert(1)</script>')
    await expect(discoverAtoms(root)).rejects.toThrow('plain Markdown')
  })
  it('does not expose archived entries', async () => {
    const root = await directory()
    await fixture(root, 'archived', 'Body', { status: 'archived' })
    expect((await discoverAtoms(root))[0].mcp_exposed).toBe(false)
  })
})

describe('public mirror', () => {
  it('stamps MIT without breaking frontmatter', () => {
    const body = '---\nname: swedish-test\n---\n# Test\n'
    expect(stampMit(body)).toMatch(/^---\nname: swedish-test\n---\n<!-- SPDX/)
  })
  it('mirrors canonical skills and references without drift and detects edits', async () => {
    const target = await directory()
    const files = await publicSkillFiles(process.cwd())
    expect(files.has('.claude/skills/swedish-vat/references/vat-compliance-reference.md')).toBe(true)
    expect([...files.keys()].some((file) => file.includes('industry/'))).toBe(false)
    await syncPublicSkills(process.cwd(), target)
    expect(await syncPublicSkills(process.cwd(), target, true)).toEqual([])
    for (const [file, body] of files) expect(await readFile(join(target, file), 'utf8')).toBe(body)
    await writeFile(join(target, '.claude/skills/swedish-vat/SKILL.md'), 'Drift')
    expect(await syncPublicSkills(process.cwd(), target, true)).toEqual(['.claude/skills/swedish-vat/SKILL.md'])
    expect(await readFile(join(target, '.claude/skills/swedish-vat/SKILL.md'), 'utf8')).toBe('Drift')
  })
  it('refuses the source checkout as a destination', async () => {
    await expect(syncPublicSkills(process.cwd(), process.cwd())).rejects.toThrow('separate')
  })
  it('refuses a destination symlink that points into the source checkout', async () => {
    const target = await directory()
    await symlink(process.cwd(), join(target, 'source-link'))
    await expect(syncPublicSkills(process.cwd(), join(target, 'source-link'))).rejects.toThrow('separate')
  })
})