@sveltejs/opencode 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +50 -13
- package/config.ts +75 -20
- package/index.ts +39 -6
- package/package.json +1 -1
- package/skills/svelte-core-bestpractices/SKILL.md +1 -1
package/README.md
CHANGED
|
@@ -36,39 +36,76 @@ The plugin injects instructions that teach the agent how to effectively use the
|
|
|
36
36
|
|
|
37
37
|
## Configuration
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
Create `svelte.json` to customize how the plugin configures MCP, the Svelte subagent, instructions, and skills.
|
|
40
40
|
|
|
41
41
|
```json
|
|
42
42
|
{
|
|
43
|
-
"$schema": "https://
|
|
43
|
+
"$schema": "https://svelte.dev/opencode/schema.json",
|
|
44
44
|
"mcp": {
|
|
45
45
|
"type": "remote",
|
|
46
46
|
"enabled": true
|
|
47
47
|
},
|
|
48
48
|
"subagent": {
|
|
49
|
-
"enabled": true
|
|
49
|
+
"enabled": true,
|
|
50
|
+
"agents": {
|
|
51
|
+
"svelte-file-editor": {
|
|
52
|
+
"model": "anthropic/claude-sonnet-4-20250514",
|
|
53
|
+
"temperature": 0.7,
|
|
54
|
+
"top_p": 0.9,
|
|
55
|
+
"maxSteps": 20
|
|
56
|
+
}
|
|
57
|
+
}
|
|
50
58
|
},
|
|
51
59
|
"instructions": {
|
|
52
60
|
"enabled": true
|
|
61
|
+
},
|
|
62
|
+
"skills": {
|
|
63
|
+
"enabled": ["svelte-code-writer", "svelte-core-bestpractices"]
|
|
53
64
|
}
|
|
54
65
|
}
|
|
55
66
|
```
|
|
56
67
|
|
|
68
|
+
### Defaults
|
|
69
|
+
|
|
70
|
+
If omitted, the plugin uses these defaults:
|
|
71
|
+
|
|
72
|
+
- `mcp.type`: `"remote"`
|
|
73
|
+
- `mcp.enabled`: `true`
|
|
74
|
+
- `subagent.enabled`: `true`
|
|
75
|
+
- `subagent.agents`: `{}`
|
|
76
|
+
- `instructions.enabled`: `true`
|
|
77
|
+
- `skills.enabled`: `true`
|
|
78
|
+
|
|
57
79
|
### Configuration Options
|
|
58
80
|
|
|
59
|
-
| Option
|
|
60
|
-
|
|
|
61
|
-
| `mcp.type`
|
|
62
|
-
| `mcp.enabled`
|
|
63
|
-
| `subagent.enabled`
|
|
64
|
-
| `
|
|
81
|
+
| Option | Type | Default | Description |
|
|
82
|
+
| ------------------------------------------------ | --------------------- | ---------- | ---------------------------------------------------------------------------------------------- |
|
|
83
|
+
| `mcp.type` | `"remote" \| "local"` | `"remote"` | Use `https://mcp.svelte.dev/mcp` (`remote`) or run `@sveltejs/mcp` via `npx` (`local`). |
|
|
84
|
+
| `mcp.enabled` | `boolean` | `true` | Enable or disable the Svelte MCP server entry. |
|
|
85
|
+
| `subagent.enabled` | `boolean` | `true` | Enable or disable registration of the `svelte-file-editor` subagent. |
|
|
86
|
+
| `subagent.agents.svelte-file-editor.model` | `string` | main agent | Override the model used by the Svelte file editor subagent. |
|
|
87
|
+
| `subagent.agents.svelte-file-editor.temperature` | `number` | unset | Set temperature for the subagent. |
|
|
88
|
+
| `subagent.agents.svelte-file-editor.top_p` | `number` | unset | Set top-p sampling for the subagent. |
|
|
89
|
+
| `subagent.agents.svelte-file-editor.maxSteps` | `number` | unlimited | Limit the number of steps the subagent can execute. |
|
|
90
|
+
| `instructions.enabled` | `boolean` | `true` | Enable or disable automatic instruction-file injection. |
|
|
91
|
+
| `skills.enabled` | `boolean \| string[]` | `true` | Enable all skills (`true`), disable all skills (`false`), or enable only specific skill names. |
|
|
92
|
+
|
|
93
|
+
### Supported Skill Names
|
|
94
|
+
|
|
95
|
+
When using `skills.enabled` as an array, these built-in names are currently available:
|
|
96
|
+
|
|
97
|
+
- `svelte-code-writer`
|
|
98
|
+
- `svelte-core-bestpractices`
|
|
99
|
+
|
|
100
|
+
### Config File Locations and Precedence
|
|
65
101
|
|
|
66
|
-
|
|
102
|
+
The plugin reads from these files (lowest priority first, highest priority last):
|
|
67
103
|
|
|
68
|
-
|
|
104
|
+
- `~/.config/opencode/svelte.json`
|
|
105
|
+
- `$OPENCODE_CONFIG_DIR/svelte.json` (when `OPENCODE_CONFIG_DIR` is set)
|
|
106
|
+
- `.opencode/svelte.json` in the current project
|
|
69
107
|
|
|
70
|
-
|
|
71
|
-
- `$OPENCODE_CONFIG_DIR/svelte.json` (if `OPENCODE_CONFIG_DIR` is set, takes priority)
|
|
108
|
+
If the same key is defined in multiple files, the later location overrides earlier ones.
|
|
72
109
|
|
|
73
110
|
## License
|
|
74
111
|
|
package/config.ts
CHANGED
|
@@ -4,6 +4,28 @@ import { homedir } from 'os';
|
|
|
4
4
|
import { join } from 'path';
|
|
5
5
|
import * as v from 'valibot';
|
|
6
6
|
|
|
7
|
+
// Schema for individual agent configuration
|
|
8
|
+
const agent_config_schema = v.object({
|
|
9
|
+
model: v.pipe(
|
|
10
|
+
v.optional(v.string()),
|
|
11
|
+
v.description('Model identifier for the agent (e.g., "anthropic/claude-sonnet-4-20250514")'),
|
|
12
|
+
),
|
|
13
|
+
temperature: v.pipe(
|
|
14
|
+
v.optional(v.number()),
|
|
15
|
+
v.description('Temperature setting for the agent (e.g., 0.7)'),
|
|
16
|
+
),
|
|
17
|
+
top_p: v.pipe(
|
|
18
|
+
v.optional(v.number()),
|
|
19
|
+
v.description(
|
|
20
|
+
'Control response diversity with the top_p option. Alternative to temperature for controlling randomness.',
|
|
21
|
+
),
|
|
22
|
+
),
|
|
23
|
+
maxSteps: v.pipe(
|
|
24
|
+
v.optional(v.number()),
|
|
25
|
+
v.description('Maximum number of steps the agent can take (e.g., 10)'),
|
|
26
|
+
),
|
|
27
|
+
});
|
|
28
|
+
|
|
7
29
|
const default_config = {
|
|
8
30
|
mcp: {
|
|
9
31
|
type: 'remote' as 'remote' | 'local',
|
|
@@ -11,36 +33,61 @@ const default_config = {
|
|
|
11
33
|
},
|
|
12
34
|
subagent: {
|
|
13
35
|
enabled: true,
|
|
36
|
+
agents: {} as Record<string, v.InferInput<typeof agent_config_schema>>,
|
|
14
37
|
},
|
|
15
38
|
instructions: {
|
|
16
39
|
enabled: true,
|
|
17
40
|
},
|
|
18
41
|
skills: {
|
|
19
|
-
enabled: true,
|
|
42
|
+
enabled: true as boolean | string[],
|
|
20
43
|
},
|
|
21
44
|
};
|
|
22
45
|
|
|
23
46
|
export const config_schema = v.object({
|
|
24
|
-
mcp: v.
|
|
25
|
-
v.
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
47
|
+
mcp: v.pipe(
|
|
48
|
+
v.optional(
|
|
49
|
+
v.object({
|
|
50
|
+
type: v.optional(v.picklist(['remote', 'local'])),
|
|
51
|
+
enabled: v.optional(v.boolean()),
|
|
52
|
+
}),
|
|
53
|
+
),
|
|
54
|
+
v.description(
|
|
55
|
+
"Configuration for the MCP. You can chose if it should be enabled or not and the transport to use 'remote' (default) and 'local'.",
|
|
56
|
+
),
|
|
29
57
|
),
|
|
30
|
-
subagent: v.
|
|
31
|
-
v.
|
|
32
|
-
|
|
33
|
-
|
|
58
|
+
subagent: v.pipe(
|
|
59
|
+
v.optional(
|
|
60
|
+
v.object({
|
|
61
|
+
enabled: v.optional(v.boolean()),
|
|
62
|
+
agents: v.optional(v.record(v.string(), agent_config_schema)),
|
|
63
|
+
}),
|
|
64
|
+
),
|
|
65
|
+
v.description('Configuration for the subagent. You can choose if it should be enabled or not.'),
|
|
34
66
|
),
|
|
35
|
-
instructions: v.
|
|
36
|
-
v.
|
|
37
|
-
|
|
38
|
-
|
|
67
|
+
instructions: v.pipe(
|
|
68
|
+
v.optional(
|
|
69
|
+
v.object({
|
|
70
|
+
enabled: v.optional(v.boolean()),
|
|
71
|
+
}),
|
|
72
|
+
),
|
|
73
|
+
v.description(
|
|
74
|
+
'Configuration for the automatic AGENTS.md injection. You can choose if it should be enabled or not.',
|
|
75
|
+
),
|
|
39
76
|
),
|
|
40
|
-
skills: v.
|
|
41
|
-
v.
|
|
42
|
-
|
|
43
|
-
|
|
77
|
+
skills: v.pipe(
|
|
78
|
+
v.optional(
|
|
79
|
+
v.object({
|
|
80
|
+
enabled: v.pipe(
|
|
81
|
+
v.optional(v.union([v.boolean(), v.array(v.string())])),
|
|
82
|
+
v.description(
|
|
83
|
+
'It can be either a boolean or an array containing the skills that you want to enable',
|
|
84
|
+
),
|
|
85
|
+
),
|
|
86
|
+
}),
|
|
87
|
+
),
|
|
88
|
+
v.description(
|
|
89
|
+
'Configuration for the skills. You can choose if it they should be enabled or not, or specify an array of skill names to enable only specific skills.',
|
|
90
|
+
),
|
|
44
91
|
),
|
|
45
92
|
});
|
|
46
93
|
|
|
@@ -112,8 +159,12 @@ function merge_with_defaults(user_config: Partial<McpConfig>): McpConfig {
|
|
|
112
159
|
...user_config.mcp,
|
|
113
160
|
},
|
|
114
161
|
subagent: {
|
|
115
|
-
|
|
162
|
+
enabled: default_config.subagent.enabled,
|
|
116
163
|
...user_config.subagent,
|
|
164
|
+
agents: {
|
|
165
|
+
...default_config.subagent.agents,
|
|
166
|
+
...user_config.subagent?.agents,
|
|
167
|
+
},
|
|
117
168
|
},
|
|
118
169
|
instructions: {
|
|
119
170
|
...default_config.instructions,
|
|
@@ -151,7 +202,11 @@ export function get_mcp_config(ctx: PluginInput) {
|
|
|
151
202
|
if (parsed.success) {
|
|
152
203
|
merged = {
|
|
153
204
|
mcp: { ...merged.mcp, ...parsed.output.mcp },
|
|
154
|
-
subagent: {
|
|
205
|
+
subagent: {
|
|
206
|
+
...merged.subagent,
|
|
207
|
+
...parsed.output.subagent,
|
|
208
|
+
agents: { ...merged.subagent?.agents, ...parsed.output.subagent?.agents },
|
|
209
|
+
},
|
|
155
210
|
instructions: { ...merged.instructions, ...parsed.output.instructions },
|
|
156
211
|
skills: { ...merged.skills, ...parsed.output.skills },
|
|
157
212
|
};
|
package/index.ts
CHANGED
|
@@ -39,34 +39,46 @@ export const svelte_plugin: Plugin = async (ctx) => {
|
|
|
39
39
|
input.instructions.push(...instructions_paths.map((file) => join(instructions_dir, file)));
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
const skills_enabled = mcp_config.skills?.enabled;
|
|
43
|
+
if (skills_enabled !== false) {
|
|
43
44
|
const skills_dir = join(current_dir, 'skills');
|
|
44
|
-
|
|
45
|
-
|
|
45
|
+
if (Array.isArray(skills_enabled)) {
|
|
46
|
+
// only add specific skill directories by name
|
|
47
|
+
for (const skill_name of skills_enabled) {
|
|
48
|
+
const skill_path = join(skills_dir, skill_name);
|
|
49
|
+
// @ts-expect-error -- skills is a new opencode feature
|
|
50
|
+
input.skills.paths.push(skill_path);
|
|
51
|
+
}
|
|
52
|
+
} else {
|
|
53
|
+
// @ts-expect-error -- skills is a new opencode feature
|
|
54
|
+
input.skills.paths.push(skills_dir);
|
|
55
|
+
}
|
|
46
56
|
}
|
|
47
57
|
|
|
48
58
|
// if the user doesn't have the MCP server already we add one based on config
|
|
49
|
-
if (!input.mcp[svelte_mcp_name]
|
|
59
|
+
if (!input.mcp[svelte_mcp_name]) {
|
|
50
60
|
if (mcp_config.mcp?.type === 'remote') {
|
|
51
61
|
input.mcp[svelte_mcp_name] = {
|
|
52
62
|
type: 'remote',
|
|
53
63
|
url: 'https://mcp.svelte.dev/mcp',
|
|
64
|
+
enabled: mcp_config.mcp?.enabled ?? true,
|
|
54
65
|
};
|
|
55
66
|
} else {
|
|
56
67
|
input.mcp[svelte_mcp_name] = {
|
|
57
68
|
type: 'local',
|
|
58
69
|
command: ['npx', '-y', '@sveltejs/mcp'],
|
|
70
|
+
enabled: mcp_config.mcp?.enabled ?? true,
|
|
59
71
|
};
|
|
60
72
|
}
|
|
61
73
|
}
|
|
62
74
|
if (mcp_config.subagent?.enabled !== false) {
|
|
63
75
|
// we add the editor subagent that will be used when editing Svelte files to prevent wasting context on the main agent
|
|
64
|
-
input.agent[
|
|
76
|
+
const default_config: (typeof input.agent)[string] = {
|
|
65
77
|
color: '#ff3e00',
|
|
66
78
|
mode: 'subagent',
|
|
67
79
|
prompt: `You are a Svelte 5 expert responsible for writing, editing, and validating Svelte components and modules. You have access to the Svelte MCP server which provides documentation and code analysis tools. Always use the tools from the svelte MCP server to fetch documentation with \`get_documentation\` and validating the code with \`svelte_autofixer\`. If the autofixer returns any issue or suggestions try to solve them.
|
|
68
80
|
|
|
69
|
-
If the MCP tools are not available you can use the \`svelte-code-
|
|
81
|
+
If the MCP tools are not available you can use the \`svelte-code-writer\` skill to learn how to use the \`@sveltejs/mcp\` cli to access the same tools.
|
|
70
82
|
|
|
71
83
|
If the skill is not available you can run \`npx @sveltejs/mcp@latest -y --help\` to learn how to use it.
|
|
72
84
|
|
|
@@ -138,6 +150,27 @@ After completing your work, provide:
|
|
|
138
150
|
[`${svelte_mcp_name}_*`]: true,
|
|
139
151
|
},
|
|
140
152
|
};
|
|
153
|
+
|
|
154
|
+
// Get per-agent config from svelte.json (if any)
|
|
155
|
+
const svelte_file_editor_config = mcp_config.subagent?.agents?.['svelte-file-editor'];
|
|
156
|
+
|
|
157
|
+
// Configure agent from svelte.json only
|
|
158
|
+
// Priority: svelte.json agent config > defaults
|
|
159
|
+
input.agent['svelte-file-editor'] = {
|
|
160
|
+
...default_config,
|
|
161
|
+
...(svelte_file_editor_config?.model !== undefined && {
|
|
162
|
+
model: svelte_file_editor_config.model,
|
|
163
|
+
}),
|
|
164
|
+
...(svelte_file_editor_config?.temperature !== undefined && {
|
|
165
|
+
temperature: svelte_file_editor_config.temperature,
|
|
166
|
+
}),
|
|
167
|
+
...(svelte_file_editor_config?.maxSteps !== undefined && {
|
|
168
|
+
maxSteps: svelte_file_editor_config.maxSteps,
|
|
169
|
+
}),
|
|
170
|
+
...(svelte_file_editor_config?.top_p !== undefined && {
|
|
171
|
+
top_p: svelte_file_editor_config.top_p,
|
|
172
|
+
}),
|
|
173
|
+
};
|
|
141
174
|
}
|
|
142
175
|
},
|
|
143
176
|
};
|
package/package.json
CHANGED
|
@@ -134,7 +134,7 @@ The CSS in a component's `<style>` is scoped to that component. If a parent comp
|
|
|
134
134
|
</style>
|
|
135
135
|
```
|
|
136
136
|
|
|
137
|
-
If this impossible (for example, the child component comes from a library) you can use `:global` to override styles:
|
|
137
|
+
If this is impossible (for example, the child component comes from a library) you can use `:global` to override styles:
|
|
138
138
|
|
|
139
139
|
```svelte
|
|
140
140
|
<div>
|