import type { Plugin } from '@opencode-ai/plugin';
import { tool } from '@opencode-ai/plugin';
import path from 'path';
interface CommandFrontmatter {
description?: string;
agent?: string;
model?: string;
subtask?: boolean;
}
interface ParsedCommand {
name: string;
frontmatter: CommandFrontmatter;
template: string;
}
function parseFrontmatter(content: string): { frontmatter: CommandFrontmatter; body: string } {
const frontmatterRegex = /^---\n([\s\S]*?)\n---\n([\s\S]*)$/;
const match = content.match(frontmatterRegex);
if (!match) {
return { frontmatter: {}, body: content.trim() };
}
const [, yamlContent, body] = match;
const frontmatter: CommandFrontmatter = {};
for (const line of yamlContent.split('\n')) {
const colonIndex = line.indexOf(':');
if (colonIndex === -1) continue;
const key = line.slice(0, colonIndex).trim();
const value = line.slice(colonIndex + 1).trim();
if (key === 'description') frontmatter.description = value;
if (key === 'agent') frontmatter.agent = value;
if (key === 'model') frontmatter.model = value;
if (key === 'subtask') frontmatter.subtask = value === 'true';
}
return { frontmatter, body: body.trim() };
}
async function loadCommands(): Promise<ParsedCommand[]> {
const commands: ParsedCommand[] = [];
const commandDir = path.join(import.meta.dir, 'command');
const glob = new Bun.Glob('**/*.md');
for await (const file of glob.scan({ cwd: commandDir, absolute: true })) {
const content = await Bun.file(file).text();
const { frontmatter, body } = parseFrontmatter(content);
const relativePath = path.relative(commandDir, file);
const name = relativePath.replace(/\.md$/, '').replace(/\//g, '-');
commands.push({
name,
frontmatter,
template: body,
});
}
return commands;
}
export const AnarchyPlugin: Plugin = async () => {
const commands = await loadCommands();
const anarchyTool = tool({
description: 'Returns a short anarchy manifesto line.',
args: {},
async execute() {
return 'No gods, no masters.';
},
});
return {
tool: {
anarchy_manifest: anarchyTool,
},
async config(config) {
config.command = config.command ?? {};
for (const cmd of commands) {
config.command[cmd.name] = {
template: cmd.template,
description: cmd.frontmatter.description,
agent: cmd.frontmatter.agent,
model: cmd.frontmatter.model,
subtask: cmd.frontmatter.subtask,
};
}
},
};
};