mirror of
https://github.com/sveltejs/ai-tools.git
synced 2026-09-14 13:50:38 +08:00
145 lines
4.5 KiB
JavaScript
145 lines
4.5 KiB
JavaScript
import { readdir } from 'node:fs/promises';
|
|
import { dirname, join } from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
import { agents } from './agents.js';
|
|
import { get_mcp_config } from './config.js';
|
|
import { setup_updates } from './update.js';
|
|
|
|
/** @typedef {import('@opencode-ai/plugin-v1').Plugin} Plugin */
|
|
|
|
const current_dir = dirname(fileURLToPath(import.meta.url));
|
|
|
|
/**
|
|
* @param {Parameters<Plugin>[0]} ctx
|
|
* @returns {ReturnType<Plugin>}
|
|
*/
|
|
export async function v1_plugin(ctx) {
|
|
const mcp_config = get_mcp_config({
|
|
on_warning(warning) {
|
|
setTimeout(() => {
|
|
ctx.client.tui.showToast({
|
|
body: {
|
|
...warning,
|
|
variant: 'warning',
|
|
duration: 7000,
|
|
},
|
|
});
|
|
}, 7000);
|
|
},
|
|
});
|
|
const dispose = setup_updates(mcp_config.autoupdate === true, (update) => {
|
|
setTimeout(() => {
|
|
ctx.client.tui.showToast({
|
|
body: {
|
|
title: 'Svelte: new plugin version available',
|
|
message: update.message,
|
|
variant: 'warning',
|
|
duration: 7000,
|
|
},
|
|
});
|
|
}, 7000);
|
|
});
|
|
|
|
return {
|
|
dispose,
|
|
async config(input) {
|
|
input.agent ??= {};
|
|
input.mcp ??= {};
|
|
input.instructions ??= [];
|
|
// @ts-expect-error -- types are wrong in the opencode package...will fix there and remove this
|
|
input.skills ??= {};
|
|
// @ts-expect-error -- types are wrong in the opencode package...will fix there and remove this
|
|
input.skills.paths ??= [];
|
|
// by default we use svelte as the name for the svelte MCP server
|
|
let svelte_mcp_name = 'svelte';
|
|
// we loop over every mcp server to see if any of them is already the svelte MCP server
|
|
for (const name in input.mcp) {
|
|
const mcp = input.mcp[name];
|
|
if (
|
|
(mcp?.type === 'remote' && mcp.url.includes('https://mcp.svelte.dev/mcp')) ||
|
|
(mcp?.type === 'local' && mcp.command.some((cmd) => cmd.includes('@sveltejs/mcp')))
|
|
) {
|
|
// if we found the svelte MCP server, we store its name and break
|
|
svelte_mcp_name = name;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (mcp_config.instructions?.enabled !== false) {
|
|
const instructions_dir = join(current_dir, 'instructions');
|
|
const instructions_paths = await readdir(instructions_dir);
|
|
input.instructions.push(...instructions_paths.map((file) => join(instructions_dir, file)));
|
|
}
|
|
|
|
const skills_enabled = mcp_config.skills?.enabled;
|
|
if (skills_enabled !== false) {
|
|
const skills_dir = join(current_dir, 'skills');
|
|
if (Array.isArray(skills_enabled)) {
|
|
// only add specific skill directories by name
|
|
for (const skill_name of skills_enabled) {
|
|
const skill_path = join(skills_dir, skill_name);
|
|
// @ts-expect-error -- skills is a new opencode feature
|
|
input.skills.paths.push(skill_path);
|
|
}
|
|
} else {
|
|
// @ts-expect-error -- skills is a new opencode feature
|
|
input.skills.paths.push(skills_dir);
|
|
}
|
|
}
|
|
|
|
// if the user doesn't have the MCP server already we add one based on config
|
|
if (!input.mcp[svelte_mcp_name]) {
|
|
if (mcp_config.mcp?.type === 'remote') {
|
|
input.mcp[svelte_mcp_name] = {
|
|
type: 'remote',
|
|
url: 'https://mcp.svelte.dev/mcp',
|
|
enabled: mcp_config.mcp?.enabled ?? true,
|
|
};
|
|
} else {
|
|
input.mcp[svelte_mcp_name] = {
|
|
type: 'local',
|
|
command: ['npx', '-y', '@sveltejs/mcp'],
|
|
enabled: mcp_config.mcp?.enabled ?? true,
|
|
};
|
|
}
|
|
}
|
|
if (mcp_config.subagent?.enabled !== false) {
|
|
for (const [agent_name, agent_data] of Object.entries(agents)) {
|
|
// we add the editor subagent that will be used when editing Svelte files to prevent wasting context on the main agent
|
|
/** @type {(typeof input.agent)[string]} */
|
|
const default_config = {
|
|
color: '#ff3e00',
|
|
mode: 'subagent',
|
|
prompt: agent_data.prompt,
|
|
description: agent_data.description,
|
|
permission: {
|
|
[`${svelte_mcp_name}_*`]: 'allow',
|
|
},
|
|
};
|
|
|
|
// Get per-agent config from svelte.json (if any)
|
|
const agent_config = mcp_config.subagent?.agents?.[agent_name];
|
|
|
|
// Configure agent from svelte.json only
|
|
// Priority: svelte.json agent config > defaults
|
|
input.agent[agent_name] = {
|
|
...default_config,
|
|
...(agent_config?.model !== undefined && {
|
|
model: agent_config.model,
|
|
}),
|
|
...(agent_config?.temperature !== undefined && {
|
|
temperature: agent_config.temperature,
|
|
}),
|
|
...(agent_config?.maxSteps !== undefined && {
|
|
maxSteps: agent_config.maxSteps,
|
|
}),
|
|
...(agent_config?.top_p !== undefined && {
|
|
top_p: agent_config.top_p,
|
|
}),
|
|
};
|
|
}
|
|
}
|
|
},
|
|
};
|
|
}
|