070959e133
landing-page-staging / Deploy landing page to staging (push) Has been skipped
landing-page-ci / Validate landing page (push) Failing after 4s
visual-baseline / Capture visual baselines (push) Has been cancelled
bake-plugin-previews / Bake plugin previews (push) Has been cancelled
87 lines
3.1 KiB
TypeScript
87 lines
3.1 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import { adaptAgentSkill } from '../src/adapters/agent-skill';
|
|
import { parseManifestObject } from '../src/parsers/manifest';
|
|
|
|
const SAMPLE_SKILL = `---
|
|
name: blog-post
|
|
description: |
|
|
A long-form article. Use when the brief asks for "blog".
|
|
od:
|
|
mode: prototype
|
|
platform: desktop
|
|
scenario: marketing
|
|
preview:
|
|
type: html
|
|
entry: index.html
|
|
design_system:
|
|
requires: true
|
|
craft:
|
|
requires: [typography, typography-hierarchy]
|
|
inputs:
|
|
- name: tone
|
|
type: enum
|
|
values: [editorial, casual]
|
|
---
|
|
|
|
# Blog Post Skill
|
|
Produce one long-form article page.
|
|
`;
|
|
|
|
describe('adaptAgentSkill', () => {
|
|
it('synthesizes a v1-valid manifest from od: frontmatter', () => {
|
|
const result = adaptAgentSkill(SAMPLE_SKILL, { folderId: 'blog-post' });
|
|
expect(result.manifest.name).toBe('blog-post');
|
|
expect(result.manifest.title).toBe('Blog Post');
|
|
expect(result.manifest.compat?.agentSkills?.[0]?.path).toBe('./SKILL.md');
|
|
expect(result.manifest.od?.mode).toBe('prototype');
|
|
expect(result.manifest.od?.preview?.entry).toBe('index.html');
|
|
expect(result.manifest.od?.context?.craft).toEqual(['typography', 'typography-hierarchy']);
|
|
expect(result.manifest.od?.inputs?.[0]?.type).toBe('select');
|
|
expect(result.manifest.od?.inputs?.[0]?.options).toEqual(['editorial', 'casual']);
|
|
// Spec invariant I1: synthesized output must validate against the v1 schema.
|
|
const reparsed = parseManifestObject(result.manifest);
|
|
expect(reparsed.ok).toBe(true);
|
|
});
|
|
|
|
it('falls back to folderId when frontmatter has no name', () => {
|
|
const result = adaptAgentSkill('---\n---\n# heading', { folderId: 'no-name' });
|
|
expect(result.manifest.name).toBe('no-name');
|
|
});
|
|
|
|
it('passes display copy and tags from SKILL frontmatter into the manifest', () => {
|
|
const result = adaptAgentSkill(
|
|
`---
|
|
name: board-pre-read
|
|
en_name: Board Pre-read Decision Memo
|
|
zh_name: 董事会决策预读
|
|
description: Legacy design note.
|
|
en_description: Turn metrics, risks, and owners into a board-ready decision deck.
|
|
zh_description: 把经营指标、风险和负责人收敛成董事会可直接决策的预读材料。
|
|
tags: [board-pre-read, corporate-strategy, decision-deck]
|
|
od:
|
|
mode: deck
|
|
---
|
|
# Board Pre-read
|
|
`,
|
|
{ folderId: 'board-pre-read' },
|
|
);
|
|
|
|
expect(result.manifest.title).toBe('Board Pre-read Decision Memo');
|
|
expect(result.manifest.title_i18n).toEqual({
|
|
en: 'Board Pre-read Decision Memo',
|
|
'zh-CN': '董事会决策预读',
|
|
});
|
|
expect(result.manifest.description).toBe('Turn metrics, risks, and owners into a board-ready decision deck.');
|
|
expect(result.manifest.description_i18n).toEqual({
|
|
en: 'Turn metrics, risks, and owners into a board-ready decision deck.',
|
|
'zh-CN': '把经营指标、风险和负责人收敛成董事会可直接决策的预读材料。',
|
|
});
|
|
expect(result.manifest.tags).toEqual([
|
|
'board-pre-read',
|
|
'corporate-strategy',
|
|
'decision-deck',
|
|
]);
|
|
expect(parseManifestObject(result.manifest).ok).toBe(true);
|
|
});
|
|
});
|