Migrate to unified skills architecture, add Copilot & Antigravity (v2.0.0)

All commands are now skills with user-invokable: true. Source lives in
source/skills/{name}/SKILL.md. Added VS Code Copilot (.agents/skills/)
and Google Antigravity (.agent/skills/) transformers. All 6 providers
output to skills directories only — no more commands/prompts dirs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Paul Bakaus
2026-03-04 10:10:41 -08:00
co-authored by Claude Opus 4.6
parent a94e237359
commit 87106b5271
65 changed files with 418 additions and 7055 deletions
+15 -75
View File
@@ -2,104 +2,44 @@ import path from 'path';
import { cleanDir, ensureDir, writeFile, generateYamlFrontmatter, replacePlaceholders } from '../utils.js';
/**
* Generate markdown from structured patterns/antipatterns data
*/
function generatePatternsMarkdown(patterns) {
if (!patterns || (!patterns.patterns?.length && !patterns.antipatterns?.length)) {
return '';
}
let md = `## Design Patterns Reference
This reference defines what TO do and what NOT to do when creating frontend interfaces. These patterns fight against model bias—the tendency of LLMs to converge on the same predictable choices.
### What TO Do (Patterns)
Focus on intentional, distinctive design choices:
`;
for (const category of patterns.patterns || []) {
md += `\n**${category.name}**:\n`;
for (const item of category.items || []) {
md += `- ${item}\n`;
}
}
md += `
### What NOT to Do (Anti-Patterns)
These patterns create generic "AI slop" aesthetics:
`;
for (const category of patterns.antipatterns || []) {
md += `\n**${category.name}**:\n`;
for (const item of category.items || []) {
md += `- ${item}\n`;
}
}
md += `
These anti-patterns are baked into training data from countless generic templates. Without explicit guidance, AI reproduces them. This skill ensures your AI knows both what to do AND what to avoid.
`;
return md;
}
/**
* Claude Code Transformer (Full Featured)
* Claude Code Transformer (Skills Only)
*
* Keeps full YAML frontmatter with args support.
* Skills stored in subdirectories with SKILL.md filename.
* Supports reference files in skill subdirectories.
* All skills output to .claude/skills/{name}/SKILL.md
* User-invokable skills get args support in frontmatter.
*
* @param {Array} skills - All skills (including user-invokable ones)
* @param {string} distDir - Distribution output directory
* @param {Object} patterns - Design patterns data (unused, kept for interface consistency)
* @param {Object} options - Optional settings
* @param {string} options.prefix - Prefix to add to command names (e.g., 'i-')
* @param {string} options.prefix - Prefix to add to user-invokable skill names (e.g., 'i-')
* @param {string} options.outputSuffix - Suffix for output directory (e.g., '-prefixed')
*/
export function transformClaudeCode(commands, skills, distDir, patterns = null, options = {}) {
export function transformClaudeCode(skills, distDir, patterns = null, options = {}) {
const { prefix = '', outputSuffix = '' } = options;
const claudeDir = path.join(distDir, `claude-code${outputSuffix}`);
const commandsDir = path.join(claudeDir, '.claude/commands');
const skillsDir = path.join(claudeDir, '.claude/skills');
cleanDir(claudeDir);
ensureDir(commandsDir);
ensureDir(skillsDir);
// Commands: Keep frontmatter + body
for (const command of commands) {
const commandName = `${prefix}${command.name}`;
const frontmatter = generateYamlFrontmatter({
name: commandName,
description: command.description,
...(command.context && { context: command.context }),
...(command.args.length > 0 && { args: command.args })
});
const commandBody = replacePlaceholders(command.body, 'claude-code');
const content = `${frontmatter}\n\n${commandBody}`;
const outputPath = path.join(commandsDir, `${commandName}.md`);
writeFile(outputPath, content);
}
// Skills: Keep frontmatter + body in subdirectories
let refCount = 0;
for (const skill of skills) {
const skillDir = path.join(skillsDir, skill.name);
const skillName = skill.userInvokable ? `${prefix}${skill.name}` : skill.name;
const skillDir = path.join(skillsDir, skillName);
const frontmatterObj = {
name: skill.name,
name: skillName,
description: skill.description,
};
// Add optional fields if present
if (skill.userInvokable) frontmatterObj['user-invokable'] = true;
if (skill.args && skill.args.length > 0) frontmatterObj.args = skill.args;
if (skill.license) frontmatterObj.license = skill.license;
if (skill.compatibility) frontmatterObj.compatibility = skill.compatibility;
if (skill.metadata) frontmatterObj.metadata = skill.metadata;
if (skill.allowedTools) frontmatterObj['allowed-tools'] = skill.allowedTools;
const frontmatter = generateYamlFrontmatter(frontmatterObj);
const skillBody = replacePlaceholders(skill.body, 'claude-code');
const content = `${frontmatter}\n\n${skillBody}`;
const outputPath = path.join(skillDir, 'SKILL.md');
@@ -118,8 +58,8 @@ export function transformClaudeCode(commands, skills, distDir, patterns = null,
}
}
const userInvokableCount = skills.filter(s => s.userInvokable).length;
const refInfo = refCount > 0 ? ` (${refCount} reference files)` : '';
const prefixInfo = prefix ? ` [${prefix}prefixed]` : '';
console.log(`✓ Claude Code${prefixInfo}: ${commands.length} commands, ${skills.length} skills${refInfo}`);
console.log(`✓ Claude Code${prefixInfo}: ${skills.length} skills (${userInvokableCount} user-invokable)${refInfo}`);
}