mirror of
https://github.com/sveltejs/ai-tools.git
synced 2026-07-04 03:19:38 +08:00
Compare commits
17 Commits
@sveltejs/
...
@sveltejs/
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2ded13539a | ||
|
|
96c50acae2 | ||
|
|
4920088e5c | ||
|
|
8557f0af6f | ||
|
|
972d0f0bb2 | ||
|
|
7bf364a9d5 | ||
|
|
d06d758b81 | ||
|
|
e5ce7437c4 | ||
|
|
2f422ee190 | ||
|
|
14f087cd7a | ||
|
|
1ef5ddf605 | ||
|
|
0e55ee792d | ||
|
|
84ec24b6f6 | ||
|
|
710cebe539 | ||
|
|
b2a380c4ce | ||
|
|
eef0a9b4d9 | ||
|
|
260b36e8af |
2
.github/workflows/check.yml
vendored
2
.github/workflows/check.yml
vendored
@@ -16,7 +16,7 @@ jobs:
|
|||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@v4
|
uses: pnpm/action-setup@v5
|
||||||
with:
|
with:
|
||||||
version: 10.28.2
|
version: 10.28.2
|
||||||
|
|
||||||
|
|||||||
2
.github/workflows/lint.yml
vendored
2
.github/workflows/lint.yml
vendored
@@ -16,7 +16,7 @@ jobs:
|
|||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@v4
|
uses: pnpm/action-setup@v5
|
||||||
with:
|
with:
|
||||||
version: 10.28.2
|
version: 10.28.2
|
||||||
|
|
||||||
|
|||||||
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -64,7 +64,7 @@ jobs:
|
|||||||
|
|
||||||
publish-mcp:
|
publish-mcp:
|
||||||
needs: release
|
needs: release
|
||||||
if: contains(needs.release.outputs.publishedPackages, '"@sveltejs/ai-tools"')
|
if: contains(needs.release.outputs.publishedPackages, '"@sveltejs/mcp"')
|
||||||
uses: ./.github/workflows/publish-mcp.yml
|
uses: ./.github/workflows/publish-mcp.yml
|
||||||
secrets:
|
secrets:
|
||||||
MCP_KEY: ${{ secrets.MCP_KEY }}
|
MCP_KEY: ${{ secrets.MCP_KEY }}
|
||||||
|
|||||||
13
.github/workflows/sync-plugins.yml
vendored
13
.github/workflows/sync-plugins.yml
vendored
@@ -46,21 +46,12 @@ jobs:
|
|||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm install --frozen-lockfile --prefer-offline --ignore-scripts
|
run: pnpm install --frozen-lockfile --prefer-offline --ignore-scripts
|
||||||
|
|
||||||
- name: Sync Claude plugin
|
- name: Sync plugins
|
||||||
run: pnpm sync-claude-plugin
|
run: pnpm sync-plugins
|
||||||
|
|
||||||
- name: Sync Cursor plugin
|
|
||||||
run: pnpm sync-cursor-plugin
|
|
||||||
|
|
||||||
- name: Sync OpenCode plugin
|
|
||||||
run: pnpm sync-opencode-plugin && pnpm generate-opencode-jsonschema
|
|
||||||
|
|
||||||
- name: Generate skills documentation
|
- name: Generate skills documentation
|
||||||
run: pnpm generate-skill-docs
|
run: pnpm generate-skill-docs
|
||||||
|
|
||||||
- name: Bump plugin versions for changed plugins
|
|
||||||
run: pnpm bump-plugin-versions
|
|
||||||
|
|
||||||
- name: Check for changes
|
- name: Check for changes
|
||||||
id: git-check
|
id: git-check
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
@@ -16,7 +16,7 @@ jobs:
|
|||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@v4
|
uses: pnpm/action-setup@v5
|
||||||
with:
|
with:
|
||||||
version: 10.28.2
|
version: 10.28.2
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,12 @@
|
|||||||
"options": {
|
"options": {
|
||||||
"parser": "svelte"
|
"parser": "svelte"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": "**/references/*.md",
|
||||||
|
"options": {
|
||||||
|
"embeddedLanguageFormatting": "off"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,10 @@ To get the most out of the MCP server we recommend including the following promp
|
|||||||
|
|
||||||
> [!NOTE] This is already setup for you when using `npx sv add mcp`
|
> [!NOTE] This is already setup for you when using `npx sv add mcp`
|
||||||
|
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
|
````markdown
|
||||||
@include .generated/agents.md
|
@include .generated/agents.md
|
||||||
|
````
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
If your MCP client supports it, we also recommend using the [svelte-task](prompts#svelte-task) prompt to instruct the LLM on the best way to use the MCP server.
|
If your MCP client supports it, we also recommend using the [svelte-task](prompts#svelte-task) prompt to instruct the LLM on the best way to use the MCP server.
|
||||||
|
|||||||
@@ -5,10 +5,22 @@ This prompt should be used whenever you are asking the model to work on a Svelte
|
|||||||
<details>
|
<details>
|
||||||
<summary>Copy the prompt</summary>
|
<summary>Copy the prompt</summary>
|
||||||
|
|
||||||
```md
|
<!-- prettier-ignore-start -->
|
||||||
|
````markdown
|
||||||
You are a Svelte expert tasked to build components and utilities for Svelte developers. If you need documentation for anything related to Svelte you can invoke the tool `get-documentation` with one of the following paths. However: before invoking the `get-documentation` tool, try to answer the users query using your own knowledge and the `svelte-autofixer` tool. Be mindful of how many section you request, since it is token-intensive!
|
You are a Svelte expert tasked to build components and utilities for Svelte developers. If you need documentation for anything related to Svelte you can invoke the tool `get-documentation` with one of the following paths. However: before invoking the `get-documentation` tool, try to answer the users query using your own knowledge and the `svelte-autofixer` tool. Be mindful of how many section you request, since it is token-intensive!
|
||||||
<available-docs>
|
<available-docs>
|
||||||
|
|
||||||
|
- title: Overview, use_cases: use title and path to estimate use case, path: ai/overview
|
||||||
|
- title: Local setup, use_cases: use title and path to estimate use case, path: ai/local-setup
|
||||||
|
- title: Remote setup, use_cases: use title and path to estimate use case, path: ai/remote-setup
|
||||||
|
- title: Tools, use_cases: use title and path to estimate use case, path: ai/tools
|
||||||
|
- title: Resources, use_cases: use title and path to estimate use case, path: ai/resources
|
||||||
|
- title: Prompts, use_cases: use title and path to estimate use case, path: ai/prompts
|
||||||
|
- title: Overview, use_cases: use title and path to estimate use case, path: ai/plugin
|
||||||
|
- title: Subagent, use_cases: use title and path to estimate use case, path: ai/subagent
|
||||||
|
- title: Overview, use_cases: use title and path to estimate use case, path: ai/opencode-plugin
|
||||||
|
- title: Subagent, use_cases: use title and path to estimate use case, path: ai/opencode-subagent
|
||||||
|
- title: Overview, use_cases: use title and path to estimate use case, path: ai/skills
|
||||||
- title: Overview, use_cases: project setup, creating new svelte apps, scaffolding, cli tools, initializing projects, path: cli/overview
|
- title: Overview, use_cases: project setup, creating new svelte apps, scaffolding, cli tools, initializing projects, path: cli/overview
|
||||||
- title: Frequently asked questions, use_cases: project setup, initializing new svelte projects, troubleshooting cli installation, package manager configuration, path: cli/faq
|
- title: Frequently asked questions, use_cases: project setup, initializing new svelte projects, troubleshooting cli installation, package manager configuration, path: cli/faq
|
||||||
- title: sv create, use_cases: project setup, starting new sveltekit app, initializing project, creating from playground, choosing project template, path: cli/sv-create
|
- title: sv create, use_cases: project setup, starting new sveltekit app, initializing project, creating from playground, choosing project template, path: cli/sv-create
|
||||||
@@ -18,7 +30,7 @@ You are a Svelte expert tasked to build components and utilities for Svelte deve
|
|||||||
- title: devtools-json, use_cases: development setup, chrome devtools integration, browser-based editing, local development workflow, debugging setup, path: cli/devtools-json
|
- title: devtools-json, use_cases: development setup, chrome devtools integration, browser-based editing, local development workflow, debugging setup, path: cli/devtools-json
|
||||||
- title: drizzle, use_cases: database setup, sql queries, orm integration, data modeling, postgresql, mysql, sqlite, server-side data access, database migrations, type-safe queries, path: cli/drizzle
|
- title: drizzle, use_cases: database setup, sql queries, orm integration, data modeling, postgresql, mysql, sqlite, server-side data access, database migrations, type-safe queries, path: cli/drizzle
|
||||||
- title: eslint, use_cases: code quality, linting, error detection, project setup, code standards, team collaboration, typescript projects, path: cli/eslint
|
- title: eslint, use_cases: code quality, linting, error detection, project setup, code standards, team collaboration, typescript projects, path: cli/eslint
|
||||||
- title: lucia, use_cases: authentication, login systems, user management, registration pages, session handling, auth setup, path: cli/lucia
|
- title: better-auth, use_cases: use title and path to estimate use case, path: cli/better-auth
|
||||||
- title: mcp, use_cases: use title and path to estimate use case, path: cli/mcp
|
- title: mcp, use_cases: use title and path to estimate use case, path: cli/mcp
|
||||||
- title: mdsvex, use_cases: blog, content sites, markdown rendering, documentation sites, technical writing, cms integration, article pages, path: cli/mdsvex
|
- title: mdsvex, use_cases: blog, content sites, markdown rendering, documentation sites, technical writing, cms integration, article pages, path: cli/mdsvex
|
||||||
- title: paraglide, use_cases: internationalization, multi-language sites, i18n, translation, localization, language switching, global apps, multilingual content, path: cli/paraglide
|
- title: paraglide, use_cases: internationalization, multi-language sites, i18n, translation, localization, language switching, global apps, multilingual content, path: cli/paraglide
|
||||||
@@ -29,6 +41,7 @@ You are a Svelte expert tasked to build components and utilities for Svelte deve
|
|||||||
- title: tailwindcss, use_cases: project setup, styling, css framework, rapid prototyping, utility-first css, design systems, responsive design, adding tailwind to svelte, path: cli/tailwind
|
- title: tailwindcss, use_cases: project setup, styling, css framework, rapid prototyping, utility-first css, design systems, responsive design, adding tailwind to svelte, path: cli/tailwind
|
||||||
- title: vitest, use_cases: testing, unit tests, component testing, test setup, quality assurance, ci/cd pipelines, test-driven development, path: cli/vitest
|
- title: vitest, use_cases: testing, unit tests, component testing, test setup, quality assurance, ci/cd pipelines, test-driven development, path: cli/vitest
|
||||||
- title: add-on, use_cases: use title and path to estimate use case, path: cli/add-on
|
- title: add-on, use_cases: use title and path to estimate use case, path: cli/add-on
|
||||||
|
- title: sv-utils, use_cases: use title and path to estimate use case, path: cli/sv-utils
|
||||||
- title: Introduction, use_cases: learning sveltekit, project setup, understanding framework basics, choosing between svelte and sveltekit, getting started with full-stack apps, path: kit/introduction
|
- title: Introduction, use_cases: learning sveltekit, project setup, understanding framework basics, choosing between svelte and sveltekit, getting started with full-stack apps, path: kit/introduction
|
||||||
- title: Creating a project, use_cases: project setup, starting new sveltekit app, initial development environment, first-time sveltekit users, scaffolding projects, path: kit/creating-a-project
|
- title: Creating a project, use_cases: project setup, starting new sveltekit app, initial development environment, first-time sveltekit users, scaffolding projects, path: kit/creating-a-project
|
||||||
- title: Project types, use_cases: deployment, project setup, choosing adapters, ssg, spa, ssr, serverless, mobile apps, desktop apps, pwa, offline apps, browser extensions, separate backend, docker containers, path: kit/project-types
|
- title: Project types, use_cases: deployment, project setup, choosing adapters, ssg, spa, ssr, serverless, mobile apps, desktop apps, pwa, offline apps, browser extensions, separate backend, docker containers, path: kit/project-types
|
||||||
@@ -96,17 +109,6 @@ You are a Svelte expert tasked to build components and utilities for Svelte deve
|
|||||||
- title: Configuration, use_cases: project setup, configuration, adapters, deployment, build settings, environment variables, routing customization, prerendering, csp security, csrf protection, path configuration, typescript setup, path: kit/configuration
|
- title: Configuration, use_cases: project setup, configuration, adapters, deployment, build settings, environment variables, routing customization, prerendering, csp security, csrf protection, path configuration, typescript setup, path: kit/configuration
|
||||||
- title: Command Line Interface, use_cases: project setup, typescript configuration, generated types, ./$types imports, initial project configuration, path: kit/cli
|
- title: Command Line Interface, use_cases: project setup, typescript configuration, generated types, ./$types imports, initial project configuration, path: kit/cli
|
||||||
- title: Types, use_cases: typescript, type safety, route parameters, api endpoints, load functions, form actions, generated types, jsconfig setup, path: kit/types
|
- title: Types, use_cases: typescript, type safety, route parameters, api endpoints, load functions, form actions, generated types, jsconfig setup, path: kit/types
|
||||||
- title: Overview, use_cases: use title and path to estimate use case, path: mcp/overview
|
|
||||||
- title: Local setup, use_cases: use title and path to estimate use case, path: mcp/local-setup
|
|
||||||
- title: Remote setup, use_cases: use title and path to estimate use case, path: mcp/remote-setup
|
|
||||||
- title: Tools, use_cases: use title and path to estimate use case, path: mcp/tools
|
|
||||||
- title: Resources, use_cases: use title and path to estimate use case, path: mcp/resources
|
|
||||||
- title: Prompts, use_cases: use title and path to estimate use case, path: mcp/prompts
|
|
||||||
- title: Overview, use_cases: use title and path to estimate use case, path: mcp/plugin
|
|
||||||
- title: Skill, use_cases: use title and path to estimate use case, path: mcp/skill
|
|
||||||
- title: Subagent, use_cases: use title and path to estimate use case, path: mcp/subagent
|
|
||||||
- title: Overview, use_cases: use title and path to estimate use case, path: mcp/opencode-plugin
|
|
||||||
- title: Subagent, use_cases: use title and path to estimate use case, path: mcp/opencode-subagent
|
|
||||||
- title: Overview, use_cases: always, any svelte project, getting started, learning svelte, introduction, project setup, understanding framework basics, path: svelte/overview
|
- title: Overview, use_cases: always, any svelte project, getting started, learning svelte, introduction, project setup, understanding framework basics, path: svelte/overview
|
||||||
- title: Getting started, use_cases: project setup, starting new svelte project, initial installation, choosing between sveltekit and vite, editor configuration, path: svelte/getting-started
|
- title: Getting started, use_cases: project setup, starting new svelte project, initial installation, choosing between sveltekit and vite, editor configuration, path: svelte/getting-started
|
||||||
- title: .svelte files, use_cases: always, any svelte project, component creation, project setup, learning svelte basics, path: svelte/svelte-files
|
- title: .svelte files, use_cases: always, any svelte project, component creation, project setup, learning svelte basics, path: svelte/svelte-files
|
||||||
@@ -154,6 +156,7 @@ You are a Svelte expert tasked to build components and utilities for Svelte deve
|
|||||||
- title: Lifecycle hooks, use_cases: component initialization, cleanup tasks, timers, subscriptions, dom measurements, chat windows, autoscroll features, migration from svelte 4, path: svelte/lifecycle-hooks
|
- title: Lifecycle hooks, use_cases: component initialization, cleanup tasks, timers, subscriptions, dom measurements, chat windows, autoscroll features, migration from svelte 4, path: svelte/lifecycle-hooks
|
||||||
- title: Imperative component API, use_cases: project setup, client-side rendering, server-side rendering, ssr, hydration, testing, programmatic component creation, tooltips, dynamic mounting, path: svelte/imperative-component-api
|
- title: Imperative component API, use_cases: project setup, client-side rendering, server-side rendering, ssr, hydration, testing, programmatic component creation, tooltips, dynamic mounting, path: svelte/imperative-component-api
|
||||||
- title: Hydratable data, use_cases: use title and path to estimate use case, path: svelte/hydratable
|
- title: Hydratable data, use_cases: use title and path to estimate use case, path: svelte/hydratable
|
||||||
|
- title: Best practices, use_cases: use title and path to estimate use case, path: svelte/best-practices
|
||||||
- title: Testing, use_cases: testing, quality assurance, unit tests, integration tests, component tests, e2e tests, vitest setup, playwright setup, test automation, path: svelte/testing
|
- title: Testing, use_cases: testing, quality assurance, unit tests, integration tests, component tests, e2e tests, vitest setup, playwright setup, test automation, path: svelte/testing
|
||||||
- title: TypeScript, use_cases: typescript setup, type safety, component props typing, generic components, wrapper components, dom type augmentation, project configuration, path: svelte/typescript
|
- title: TypeScript, use_cases: typescript setup, type safety, component props typing, generic components, wrapper components, dom type augmentation, project configuration, path: svelte/typescript
|
||||||
- title: Custom elements, use_cases: web components, custom elements, component library, design system, framework-agnostic components, embedding svelte in non-svelte apps, shadow dom, path: svelte/custom-elements
|
- title: Custom elements, use_cases: web components, custom elements, component library, design system, framework-agnostic components, embedding svelte in non-svelte apps, shadow dom, path: svelte/custom-elements
|
||||||
@@ -204,6 +207,7 @@ This is the task you will work on:
|
|||||||
</task>
|
</task>
|
||||||
|
|
||||||
If you are not writing the code into a file, once you have the final version of the code ask the user if it wants to generate a playground link to quickly check the code in it and if it answer yes call the `playground-link` tool and return the url to the user nicely formatted. The playground link MUST be generated only once you have the final version of the code and you are ready to share it, it MUST include an entry point file called `App.svelte` where the main component should live. If you have multiple files to include in the playground link you can include them all at the root.
|
If you are not writing the code into a file, once you have the final version of the code ask the user if it wants to generate a playground link to quickly check the code in it and if it answer yes call the `playground-link` tool and return the url to the user nicely formatted. The playground link MUST be generated only once you have the final version of the code and you are ready to share it, it MUST include an entry point file called `App.svelte` where the main component should live. If you have multiple files to include in the playground link you can include them all at the root.
|
||||||
```
|
````
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ OpenCode has a [plugin system](https://opencode.ai/docs/plugins/) that allows de
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
To install the plugin in OpenCode you can edit your [OpenCode config]() (either the global or the local one), adding `@sveltejs/opencode` to the list of plugins.
|
To install the plugin in OpenCode you can edit your [OpenCode config](https://opencode.ai/docs/config/) (either the global or the local one), adding `@sveltejs/opencode` to the list of plugins.
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -23,7 +23,7 @@ The default configuration for the Svelte OpenCode plugin looks like this...
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"$schema": "https://raw.githubusercontent.com/sveltejs/ai-tools/refs/heads/main/packages/opencode/schema.json",
|
"$schema": "https://svelte.dev/opencode/schema.json",
|
||||||
"mcp": {
|
"mcp": {
|
||||||
"type": "remote",
|
"type": "remote",
|
||||||
"enabled": true
|
"enabled": true
|
||||||
|
|||||||
@@ -217,7 +217,7 @@ The CSS in a component's `<style>` is scoped to that component. If a parent comp
|
|||||||
</style>
|
</style>
|
||||||
```
|
```
|
||||||
|
|
||||||
If this impossible (for example, the child component comes from a library) you can use `:global` to override styles:
|
If this is impossible (for example, the child component comes from a library) you can use `:global` to override styles:
|
||||||
|
|
||||||
```svelte
|
```svelte
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -25,10 +25,12 @@
|
|||||||
"debug:generate-summaries": "pnpm --filter @sveltejs/mcp-server run debug:generate-summaries",
|
"debug:generate-summaries": "pnpm --filter @sveltejs/mcp-server run debug:generate-summaries",
|
||||||
"release": "pnpm --filter @sveltejs/mcp run build && changeset publish",
|
"release": "pnpm --filter @sveltejs/mcp run build && changeset publish",
|
||||||
"changeset:version": "changeset version && pnpm --filter @sveltejs/mcp run update:version && git add --all",
|
"changeset:version": "changeset version && pnpm --filter @sveltejs/mcp run update:version && git add --all",
|
||||||
|
"sync-plugins": "pnpm sync-claude-plugin && pnpm sync-cursor-plugin && pnpm sync-opencode-plugin && pnpm bump-plugin-versions",
|
||||||
"sync-claude-plugin": "node scripts/sync-claude-plugin.ts",
|
"sync-claude-plugin": "node scripts/sync-claude-plugin.ts",
|
||||||
"sync-cursor-plugin": "node scripts/sync-cursor-plugin.ts",
|
"sync-cursor-plugin": "node scripts/sync-cursor-plugin.ts",
|
||||||
"sync-opencode-plugin": "node scripts/sync-opencode-plugin.ts",
|
"sync-opencode-plugin": "node scripts/sync-opencode-plugin.ts && pnpm generate-opencode-jsonschema",
|
||||||
"bump-plugin-versions": "node scripts/bump-plugin-versions.ts",
|
"bump-plugin-versions": "node scripts/bump-plugin-versions.ts",
|
||||||
|
"postbump-plugin-versions": "pnpm format",
|
||||||
"resolve-references": "node scripts/resolve-references.ts",
|
"resolve-references": "node scripts/resolve-references.ts",
|
||||||
"postresolve-references": "pnpm format"
|
"postresolve-references": "pnpm format"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -344,87 +344,111 @@ describe('add_autofixers_issues', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('imported_runes', () => {
|
describe('imported_runes', () => {
|
||||||
describe.each([{ source: 'svelte' }, { source: 'svelte/runes' }])(
|
describe.each([
|
||||||
'from "$source"',
|
{ source: 'svelte' },
|
||||||
({ source }) => {
|
{ source: 'svelte/runes' },
|
||||||
describe.each(dollarless_runes)('single import ($rune)', ({ rune }) => {
|
{ source: '@sveltejs/runes' },
|
||||||
it(`should add suggestions when importing '${rune}' from '${source}'`, () => {
|
{ source: '@sveltejs/vite-plugin-svelte' },
|
||||||
const content = run_autofixers_on_code(`
|
])('from "$source"', ({ source }) => {
|
||||||
|
describe.each(dollarless_runes)('single import ($rune)', ({ rune }) => {
|
||||||
|
it(`should add suggestions when importing '${rune}' from '${source}'`, () => {
|
||||||
|
const content = run_autofixers_on_code(`
|
||||||
<script>
|
<script>
|
||||||
import { ${rune} } from '${source}';
|
import { ${rune} } from '${source}';
|
||||||
</script>`);
|
</script>`);
|
||||||
|
|
||||||
expect(content.suggestions.length).toBeGreaterThanOrEqual(1);
|
expect(content.suggestions.length).toBeGreaterThanOrEqual(1);
|
||||||
expect(content.suggestions).toContain(
|
expect(content.suggestions).toContain(
|
||||||
`You are importing "${rune}" from "${source}". This is not necessary, all runes are globally available. Please remove this import and use "$${rune}" directly.`,
|
`You are importing "${rune}" from "${source}". This is not necessary, all runes are globally available. Please remove this import and use "$${rune}" directly.`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should add suggestions when importing "${rune}" as the default export from '${source}'`, () => {
|
it(`should add suggestions when importing "${rune}" as the default export from '${source}'`, () => {
|
||||||
const content = run_autofixers_on_code(`
|
const content = run_autofixers_on_code(`
|
||||||
<script>
|
<script>
|
||||||
import ${rune} from '${source}';
|
import ${rune} from '${source}';
|
||||||
</script>`);
|
</script>`);
|
||||||
|
|
||||||
expect(content.suggestions.length).toBeGreaterThanOrEqual(1);
|
expect(content.suggestions.length).toBeGreaterThanOrEqual(1);
|
||||||
expect(content.suggestions).toContain(
|
expect(content.suggestions).toContain(
|
||||||
`You are importing "${rune}" from "${source}". This is not necessary, all runes are globally available. Please remove this import and use "$${rune}" directly.`,
|
`You are importing "${rune}" from "${source}". This is not necessary, all runes are globally available. Please remove this import and use "$${rune}" directly.`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should add suggestions when importing '${rune}' as the namespace export from '${source}'`, () => {
|
it(`should add suggestions when importing '${rune}' as the namespace export from '${source}'`, () => {
|
||||||
const content = run_autofixers_on_code(`
|
const content = run_autofixers_on_code(`
|
||||||
<script>
|
<script>
|
||||||
import * as ${rune} from '${source}';
|
import * as ${rune} from '${source}';
|
||||||
</script>`);
|
</script>`);
|
||||||
|
|
||||||
expect(content.suggestions.length).toBeGreaterThanOrEqual(1);
|
expect(content.suggestions.length).toBeGreaterThanOrEqual(1);
|
||||||
expect(content.suggestions).toContain(
|
expect(content.suggestions).toContain(
|
||||||
`You are importing "${rune}" from "${source}". This is not necessary, all runes are globally available. Please remove this import and use "$${rune}" directly.`,
|
`You are importing "${rune}" from "${source}". This is not necessary, all runes are globally available. Please remove this import and use "$${rune}" directly.`,
|
||||||
);
|
);
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it(`should add suggestions when importing multiple runes from '${source}'`, () => {
|
it(`should add suggestions when importing multiple runes from '${source}'`, () => {
|
||||||
const content = run_autofixers_on_code(`
|
const content = run_autofixers_on_code(`
|
||||||
<script>
|
<script>
|
||||||
import { onMount, state, effect } from '${source}';
|
import { onMount, state, effect } from '${source}';
|
||||||
</script>`);
|
</script>`);
|
||||||
|
|
||||||
expect(content.suggestions.length).toBeGreaterThanOrEqual(2);
|
expect(content.suggestions.length).toBeGreaterThanOrEqual(2);
|
||||||
expect(content.suggestions).toContain(
|
expect(content.suggestions).toContain(
|
||||||
`You are importing "state" from "${source}". This is not necessary, all runes are globally available. Please remove this import and use "$state" directly.`,
|
`You are importing "state" from "${source}". This is not necessary, all runes are globally available. Please remove this import and use "$state" directly.`,
|
||||||
);
|
);
|
||||||
expect(content.suggestions).toContain(
|
expect(content.suggestions).toContain(
|
||||||
`You are importing "effect" from "${source}". This is not necessary, all runes are globally available. Please remove this import and use "$effect" directly.`,
|
`You are importing "effect" from "${source}". This is not necessary, all runes are globally available. Please remove this import and use "$effect" directly.`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should not add suggestions when importing other identifiers from '${source}'`, () => {
|
it(`should not add suggestions when importing other identifiers from '${source}'`, () => {
|
||||||
const content = run_autofixers_on_code(`
|
const content = run_autofixers_on_code(`
|
||||||
<script>
|
<script>
|
||||||
import { onMount } from '${source}';
|
import { onMount } from '${source}';
|
||||||
</script>`);
|
</script>`);
|
||||||
|
|
||||||
expect(content.suggestions).not.toContain(
|
expect(content.suggestions).not.toContain(
|
||||||
`You are importing "onMount" from "${source}". This is not necessary, all runes are globally available. Please remove this import and use "$onMount" directly.`,
|
`You are importing "onMount" from "${source}". This is not necessary, all runes are globally available. Please remove this import and use "$onMount" directly.`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
},
|
});
|
||||||
);
|
|
||||||
|
|
||||||
describe.each(dollarless_runes)('importing $rune from external lib', ({ rune }) => {
|
describe.each(dollarless_runes)('importing $rune from external lib', ({ rune }) => {
|
||||||
it(`should not add suggestions when importing from packages that are not svelte`, () => {
|
it(`should not add suggestions when importing from packages whose name doesn't contain svelte`, () => {
|
||||||
|
const content = run_autofixers_on_code(`
|
||||||
|
<script>
|
||||||
|
import { ${rune} } from 'something-something';
|
||||||
|
</script>`);
|
||||||
|
|
||||||
|
expect(content.suggestions).not.toContain(
|
||||||
|
`You are importing "${rune}" from "something-something". This is not necessary, all runes are globally available. Please remove this import and use "$${rune}" directly.`,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should add suggestions with a different hint when importing from packages whose name contains svelte but it's not official`, () => {
|
||||||
const content = run_autofixers_on_code(`
|
const content = run_autofixers_on_code(`
|
||||||
<script>
|
<script>
|
||||||
import { ${rune} } from 'svelte-something-something';
|
import { ${rune} } from 'svelte-something-something';
|
||||||
</script>`);
|
</script>`);
|
||||||
|
|
||||||
expect(content.suggestions).not.toContain(
|
expect(content.suggestions).toContain(
|
||||||
`You are importing "${rune}" from "svelte-something-something". This is not necessary, all runes are globally available. Please remove this import and use "$${rune}" directly.`,
|
`You are importing "${rune}" from "svelte-something-something". If you are trying to import runes to use them this is not necessary, all runes are globally available. Please remove this import and use "$${rune}" directly. If you are importing the function from a separate library ignore this suggestion.`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should not add the imported_runes suggestion when importing derived from svelte/store', () => {
|
||||||
|
const content = run_autofixers_on_code(`
|
||||||
|
<script>
|
||||||
|
import { derived } from 'svelte/store';
|
||||||
|
</script>`);
|
||||||
|
|
||||||
|
expect(content.suggestions).not.toContain(
|
||||||
|
'You are importing "derived" from "svelte/store". This is not necessary, all runes are globally available. Please remove this import and use "$derived" directly.',
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('derived_with_function', () => {
|
describe('derived_with_function', () => {
|
||||||
|
|||||||
@@ -3,10 +3,20 @@ import type { Autofixer } from './index.js';
|
|||||||
|
|
||||||
const dollarless_runes = base_runes.map((r) => r.replace('$', ''));
|
const dollarless_runes = base_runes.map((r) => r.replace('$', ''));
|
||||||
|
|
||||||
|
function should_suggest_for_source(source: string, rune: string) {
|
||||||
|
if (!source.includes('svelte')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (source === 'svelte/store' && rune === 'derived') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
export const imported_runes: Autofixer = {
|
export const imported_runes: Autofixer = {
|
||||||
ImportDeclaration(node, { state, next }) {
|
ImportDeclaration(node, { state, next }) {
|
||||||
const source = (node.source.value || node.source.raw?.slice(1, -1))?.toString();
|
const source = (node.source.value || node.source.raw?.slice(1, -1))?.toString();
|
||||||
if (source && (source === 'svelte' || source.startsWith('svelte/'))) {
|
if (source) {
|
||||||
for (const specifier of node.specifiers) {
|
for (const specifier of node.specifiers) {
|
||||||
const id =
|
const id =
|
||||||
specifier.type === 'ImportDefaultSpecifier'
|
specifier.type === 'ImportDefaultSpecifier'
|
||||||
@@ -16,10 +26,25 @@ export const imported_runes: Autofixer = {
|
|||||||
: specifier.type === 'ImportSpecifier'
|
: specifier.type === 'ImportSpecifier'
|
||||||
? specifier.imported
|
? specifier.imported
|
||||||
: null;
|
: null;
|
||||||
if (id && id.type === 'Identifier' && dollarless_runes.includes(id.name)) {
|
if (
|
||||||
state.output.suggestions.push(
|
id &&
|
||||||
`You are importing "${id.name}" from "${source}". This is not necessary, all runes are globally available. Please remove this import and use "$${id.name}" directly.`,
|
id.type === 'Identifier' &&
|
||||||
);
|
dollarless_runes.includes(id.name) &&
|
||||||
|
should_suggest_for_source(source, id.name)
|
||||||
|
) {
|
||||||
|
if (
|
||||||
|
source === 'svelte' ||
|
||||||
|
source.startsWith('svelte/') ||
|
||||||
|
source.startsWith('@sveltejs')
|
||||||
|
) {
|
||||||
|
state.output.suggestions.push(
|
||||||
|
`You are importing "${id.name}" from "${source}". This is not necessary, all runes are globally available. Please remove this import and use "$${id.name}" directly.`,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
state.output.suggestions.push(
|
||||||
|
`You are importing "${id.name}" from "${source}". If you are trying to import runes to use them this is not necessary, all runes are globally available. Please remove this import and use "$${id.name}" directly. If you are importing the function from a separate library ignore this suggestion.`,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
# @sveltejs/mcp
|
# @sveltejs/mcp
|
||||||
|
|
||||||
|
## 0.1.22
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- fix: broaden checks for imported runes because LLMs are unhinged ([#185](https://github.com/sveltejs/ai-tools/pull/185))
|
||||||
|
|
||||||
## 0.1.21
|
## 0.1.21
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@sveltejs/mcp",
|
"name": "@sveltejs/mcp",
|
||||||
"version": "0.1.21",
|
"version": "0.1.22",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"mcpName": "dev.svelte/mcp",
|
"mcpName": "dev.svelte/mcp",
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
"subfolder": "packages/mcp-stdio",
|
"subfolder": "packages/mcp-stdio",
|
||||||
"source": "github"
|
"source": "github"
|
||||||
},
|
},
|
||||||
"version": "0.1.21",
|
"version": "0.1.22",
|
||||||
"websiteUrl": "https://svelte.dev/docs/mcp/overview",
|
"websiteUrl": "https://svelte.dev/docs/mcp/overview",
|
||||||
"icons": [
|
"icons": [
|
||||||
{
|
{
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
{
|
{
|
||||||
"registryType": "npm",
|
"registryType": "npm",
|
||||||
"identifier": "@sveltejs/mcp",
|
"identifier": "@sveltejs/mcp",
|
||||||
"version": "0.1.21",
|
"version": "0.1.22",
|
||||||
"runtimeHint": "npx",
|
"runtimeHint": "npx",
|
||||||
"transport": {
|
"transport": {
|
||||||
"type": "stdio"
|
"type": "stdio"
|
||||||
|
|||||||
@@ -1,5 +1,25 @@
|
|||||||
# @sveltejs/opencode
|
# @sveltejs/opencode
|
||||||
|
|
||||||
|
## 0.1.8
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- fix: add `server` export to opencode plugin ([`96c50ac`](https://github.com/sveltejs/ai-tools/commit/96c50acae2b4131a6c72d3579a73c44ab9158b18))
|
||||||
|
|
||||||
|
## 0.1.7
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- fix: import `ts` files directly ([#190](https://github.com/sveltejs/ai-tools/pull/190))
|
||||||
|
|
||||||
|
## 0.1.6
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- chore: sync skills from svelte.dev ([#178](https://github.com/sveltejs/ai-tools/pull/178))
|
||||||
|
|
||||||
|
- fix: update svelte-file-editor agent to use proper name ([#183](https://github.com/sveltejs/ai-tools/pull/183))
|
||||||
|
|
||||||
## 0.1.5
|
## 0.1.5
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
@@ -36,39 +36,76 @@ The plugin injects instructions that teach the agent how to effectively use the
|
|||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
The default configuration:
|
Create `svelte.json` to customize how the plugin configures MCP, the Svelte subagent, instructions, and skills.
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"$schema": "https://raw.githubusercontent.com/sveltejs/ai-tools/refs/heads/main/packages/opencode/schema.json",
|
"$schema": "https://svelte.dev/opencode/schema.json",
|
||||||
"mcp": {
|
"mcp": {
|
||||||
"type": "remote",
|
"type": "remote",
|
||||||
"enabled": true
|
"enabled": true
|
||||||
},
|
},
|
||||||
"subagent": {
|
"subagent": {
|
||||||
"enabled": true
|
"enabled": true,
|
||||||
|
"agents": {
|
||||||
|
"svelte-file-editor": {
|
||||||
|
"model": "anthropic/claude-sonnet-4-20250514",
|
||||||
|
"temperature": 0.7,
|
||||||
|
"top_p": 0.9,
|
||||||
|
"maxSteps": 20
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"instructions": {
|
"instructions": {
|
||||||
"enabled": true
|
"enabled": true
|
||||||
|
},
|
||||||
|
"skills": {
|
||||||
|
"enabled": ["svelte-code-writer", "svelte-core-bestpractices"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Defaults
|
||||||
|
|
||||||
|
If omitted, the plugin uses these defaults:
|
||||||
|
|
||||||
|
- `mcp.type`: `"remote"`
|
||||||
|
- `mcp.enabled`: `true`
|
||||||
|
- `subagent.enabled`: `true`
|
||||||
|
- `subagent.agents`: `{}`
|
||||||
|
- `instructions.enabled`: `true`
|
||||||
|
- `skills.enabled`: `true`
|
||||||
|
|
||||||
### Configuration Options
|
### Configuration Options
|
||||||
|
|
||||||
| Option | Type | Default | Description |
|
| Option | Type | Default | Description |
|
||||||
| ---------------------- | ----------------------- | ---------- | -------------------------------------------------------------------------------- |
|
| ------------------------------------------------ | --------------------- | ---------- | ---------------------------------------------------------------------------------------------- |
|
||||||
| `mcp.type` | `"remote"` \| `"local"` | `"remote"` | Use the remote server at `mcp.svelte.dev` or run locally via `npx @sveltejs/mcp` |
|
| `mcp.type` | `"remote" \| "local"` | `"remote"` | Use `https://mcp.svelte.dev/mcp` (`remote`) or run `@sveltejs/mcp` via `npx` (`local`). |
|
||||||
| `mcp.enabled` | `boolean` | `true` | Enable/disable the MCP server |
|
| `mcp.enabled` | `boolean` | `true` | Enable or disable the Svelte MCP server entry. |
|
||||||
| `subagent.enabled` | `boolean` | `true` | Enable/disable the Svelte file editor subagent |
|
| `subagent.enabled` | `boolean` | `true` | Enable or disable registration of the `svelte-file-editor` subagent. |
|
||||||
| `instructions.enabled` | `boolean` | `true` | Enable/disable agent instructions injection |
|
| `subagent.agents.svelte-file-editor.model` | `string` | main agent | Override the model used by the Svelte file editor subagent. |
|
||||||
|
| `subagent.agents.svelte-file-editor.temperature` | `number` | unset | Set temperature for the subagent. |
|
||||||
|
| `subagent.agents.svelte-file-editor.top_p` | `number` | unset | Set top-p sampling for the subagent. |
|
||||||
|
| `subagent.agents.svelte-file-editor.maxSteps` | `number` | unlimited | Limit the number of steps the subagent can execute. |
|
||||||
|
| `instructions.enabled` | `boolean` | `true` | Enable or disable automatic instruction-file injection. |
|
||||||
|
| `skills.enabled` | `boolean \| string[]` | `true` | Enable all skills (`true`), disable all skills (`false`), or enable only specific skill names. |
|
||||||
|
|
||||||
### Config File Location
|
### Supported Skill Names
|
||||||
|
|
||||||
Place your configuration at one of these locations:
|
When using `skills.enabled` as an array, these built-in names are currently available:
|
||||||
|
|
||||||
- `~/.config/opencode/svelte.json` (global)
|
- `svelte-code-writer`
|
||||||
- `$OPENCODE_CONFIG_DIR/svelte.json` (if `OPENCODE_CONFIG_DIR` is set, takes priority)
|
- `svelte-core-bestpractices`
|
||||||
|
|
||||||
|
### Config File Locations and Precedence
|
||||||
|
|
||||||
|
The plugin reads from these files (lowest priority first, highest priority last):
|
||||||
|
|
||||||
|
- `~/.config/opencode/svelte.json`
|
||||||
|
- `$OPENCODE_CONFIG_DIR/svelte.json` (when `OPENCODE_CONFIG_DIR` is set)
|
||||||
|
- `.opencode/svelte.json` in the current project
|
||||||
|
|
||||||
|
If the same key is defined in multiple files, the later location overrides earlier ones.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
11
packages/opencode/agents.ts
Normal file
11
packages/opencode/agents.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
// 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 = {
|
||||||
|
'svelte-file-editor': {
|
||||||
|
description:
|
||||||
|
'Specialized Svelte 5 code editor. MUST BE USED PROACTIVELY when creating, editing, or reviewing any .svelte file or .svelte.ts/.svelte.js module and MUST use the tools from the MCP server or the `svelte-file-editor` skill if they are available. Fetches relevant documentation and validates code using the Svelte MCP server tools.',
|
||||||
|
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.\n\nIf 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.\n\nIf the skill is not available you can run `npx @sveltejs/mcp@latest -y --help` to learn how to use it.\n\n## Available MCP Tools\n\n### 1. list-sections\n\nLists all available Svelte 5 and SvelteKit documentation sections with titles and paths. Use this first to discover what documentation is available.\n\n### 2. get-documentation\n\nRetrieves full documentation for specified sections. Accepts a single section name or an array of section names. Use after `list-sections` to fetch relevant docs for the task at hand.\n\n**Example sections:** `$state`, `$derived`, `$effect`, `$props`, `$bindable`, `snippets`, `routing`, `load functions`\n\n### 3. svelte-autofixer\n\nAnalyzes Svelte code and returns suggestions to fix issues. Pass the component code directly to this tool. It will detect common mistakes like:\n\n- Using `$effect` instead of `$derived` for computations\n- Missing cleanup in effects\n- Svelte 4 syntax (`on:click`, `export let`, `<slot>`)\n- Missing keys in `{#each}` blocks\n- And more\n\n## Workflow\n\nWhen invoked to work on a Svelte file:\n\n### 1. Gather Context (if needed)\n\nIf you're uncertain about Svelte 5 syntax or patterns, use the MCP tools:\n\n1. Call `list-sections` to see available documentation\n2. Call `get-documentation` with relevant section names\n\n### 2. Read the Target File\n\nRead the file to understand the current implementation.\n\n### 3. Make Changes\n\nApply edits following Svelte 5 best practices:\n\n### 4. Validate Changes\n\nAfter editing, ALWAYS call `svelte-autofixer` with the updated code to check for issues.\n\n### 5. Fix Any Issues\n\nIf the autofixer reports problems, fix them and re-validate until no issues remain.\n\n## Output Format\n\nAfter completing your work, provide:\n\n1. Summary of changes made\n2. Any issues found and fixed by the autofixer\n3. Recommendations for further improvements (if any)",
|
||||||
|
},
|
||||||
|
} as const;
|
||||||
@@ -2,7 +2,8 @@ import type { Plugin } from '@opencode-ai/plugin';
|
|||||||
import { readdir } from 'node:fs/promises';
|
import { readdir } from 'node:fs/promises';
|
||||||
import { dirname, join } from 'node:path';
|
import { dirname, join } from 'node:path';
|
||||||
import { fileURLToPath } from 'node:url';
|
import { fileURLToPath } from 'node:url';
|
||||||
import { get_mcp_config } from './config.js';
|
import { agents } from './agents.ts';
|
||||||
|
import { get_mcp_config } from './config.ts';
|
||||||
|
|
||||||
const current_dir = dirname(fileURLToPath(import.meta.url));
|
const current_dir = dirname(fileURLToPath(import.meta.url));
|
||||||
|
|
||||||
@@ -72,105 +73,44 @@ export const svelte_plugin: Plugin = async (ctx) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mcp_config.subagent?.enabled !== false) {
|
if (mcp_config.subagent?.enabled !== false) {
|
||||||
// we add the editor subagent that will be used when editing Svelte files to prevent wasting context on the main agent
|
for (const [agent_name, agent_data] of Object.entries(agents)) {
|
||||||
const default_config: (typeof input.agent)[string] = {
|
// we add the editor subagent that will be used when editing Svelte files to prevent wasting context on the main agent
|
||||||
color: '#ff3e00',
|
const default_config: (typeof input.agent)[string] = {
|
||||||
mode: 'subagent',
|
color: '#ff3e00',
|
||||||
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.
|
mode: 'subagent',
|
||||||
|
prompt: agent_data.prompt,
|
||||||
|
description: agent_data.description,
|
||||||
|
permission: {
|
||||||
|
bash: 'ask',
|
||||||
|
edit: 'allow',
|
||||||
|
webfetch: 'ask',
|
||||||
|
},
|
||||||
|
tools: {
|
||||||
|
[`${svelte_mcp_name}_*`]: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
If the MCP tools are not available you can use the \`svelte-code-editor\` skill to learn how to use the \`@sveltejs/mcp\` cli to access the same tools.
|
// Get per-agent config from svelte.json (if any)
|
||||||
|
const agent_config = mcp_config.subagent?.agents?.[agent_name];
|
||||||
|
|
||||||
If the skill is not available you can run \`npx @sveltejs/mcp@latest -y --help\` to learn how to use it.
|
// Configure agent from svelte.json only
|
||||||
|
// Priority: svelte.json agent config > defaults
|
||||||
## Available MCP Tools
|
input.agent[agent_name] = {
|
||||||
|
...default_config,
|
||||||
### 1. list-sections
|
...(agent_config?.model !== undefined && {
|
||||||
|
model: agent_config.model,
|
||||||
Lists all available Svelte 5 and SvelteKit documentation sections with titles and paths. Use this first to discover what documentation is available.
|
}),
|
||||||
|
...(agent_config?.temperature !== undefined && {
|
||||||
### 2. get-documentation
|
temperature: agent_config.temperature,
|
||||||
|
}),
|
||||||
Retrieves full documentation for specified sections. Accepts a single section name or an array of section names. Use after \`list-sections\` to fetch relevant docs for the task at hand.
|
...(agent_config?.maxSteps !== undefined && {
|
||||||
|
maxSteps: agent_config.maxSteps,
|
||||||
**Example sections:** \`$state\`, \`$derived\`, \`$effect\`, \`$props\`, \`$bindable\`, \`snippets\`, \`routing\`, \`load functions\`
|
}),
|
||||||
|
...(agent_config?.top_p !== undefined && {
|
||||||
### 3. svelte-autofixer
|
top_p: agent_config.top_p,
|
||||||
|
}),
|
||||||
Analyzes Svelte code and returns suggestions to fix issues. Pass the component code directly to this tool. It will detect common mistakes like:
|
};
|
||||||
|
}
|
||||||
- Using \`$effect\` instead of \`$derived\` for computations
|
|
||||||
- Missing cleanup in effects
|
|
||||||
- Svelte 4 syntax (\`on:click\`, \`export let\`, \`<slot>\`)
|
|
||||||
- Missing keys in \`{#each}\` blocks
|
|
||||||
- And more
|
|
||||||
|
|
||||||
## Workflow
|
|
||||||
|
|
||||||
When invoked to work on a Svelte file:
|
|
||||||
|
|
||||||
### 1. Gather Context (if needed)
|
|
||||||
|
|
||||||
If you're uncertain about Svelte 5 syntax or patterns, use the MCP tools:
|
|
||||||
|
|
||||||
1. Call \`list-sections\` to see available documentation
|
|
||||||
2. Call \`get-documentation\` with relevant section names
|
|
||||||
|
|
||||||
### 2. Read the Target File
|
|
||||||
|
|
||||||
Read the file to understand the current implementation.
|
|
||||||
|
|
||||||
### 3. Make Changes
|
|
||||||
|
|
||||||
Apply edits following Svelte 5 best practices:
|
|
||||||
|
|
||||||
### 4. Validate Changes
|
|
||||||
|
|
||||||
After editing, ALWAYS call \`svelte-autofixer\` with the updated code to check for issues.
|
|
||||||
|
|
||||||
### 5. Fix Any Issues
|
|
||||||
|
|
||||||
If the autofixer reports problems, fix them and re-validate until no issues remain.
|
|
||||||
|
|
||||||
## Output Format
|
|
||||||
|
|
||||||
After completing your work, provide:
|
|
||||||
|
|
||||||
1. Summary of changes made
|
|
||||||
2. Any issues found and fixed by the autofixer
|
|
||||||
3. Recommendations for further improvements (if any)
|
|
||||||
`,
|
|
||||||
description:
|
|
||||||
'Specialized Svelte 5 code editor. MUST BE USED PROACTIVELY when creating, editing, or reviewing any .svelte file or .svelte.ts/.svelte.js module and MUST use the tools from the MCP server or the `svelte-code-writer` skill if they are available. Fetches relevant documentation and validates code using the Svelte MCP server tools.',
|
|
||||||
permission: {
|
|
||||||
bash: 'ask',
|
|
||||||
edit: 'allow',
|
|
||||||
webfetch: 'ask',
|
|
||||||
},
|
|
||||||
tools: {
|
|
||||||
[`${svelte_mcp_name}_*`]: true,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Get per-agent config from svelte.json (if any)
|
|
||||||
const svelte_file_editor_config = mcp_config.subagent?.agents?.['svelte-file-editor'];
|
|
||||||
|
|
||||||
// Configure agent from svelte.json only
|
|
||||||
// Priority: svelte.json agent config > defaults
|
|
||||||
input.agent['svelte-file-editor'] = {
|
|
||||||
...default_config,
|
|
||||||
...(svelte_file_editor_config?.model !== undefined && {
|
|
||||||
model: svelte_file_editor_config.model,
|
|
||||||
}),
|
|
||||||
...(svelte_file_editor_config?.temperature !== undefined && {
|
|
||||||
temperature: svelte_file_editor_config.temperature,
|
|
||||||
}),
|
|
||||||
...(svelte_file_editor_config?.maxSteps !== undefined && {
|
|
||||||
maxSteps: svelte_file_editor_config.maxSteps,
|
|
||||||
}),
|
|
||||||
...(svelte_file_editor_config?.top_p !== undefined && {
|
|
||||||
top_p: svelte_file_editor_config.top_p,
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@sveltejs/opencode",
|
"name": "@sveltejs/opencode",
|
||||||
"version": "0.1.5",
|
"version": "0.1.8",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"homepage": "https://github.com/sveltejs/ai-tools#readme",
|
"homepage": "https://github.com/sveltejs/ai-tools#readme",
|
||||||
@@ -14,9 +14,16 @@
|
|||||||
"files": [
|
"files": [
|
||||||
"index.ts",
|
"index.ts",
|
||||||
"config.ts",
|
"config.ts",
|
||||||
|
"agents.ts",
|
||||||
"instructions",
|
"instructions",
|
||||||
"skills"
|
"skills"
|
||||||
],
|
],
|
||||||
|
"exports": {
|
||||||
|
"./server": {
|
||||||
|
"types": "./index.ts",
|
||||||
|
"import": "./index.ts"
|
||||||
|
}
|
||||||
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/sveltejs/ai-tools.git",
|
"url": "git+https://github.com/sveltejs/ai-tools.git",
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ The CSS in a component's `<style>` is scoped to that component. If a parent comp
|
|||||||
</style>
|
</style>
|
||||||
```
|
```
|
||||||
|
|
||||||
If this impossible (for example, the child component comes from a library) you can use `:global` to override styles:
|
If this is impossible (for example, the child component comes from a library) you can use `:global` to override styles:
|
||||||
|
|
||||||
```svelte
|
```svelte
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
{
|
{
|
||||||
"extends": "../../tsconfig.json",
|
"extends": "../../tsconfig.json",
|
||||||
"include": ["index.ts", "config.ts", "scripts/*"],
|
"compilerOptions": {
|
||||||
|
"allowImportingTsExtensions": true,
|
||||||
|
"types": ["@types/node"]
|
||||||
|
},
|
||||||
|
"include": ["index.ts", "config.ts", "agents.ts", "scripts/*"],
|
||||||
"exclude": ["node_modules"]
|
"exclude": ["node_modules"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "svelte",
|
"name": "svelte",
|
||||||
"description": "A plugin for all things related to Svelte development, MCP, skills, and more.",
|
"description": "A plugin for all things related to Svelte development, MCP, skills, and more.",
|
||||||
"version": "1.0.2",
|
"version": "1.0.4",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Svelte"
|
"name": "Svelte"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ permissionMode: acceptEdits
|
|||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
If the MCP tools are not available you can use the `svelte-code-editor` skill to learn how to use the `@sveltejs/mcp` cli to access the same tools.
|
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.
|
||||||
|
|
||||||
If the skill is not available you can run `npx @sveltejs/mcp@latest -y --help` to learn how to use it.
|
If the skill is not available you can run `npx @sveltejs/mcp@latest -y --help` to learn how to use it.
|
||||||
|
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ The CSS in a component's `<style>` is scoped to that component. If a parent comp
|
|||||||
</style>
|
</style>
|
||||||
```
|
```
|
||||||
|
|
||||||
If this impossible (for example, the child component comes from a library) you can use `:global` to override styles:
|
If this is impossible (for example, the child component comes from a library) you can use `:global` to override styles:
|
||||||
|
|
||||||
```svelte
|
```svelte
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "svelte",
|
"name": "svelte",
|
||||||
"description": "A plugin for all things related to Svelte development, MCP, skills, and more.",
|
"description": "A plugin for all things related to Svelte development, MCP, skills, and more.",
|
||||||
"version": "1.0.2",
|
"version": "1.0.4",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Svelte"
|
"name": "Svelte"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ description: Specialized Svelte 5 code editor. MUST BE USED PROACTIVELY when cre
|
|||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
If the MCP tools are not available you can use the `svelte-code-editor` skill to learn how to use the `@sveltejs/mcp` cli to access the same tools.
|
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.
|
||||||
|
|
||||||
If the skill is not available you can run `npx @sveltejs/mcp@latest -y --help` to learn how to use it.
|
If the skill is not available you can run `npx @sveltejs/mcp@latest -y --help` to learn how to use it.
|
||||||
|
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ The CSS in a component's `<style>` is scoped to that component. If a parent comp
|
|||||||
</style>
|
</style>
|
||||||
```
|
```
|
||||||
|
|
||||||
If this impossible (for example, the child component comes from a library) you can use `:global` to override styles:
|
If this is impossible (for example, the child component comes from a library) you can use `:global` to override styles:
|
||||||
|
|
||||||
```svelte
|
```svelte
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
27
pnpm-lock.yaml
generated
27
pnpm-lock.yaml
generated
@@ -123,8 +123,8 @@ catalogs:
|
|||||||
specifier: ^1.5.0
|
specifier: ^1.5.0
|
||||||
version: 1.5.0
|
version: 1.5.0
|
||||||
'@vercel/analytics':
|
'@vercel/analytics':
|
||||||
specifier: ^1.5.0
|
specifier: ^2.0.0
|
||||||
version: 1.6.1
|
version: 2.0.1
|
||||||
dotenv:
|
dotenv:
|
||||||
specifier: ^17.2.3
|
specifier: ^17.2.3
|
||||||
version: 17.2.3
|
version: 17.2.3
|
||||||
@@ -192,7 +192,7 @@ importers:
|
|||||||
version: 10.1.8(eslint@9.39.2)
|
version: 10.1.8(eslint@9.39.2)
|
||||||
eslint-plugin-import:
|
eslint-plugin-import:
|
||||||
specifier: catalog:lint
|
specifier: catalog:lint
|
||||||
version: 2.32.0(@typescript-eslint/parser@8.54.0(eslint@9.39.2)(typescript@5.9.3))(eslint@9.39.2)
|
version: 2.32.0(eslint@9.39.2)
|
||||||
eslint-plugin-pnpm:
|
eslint-plugin-pnpm:
|
||||||
specifier: catalog:lint
|
specifier: catalog:lint
|
||||||
version: 1.5.0(eslint@9.39.2)
|
version: 1.5.0(eslint@9.39.2)
|
||||||
@@ -237,7 +237,7 @@ importers:
|
|||||||
version: 0.8.4(tmcp@1.19.2(typescript@5.9.3))
|
version: 0.8.4(tmcp@1.19.2(typescript@5.9.3))
|
||||||
'@vercel/analytics':
|
'@vercel/analytics':
|
||||||
specifier: catalog:tooling
|
specifier: catalog:tooling
|
||||||
version: 1.6.1(@sveltejs/kit@2.50.1(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.48.4)(vite@7.3.1(@types/node@24.10.9)(yaml@2.8.2)))(svelte@5.48.4)(typescript@5.9.3)(vite@7.3.1(@types/node@24.10.9)(yaml@2.8.2)))(react@18.3.1)(svelte@5.48.4)
|
version: 2.0.1(@sveltejs/kit@2.50.1(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.48.4)(vite@7.3.1(@types/node@24.10.9)(yaml@2.8.2)))(svelte@5.48.4)(typescript@5.9.3)(vite@7.3.1(@types/node@24.10.9)(yaml@2.8.2)))(react@18.3.1)(svelte@5.48.4)
|
||||||
tmcp:
|
tmcp:
|
||||||
specifier: catalog:tmcp
|
specifier: catalog:tmcp
|
||||||
version: 1.19.2(typescript@5.9.3)
|
version: 1.19.2(typescript@5.9.3)
|
||||||
@@ -2171,12 +2171,13 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
valibot: ^1.2.0
|
valibot: ^1.2.0
|
||||||
|
|
||||||
'@vercel/analytics@1.6.1':
|
'@vercel/analytics@2.0.1':
|
||||||
resolution: {integrity: sha512-oH9He/bEM+6oKlv3chWuOOcp8Y6fo6/PSro8hEkgCW3pu9/OiCXiUpRUogDh3Fs3LH2sosDrx8CxeOLBEE+afg==}
|
resolution: {integrity: sha512-MTQG6V9qQrt1tsDeF+2Uoo5aPjqbVPys1xvnIftXSJYG2SrwXRHnqEvVoYID7BTruDz4lCd2Z7rM1BdkUehk2g==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@remix-run/react': ^2
|
'@remix-run/react': ^2
|
||||||
'@sveltejs/kit': ^1 || ^2
|
'@sveltejs/kit': ^1 || ^2
|
||||||
next: '>= 13'
|
next: '>= 13'
|
||||||
|
nuxt: '>= 3'
|
||||||
react: ^18 || ^19 || ^19.0.0-rc
|
react: ^18 || ^19 || ^19.0.0-rc
|
||||||
svelte: '>= 4'
|
svelte: '>= 4'
|
||||||
vue: ^3
|
vue: ^3
|
||||||
@@ -2188,6 +2189,8 @@ packages:
|
|||||||
optional: true
|
optional: true
|
||||||
next:
|
next:
|
||||||
optional: true
|
optional: true
|
||||||
|
nuxt:
|
||||||
|
optional: true
|
||||||
react:
|
react:
|
||||||
optional: true
|
optional: true
|
||||||
svelte:
|
svelte:
|
||||||
@@ -4179,6 +4182,7 @@ packages:
|
|||||||
tar@7.5.7:
|
tar@7.5.7:
|
||||||
resolution: {integrity: sha512-fov56fJiRuThVFXD6o6/Q354S7pnWMJIVlDBYijsTNx6jKSE4pvrDTs6lUnmGvNyfJwFQQwWy3owKz1ucIhveQ==}
|
resolution: {integrity: sha512-fov56fJiRuThVFXD6o6/Q354S7pnWMJIVlDBYijsTNx6jKSE4pvrDTs6lUnmGvNyfJwFQQwWy3owKz1ucIhveQ==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
|
deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
|
||||||
|
|
||||||
term-size@2.2.1:
|
term-size@2.2.1:
|
||||||
resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==}
|
resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==}
|
||||||
@@ -6169,7 +6173,7 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
valibot: 1.2.0(typescript@5.9.3)
|
valibot: 1.2.0(typescript@5.9.3)
|
||||||
|
|
||||||
'@vercel/analytics@1.6.1(@sveltejs/kit@2.50.1(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.48.4)(vite@7.3.1(@types/node@24.10.9)(yaml@2.8.2)))(svelte@5.48.4)(typescript@5.9.3)(vite@7.3.1(@types/node@24.10.9)(yaml@2.8.2)))(react@18.3.1)(svelte@5.48.4)':
|
'@vercel/analytics@2.0.1(@sveltejs/kit@2.50.1(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.48.4)(vite@7.3.1(@types/node@24.10.9)(yaml@2.8.2)))(svelte@5.48.4)(typescript@5.9.3)(vite@7.3.1(@types/node@24.10.9)(yaml@2.8.2)))(react@18.3.1)(svelte@5.48.4)':
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@sveltejs/kit': 2.50.1(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.48.4)(vite@7.3.1(@types/node@24.10.9)(yaml@2.8.2)))(svelte@5.48.4)(typescript@5.9.3)(vite@7.3.1(@types/node@24.10.9)(yaml@2.8.2))
|
'@sveltejs/kit': 2.50.1(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.48.4)(vite@7.3.1(@types/node@24.10.9)(yaml@2.8.2)))(svelte@5.48.4)(typescript@5.9.3)(vite@7.3.1(@types/node@24.10.9)(yaml@2.8.2))
|
||||||
react: 18.3.1
|
react: 18.3.1
|
||||||
@@ -6842,17 +6846,16 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
eslint-module-utils@2.12.1(@typescript-eslint/parser@8.54.0(eslint@9.39.2)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.2):
|
eslint-module-utils@2.12.1(eslint-import-resolver-node@0.3.9)(eslint@9.39.2):
|
||||||
dependencies:
|
dependencies:
|
||||||
debug: 3.2.7
|
debug: 3.2.7
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@typescript-eslint/parser': 8.54.0(eslint@9.39.2)(typescript@5.9.3)
|
|
||||||
eslint: 9.39.2
|
eslint: 9.39.2
|
||||||
eslint-import-resolver-node: 0.3.9
|
eslint-import-resolver-node: 0.3.9
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.54.0(eslint@9.39.2)(typescript@5.9.3))(eslint@9.39.2):
|
eslint-plugin-import@2.32.0(eslint@9.39.2):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@rtsao/scc': 1.1.0
|
'@rtsao/scc': 1.1.0
|
||||||
array-includes: 3.1.9
|
array-includes: 3.1.9
|
||||||
@@ -6863,7 +6866,7 @@ snapshots:
|
|||||||
doctrine: 2.1.0
|
doctrine: 2.1.0
|
||||||
eslint: 9.39.2
|
eslint: 9.39.2
|
||||||
eslint-import-resolver-node: 0.3.9
|
eslint-import-resolver-node: 0.3.9
|
||||||
eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.54.0(eslint@9.39.2)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.2)
|
eslint-module-utils: 2.12.1(eslint-import-resolver-node@0.3.9)(eslint@9.39.2)
|
||||||
hasown: 2.0.2
|
hasown: 2.0.2
|
||||||
is-core-module: 2.16.1
|
is-core-module: 2.16.1
|
||||||
is-glob: 4.0.3
|
is-glob: 4.0.3
|
||||||
@@ -6874,8 +6877,6 @@ snapshots:
|
|||||||
semver: 6.3.1
|
semver: 6.3.1
|
||||||
string.prototype.trimend: 1.0.9
|
string.prototype.trimend: 1.0.9
|
||||||
tsconfig-paths: 3.15.0
|
tsconfig-paths: 3.15.0
|
||||||
optionalDependencies:
|
|
||||||
'@typescript-eslint/parser': 8.54.0(eslint@9.39.2)(typescript@5.9.3)
|
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- eslint-import-resolver-typescript
|
- eslint-import-resolver-typescript
|
||||||
- eslint-import-resolver-webpack
|
- eslint-import-resolver-webpack
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ catalogs:
|
|||||||
'@types/estree': ^1.0.8
|
'@types/estree': ^1.0.8
|
||||||
'@types/node': ^24.3.1
|
'@types/node': ^24.3.1
|
||||||
'@valibot/to-json-schema': ^1.5.0
|
'@valibot/to-json-schema': ^1.5.0
|
||||||
'@vercel/analytics': ^1.5.0
|
'@vercel/analytics': ^2.0.0
|
||||||
dotenv: ^17.2.3
|
dotenv: ^17.2.3
|
||||||
node-resolve-ts: ^1.0.2
|
node-resolve-ts: ^1.0.2
|
||||||
publint: ^0.3.13
|
publint: ^0.3.13
|
||||||
|
|||||||
@@ -37,7 +37,77 @@ async function sync_agents_md() {
|
|||||||
console.log('Synced AGENTS.md to opencode package and documentation');
|
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_skills();
|
||||||
await sync_agents_md();
|
await sync_agents_md();
|
||||||
|
await sync_agents();
|
||||||
|
|
||||||
console.log('OpenCode plugin sync complete');
|
console.log('OpenCode plugin sync complete');
|
||||||
|
|||||||
@@ -18,9 +18,11 @@ ${module.docs_description}
|
|||||||
<details>
|
<details>
|
||||||
<summary>Copy the prompt</summary>
|
<summary>Copy the prompt</summary>
|
||||||
|
|
||||||
\`\`\`md
|
<!-- prettier-ignore-start -->
|
||||||
|
\`\`\`\`markdown
|
||||||
${await module.generate_for_docs()}
|
${await module.generate_for_docs()}
|
||||||
\`\`\`
|
\`\`\`\`
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ description: Specialized Svelte 5 code editor. MUST BE USED PROACTIVELY when cre
|
|||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
If the MCP tools are not available you can use the `svelte-code-editor` skill to learn how to use the `@sveltejs/mcp` cli to access the same tools.
|
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.
|
||||||
|
|
||||||
If the skill is not available you can run `npx @sveltejs/mcp@latest -y --help` to learn how to use it.
|
If the skill is not available you can run `npx @sveltejs/mcp@latest -y --help` to learn how to use it.
|
||||||
|
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ The CSS in a component's `<style>` is scoped to that component. If a parent comp
|
|||||||
</style>
|
</style>
|
||||||
```
|
```
|
||||||
|
|
||||||
If this impossible (for example, the child component comes from a library) you can use `:global` to override styles:
|
If this is impossible (for example, the child component comes from a library) you can use `:global` to override styles:
|
||||||
|
|
||||||
```svelte
|
```svelte
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
Reference in New Issue
Block a user