mirror of
https://github.com/sveltejs/ai-tools.git
synced 2026-07-03 11:12:28 +08:00
Co-authored-by: jyc.dev <jycouet@gmail.com> Co-authored-by: Tee Ming <chewteeming01@gmail.com> Co-authored-by: Rich Harris <rich.harris@vercel.com>
114 lines
3.3 KiB
TypeScript
114 lines
3.3 KiB
TypeScript
import fs from 'node:fs/promises';
|
|
import path from 'node:path';
|
|
|
|
const OPENCODE_PKG_DIR = './packages/opencode';
|
|
const TOOLS_DIR = './tools';
|
|
const DOCS_AGENTS_DIR = './documentation/docs/20-instructions/.generated';
|
|
|
|
/**
|
|
* Sync skills from tools/ to opencode package (direct copy)
|
|
*/
|
|
async function sync_skills() {
|
|
const source = path.join(TOOLS_DIR, 'skills');
|
|
const dest = path.join(OPENCODE_PKG_DIR, 'skills');
|
|
|
|
await fs.rm(dest, { recursive: true, force: true });
|
|
await fs.cp(source, dest, { recursive: true });
|
|
|
|
console.log('Synced skills to opencode package');
|
|
}
|
|
|
|
/**
|
|
* Sync AGENTS.md from tools/ to opencode package and documentation site
|
|
*/
|
|
async function sync_agents_md() {
|
|
const source = path.join(TOOLS_DIR, 'instructions', 'AGENTS.md');
|
|
const opencode_dest = path.join(OPENCODE_PKG_DIR, 'instructions', 'opencode-agents.md');
|
|
const docs_dest = path.join(DOCS_AGENTS_DIR, 'agents.md');
|
|
|
|
await fs.mkdir(path.dirname(opencode_dest), { recursive: true });
|
|
await fs.mkdir(DOCS_AGENTS_DIR, { recursive: true });
|
|
|
|
const content = await fs.readFile(source, 'utf-8');
|
|
|
|
await fs.writeFile(opencode_dest, content);
|
|
await fs.writeFile(docs_dest, content);
|
|
|
|
console.log('Synced AGENTS.md to opencode package and documentation');
|
|
}
|
|
|
|
interface AgentData {
|
|
name: string;
|
|
description: string;
|
|
prompt: string;
|
|
}
|
|
|
|
/**
|
|
* Parse a markdown agent file with frontmatter (name, description) and body (prompt)
|
|
*/
|
|
function parse_agent_md(content: string, file_path: string): AgentData | null {
|
|
const frontmatter_match = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
|
|
if (!frontmatter_match) {
|
|
console.warn(`Skipping ${file_path}: no frontmatter found`);
|
|
return null;
|
|
}
|
|
|
|
const frontmatter = frontmatter_match[1] ?? '';
|
|
const body = (frontmatter_match[2] ?? '').trim();
|
|
|
|
const name = frontmatter.match(/^name:\s*(.+)$/m)?.[1]?.trim();
|
|
const description = frontmatter.match(/^description:\s*(.+)$/m)?.[1]?.trim();
|
|
|
|
if (!name || !description) {
|
|
console.warn(`Skipping ${file_path}: missing name or description in frontmatter`);
|
|
return null;
|
|
}
|
|
|
|
return { name, description, prompt: body };
|
|
}
|
|
|
|
/**
|
|
* Generate agents.ts module from tools/agents/*.md files
|
|
*/
|
|
async function sync_agents() {
|
|
const agents_dir = path.join(TOOLS_DIR, 'agents');
|
|
const entries = await fs.readdir(agents_dir, { withFileTypes: true });
|
|
const md_files = entries.filter((e) => e.isFile() && e.name.endsWith('.md'));
|
|
|
|
const agents: AgentData[] = [];
|
|
|
|
for (const file of md_files) {
|
|
const file_path = path.join(agents_dir, file.name);
|
|
const content = await fs.readFile(file_path, 'utf-8');
|
|
const agent = parse_agent_md(content, file_path);
|
|
if (agent) {
|
|
agents.push(agent);
|
|
}
|
|
}
|
|
|
|
const output = [
|
|
'// This file is auto-generated by scripts/sync-opencode-plugin.ts',
|
|
'// Do not edit manually — edit the markdown files in tools/agents/ instead.',
|
|
'',
|
|
`export const agents = ${JSON.stringify(
|
|
Object.fromEntries(
|
|
agents.map((a) => [a.name, { description: a.description, prompt: a.prompt }]),
|
|
),
|
|
null,
|
|
'\t',
|
|
)} as const;`,
|
|
'',
|
|
].join('\n');
|
|
|
|
const dest = path.join(OPENCODE_PKG_DIR, 'agents.ts');
|
|
await fs.writeFile(dest, output);
|
|
|
|
console.log(`Generated agents.ts with ${agents.length} agent(s)`);
|
|
}
|
|
|
|
await sync_skills();
|
|
await sync_agents_md();
|
|
await sync_agents();
|
|
|
|
console.log('OpenCode plugin sync complete');
|