Compare commits

...

36 Commits

Author SHA1 Message Date
paoloricciuti
cb9764c234 docs: add link to CLAUDE.md and AGENTS.md docs 2025-10-08 17:22:15 +02:00
paoloricciuti
73d7625b3c chore: changesets 2025-10-07 21:34:19 +02:00
Paolo Ricciuti
c7060c8bdb Merge pull request #20 from sveltejs/attachments-autofixer 2025-10-07 21:31:50 +02:00
Paolo Ricciuti
ef2d569934 Merge pull request #26 from sveltejs/function-call-in-effect 2025-10-07 21:31:21 +02:00
Paolo Ricciuti
7ba57b45ae Merge pull request #52 from theetherGit/zed-config 2025-10-07 12:04:00 +02:00
Paolo Ricciuti
fe393bf480 docs: remove command shortcut 2025-10-07 11:59:21 +02:00
theetherGit
a63deba99d chore: Lint 2025-10-07 15:05:36 +05:30
Paolo Ricciuti
668a2e4481 Merge pull request #51 from sveltejs/renovate/all-minor-patch 2025-10-07 10:23:08 +02:00
Shivam Meena
04c82875f3 Add MCP to zed guide 2025-10-07 12:12:05 +05:30
renovate[bot]
84601f9ab0 chore(deps): update pnpm to v10.18.1 2025-10-06 14:34:35 +00:00
Paolo Ricciuti
e01a050017 Merge pull request #50 from sveltejs/changeset-release/main 2025-10-06 12:36:23 +02:00
github-actions[bot]
5920f7482f Version Packages 2025-10-06 10:30:53 +00:00
Paolo Ricciuti
fa90a2be8d Merge pull request #49 from sveltejs/allow-ts-modules 2025-10-06 12:30:23 +02:00
paoloricciuti
73bf0c3782 fix: allow TS .svelte.ts modules 2025-10-06 12:13:22 +02:00
Paolo Ricciuti
8785ad224c Merge pull request #40 from sveltejs/changeset-release/main 2025-10-05 11:24:27 +02:00
github-actions[bot]
75e676d928 Version Packages 2025-10-04 22:54:37 +00:00
Paolo Ricciuti
5b16bdd80b Merge pull request #41 from 43081j/effect-pre-assign
fix: check effect.pre in assign-in-effect
2025-10-05 00:54:12 +02:00
James Garbutt
f3ee4ed59c chore: run format 2025-10-04 20:12:47 +01:00
paoloricciuti
725f785766 chore: changeset 2025-10-04 16:50:04 +02:00
paoloricciuti
485e60e245 fix: change title names to allow claude code to invoke the prompt 2025-10-04 16:49:23 +02:00
Paolo Ricciuti
480bfca557 Merge pull request #38 from sveltejs/renovate/actions-setup-node-5.x 2025-10-04 16:40:42 +02:00
renovate[bot]
06f9fc6d63 chore(deps): update actions/setup-node action to v5 2025-10-04 14:39:44 +00:00
Paolo Ricciuti
f1f85d2445 Merge pull request #33 from sveltejs/renovate/actions-checkout-5.x 2025-10-04 16:39:20 +02:00
renovate[bot]
b9c0a011e2 chore(deps): update actions/checkout action to v5 2025-10-04 14:37:40 +00:00
Paolo Ricciuti
b92dd95dee Merge pull request #32 from sveltejs/renovate/all-minor-patch 2025-10-04 16:37:15 +02:00
Paolo Ricciuti
99537cfa25 chore: add changesets 2025-10-04 16:34:43 +02:00
James Garbutt
f93a6cee60 fix: check effect.pre in assign-in-effect
It seems like the intention here was to check `$effect` _and_
`$effect.pre`, but the condition (`in_effect`) was filtering those out.
The `is_rune` helper already does the same checks, so we can just remove
the ones here and delegate to that.
2025-10-04 12:18:08 +01:00
renovate[bot]
e8989db548 chore(deps): update all non-major dependencies 2025-10-04 07:55:47 +00:00
paoloricciuti
cb316c5b3e fix: enable doc tools 2025-10-04 09:54:14 +02:00
Paolo Ricciuti
7c762109b6 Merge pull request #39 from sveltejs/llms-txt 2025-10-04 01:58:09 +02:00
paoloricciuti
8483bd672d feat: add autofixer to tell the LLM to check if some function called in effect is assigning state 2025-09-26 13:04:11 +02:00
paoloricciuti
8414ffbcc8 fix: move attachments fixer 2025-09-23 23:05:53 +02:00
paoloricciuti
5798b50ceb Merge branch 'main' into attachments-autofixer 2025-09-23 23:04:38 +02:00
paoloricciuti
e560932211 Merge branch 'main' into attachments-autofixer 2025-09-23 23:03:13 +02:00
paoloricciuti
9504e6bac9 feat: autofixer action -> attachment 2025-09-23 00:49:09 +02:00
paoloricciuti
7086e8e55f feat: add bind:this -> attachment autofixer 2025-09-23 00:17:36 +02:00
25 changed files with 642 additions and 464 deletions

View File

@@ -0,0 +1,5 @@
---
'@sveltejs/mcp': patch
---
feat: add autofixer to tell the LLM to check if some function called in effect is assigning state #26

View File

@@ -1,5 +0,0 @@
---
'@sveltejs/mcp': patch
---
feat: `use_cases` documentation metadata

View File

@@ -0,0 +1,5 @@
---
'@sveltejs/mcp': patch
---
feat: add bind:this -> attachment and action -> attachment autofixer #20

View File

@@ -13,15 +13,15 @@ jobs:
steps:
- name: Checkout Repository
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 10.17.1
version: 10.18.1
- name: Setup Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@v5
with:
node-version: '22'
cache: 'pnpm'

View File

@@ -13,15 +13,15 @@ jobs:
steps:
- name: Checkout Repository
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 10.17.1
version: 10.18.1
- name: Setup Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@v5
with:
node-version: '22'
cache: 'pnpm'

View File

@@ -13,15 +13,15 @@ jobs:
steps:
- name: Checkout Repository
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 10.17.1
version: 10.18.1
- name: Setup Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@v5
with:
node-version: '22'
cache: 'pnpm'

View File

@@ -39,15 +39,15 @@
"devDependencies": {
"@eslint/compat": "^1.3.2",
"@eslint/js": "^9.36.0",
"@libsql/client": "^0.14.0",
"@modelcontextprotocol/inspector": "^0.16.7",
"@libsql/client": "^0.15.0",
"@modelcontextprotocol/inspector": "^0.17.0",
"@sveltejs/adapter-vercel": "^5.6.3",
"@sveltejs/kit": "^2.22.0",
"@sveltejs/vite-plugin-svelte": "^6.0.0",
"@types/node": "^24.3.1",
"@typescript-eslint/parser": "^8.44.0",
"drizzle-kit": "^0.30.2",
"drizzle-orm": "^0.40.0",
"drizzle-kit": "^0.31.0",
"drizzle-orm": "^0.44.0",
"eslint-config-prettier": "^10.0.1",
"eslint-plugin-svelte": "^3.12.3",
"globals": "^16.0.0",

View File

@@ -13,7 +13,7 @@ The setup varies based on the version of the MCP you prefer — remote or local
## Usage
To get the most out of the MCP server we recommend including the following prompt in your `AGENTS.md` (or `CLAUDE.md`, if using Claude Code). This will tell the LLM which tools are available and when it's appropriate to use them.
To get the most out of the MCP server we recommend including the following prompt in your [`AGENTS.md`](https://agents.md) (or [`CLAUDE.md`](https://docs.claude.com/en/docs/claude-code/memory#claude-md-imports), if using Claude Code). This will tell the LLM which tools are available and when it's appropriate to use them.
```md
You are able to use the Svelte MCP server, where you have access to comprehensive Svelte 5 and SvelteKit documentation. Here's how to use the available tools effectively:

View File

@@ -108,6 +108,25 @@ It will open a file with your MCP servers where you can add the following config
}
```
## Zed
- Open the command palette
- Search and select "agent:open settings"
- In settings panel look for `Model Context Protocol (MCP) Servers`
- Click on "Add Server"
- Select: "Add Custom Server"
It will open a popup with MCP server config where you can add the following configuration:
```json
{
"svelte": {
"command": "npx",
"args": ["-y", "@sveltejs/mcp"]
}
}
```
## Other clients
If we didn't include the MCP client you are using, refer to their documentation for `stdio` servers and use `npx` as the command and `-y @sveltejs/mcp` as the arguments.

View File

@@ -3,7 +3,7 @@
"version": "0.0.1",
"description": "The official Svelte MCP server implementation",
"type": "module",
"packageManager": "pnpm@10.17.1",
"packageManager": "pnpm@10.18.1",
"scripts": {
"build": "pnpm -r run build",
"dev": "pnpm --filter @sveltejs/mcp-remote run dev",
@@ -31,7 +31,7 @@
"@changesets/cli": "^2.29.7",
"@eslint/compat": "^1.3.2",
"@eslint/js": "^9.36.0",
"@modelcontextprotocol/inspector": "^0.16.7",
"@modelcontextprotocol/inspector": "^0.17.0",
"@svitejs/changesets-changelog-github-compact": "^1.2.0",
"eslint": "^9.36.0",
"eslint-config-prettier": "^10.0.1",

View File

@@ -14,6 +14,6 @@
"license": "ISC",
"type": "module",
"dependencies": {
"drizzle-orm": "^0.40.1"
"drizzle-orm": "^0.44.0"
}
}

View File

@@ -17,7 +17,7 @@
".": "./src/index.ts"
},
"peerDependencies": {
"drizzle-orm": "^0.40.0"
"drizzle-orm": "^0.44.0"
},
"dependencies": {
"@sveltejs/mcp-schema": "workspace:^",
@@ -28,6 +28,7 @@
"svelte": "^5.39.2",
"svelte-eslint-parser": "^1.3.2",
"tmcp": "^1.13.0",
"ts-blank-space": "^0.6.2",
"typescript-eslint": "^8.44.0",
"valibot": "^1.1.0",
"vitest": "^3.2.4",
@@ -35,10 +36,10 @@
},
"devDependencies": {
"@anthropic-ai/sdk": "^0.65.0",
"dotenv": "^17.2.3",
"@sveltejs/kit": "^2.42.2",
"@types/eslint-scope": "^8.3.2",
"@types/estree": "^1.0.8",
"@typescript-eslint/types": "^8.44.0"
"@typescript-eslint/types": "^8.44.0",
"dotenv": "^17.2.3"
}
}

View File

@@ -61,7 +61,7 @@ describe('add_autofixers_issues', () => {
<script>
const count = ${init}(0);
</script>
<button onclick={() => count = 43}>Increment</button>
`);
@@ -74,7 +74,7 @@ describe('add_autofixers_issues', () => {
const content = run_autofixers_on_code(`
<script>
const count = 0;
$effect(() => {
count = 43;
});
@@ -89,7 +89,7 @@ describe('add_autofixers_issues', () => {
const content = run_autofixers_on_code(`
<script>
let count = ${init}(0);
$effect(() => {
count++;
});
@@ -105,7 +105,7 @@ describe('add_autofixers_issues', () => {
const content = run_autofixers_on_code(`
<script>
let count = ${init}({ value: 0 });
$effect(() => {
count.value = 42;
});
@@ -116,6 +116,52 @@ describe('add_autofixers_issues', () => {
'The stateful variable "count" is assigned inside an $effect which is generally consider a malpractice. Consider using $derived if possible.',
);
});
it(`should add a suggestion for variables that are mutated within an effect.pre`, () => {
const content = run_autofixers_on_code(`
<script>
let count = ${init}({ value: 0 });
$effect.pre(() => {
count.value = 42;
});
</script>
`);
expect(content.suggestions).toContain(
'The stateful variable "count" is assigned inside an $effect which is generally consider a malpractice. Consider using $derived if possible.',
);
});
});
it('should add a suggestion when calling a function inside an effect', () => {
const content = run_autofixers_on_code(`
<script>
import { fetch_data } from './data.js';
$effect(() => {
fetch_data();
});
</script>`);
expect(content.suggestions.length).toBeGreaterThanOrEqual(1);
expect(content.suggestions).toContain(
`You are calling the function \`fetch_data\` inside an $effect. Please check if the function is reassigning a stateful variable because that's considered malpractice and check if it could use \`$derived\` instead. Ignore this suggestion if you are sure this function is not assigning any stateful variable or if you can't check if it does.`,
);
});
it('should add a suggestion when calling a function inside an effect (with non identifier callee)', () => {
const content = run_autofixers_on_code(`
<script>
import { fetch_data } from './data.js';
$effect(() => {
fetch_data.fetch();
});
</script>`);
expect(content.suggestions.length).toBeGreaterThanOrEqual(1);
expect(content.suggestions).toContain(
`You are calling a function inside an $effect. Please check if the function is reassigning a stateful variable because that's considered malpractice and check if it could use \`$derived\` instead. Ignore this suggestion if you are sure this function is not assigning any stateful variable or if you can't check if it does.`,
);
});
});
@@ -468,4 +514,177 @@ describe('add_autofixers_issues', () => {
);
});
});
describe('suggest_attachments', () => {
describe('bind:this', () => {
it('should add suggestions when using bind:this on an element', () => {
const content = run_autofixers_on_code(`
<script>
let a = $state();
</script>
<a bind:this={a} />`);
expect(content.suggestions.length).toBeGreaterThanOrEqual(1);
expect(content.suggestions).toContain(
'The usage of `bind:this` can often be replaced with an easier to read `action` or even better an `attachment`. Consider using the latter if possible.',
);
});
it('should not add suggestions when using bind:this on a component', () => {
const content = run_autofixers_on_code(`
<script>
import Child from './Child.svelte';
let a = $state();
</script>
<Child bind:this={a} />`);
expect(content.suggestions).not.toContain(
'The usage of `bind:this` can often be replaced with an easier to read `action` or even better an `attachment`. Consider using the latter if possible.',
);
});
it('should not add suggestions when using bind:this on a component nested in an element', () => {
const content = run_autofixers_on_code(`
<script>
import Child from './Child.svelte';
let a = $state();
</script>
<div>
<Child bind:this={a} />
</div>`);
expect(content.suggestions).not.toContain(
'The usage of `bind:this` can often be replaced with an easier to read `action` or even better an `attachment`. Consider using the latter if possible.',
);
});
it('should add suggestions but not suggest attachments when using bind:this on an element and the desired svelte version is 4', () => {
const content = run_autofixers_on_code(
`
<script>
let a;
</script>
<a bind:this={a} />`,
4,
);
expect(content.suggestions.length).toBeGreaterThanOrEqual(1);
expect(content.suggestions).toContain(
'The usage of `bind:this` can often be replaced with an easier to read `action`. Consider using the latter if possible.',
);
});
});
describe('use:', () => {
it('should add suggestions when using use: on an element and the action is declared as a function', () => {
const content = run_autofixers_on_code(
`<script>
function my_action(node) {
// do something with the node
}
</script>
<a use:my_action />`,
);
expect(content.suggestions.length).toBeGreaterThanOrEqual(1);
expect(content.suggestions).toContain(
'Consider using an `attachment` instead of an `action` for "my_action".',
);
});
it('should add suggestions when using use: on an element and the action is declared as a variable', () => {
const content = run_autofixers_on_code(
`<script>
const my_action = (node) => {
// do something with the node
}
</script>
<a use:my_action />`,
);
expect(content.suggestions.length).toBeGreaterThanOrEqual(1);
expect(content.suggestions).toContain(
'Consider using an `attachment` instead of an `action` for "my_action".',
);
});
it('should add suggestions when using use: on an element and the action is declared as an object', () => {
const content = run_autofixers_on_code(
`<script>
const my_action = {
action: (node) => {
// do something with the node
}
};
</script>
<a use:my_action.action />`,
);
expect(content.suggestions.length).toBeGreaterThanOrEqual(1);
expect(content.suggestions).toContain(
'Consider using an `attachment` instead of an `action` for "my_action".',
);
});
it('should not add suggestions when using use: on an element and the desired svelte version is 4', () => {
const content = run_autofixers_on_code(
`<script>
function my_action(node) {
// do something with the node
}
</script>
<a use:my_action />`,
4,
);
expect(content.suggestions).not.toContain(
'Consider using an `attachment` instead of an `action` for "my_action".',
);
});
it('should not add suggestions when using use: on an element and the action comes from an import', () => {
const content = run_autofixers_on_code(
`<script>
import { my_action } from './actions.js';
</script>
<a use:my_action />`,
);
expect(content.suggestions).not.toContain(
'Consider using an `attachment` instead of an `action` for "my_action".',
);
});
it('should not add suggestions when using use: on an element and the action comes from the props', () => {
const content = run_autofixers_on_code(
`<script>
const { my_action } = $props();
</script>
<a use:my_action />`,
);
expect(content.suggestions).not.toContain(
'Consider using an `attachment` instead of an `action` for "my_action".',
);
});
it('should not add suggestions when using use: on an element and the action comes from a global variable', () => {
const content = run_autofixers_on_code(`<a use:my_action />`);
expect(content.suggestions).not.toContain(
'Consider using an `attachment` instead of an `action` for "my_action".',
);
});
});
});
});

View File

@@ -1,4 +1,6 @@
import { compile } from 'svelte/compiler';
import { compile as compile_component, compileModule } from 'svelte/compiler';
import { extname } from 'path';
import ts from 'ts-blank-space';
export function add_compile_issues(
content: { issues: string[]; suggestions: string[] },
@@ -6,6 +8,21 @@ export function add_compile_issues(
desired_svelte_version: number,
filename = 'Component.svelte',
) {
let compile = compile_component;
const extension = extname(filename);
if (extension !== '.svelte') {
compile = compileModule;
// compile module doesn't accept .ts files so we need to transpile them first with ts-blank-space
// a fast and lightweight typescript transpiler that can strips types replacing them with white spaces
// so the code positions are not affected
if (extension === '.ts') {
code = ts(code, (node) => {
content.issues.push(
`The provided file is a module but it contains invalid TypeScript code: ${node.getText()} at ${node.getStart()}`,
);
});
}
}
const compilation_result = compile(code, {
filename: filename || 'Component.svelte',
generate: false,

View File

@@ -12,7 +12,7 @@ function base_config(svelte_config: Config): ESLint.Options['baseConfig'] {
return [
...svelte.configs.recommended,
{
files: ['*.svelte'],
files: ['*.svelte', '*.svelte.ts', '*.svelte.js'],
rules: {
'no-self-assign': 'warn',
'svelte/infinite-reactive-loop': 'warn',

View File

@@ -1,4 +1,10 @@
import type { AssignmentExpression, Identifier, Node, UpdateExpression } from 'estree';
import type {
AssignmentExpression,
CallExpression,
Identifier,
Node,
UpdateExpression,
} from 'estree';
import type { Autofixer, AutofixerState } from './index.js';
import { left_most_id } from '../ast/utils.js';
import type { AST } from 'svelte-eslint-parser';
@@ -11,25 +17,17 @@ function run_if_in_effect(
) {
const in_effect = path.findLast(
(node) =>
node.type === 'CallExpression' &&
node.callee.type === 'Identifier' &&
node.callee.name === '$effect',
node.type === 'CallExpression' && state.parsed.is_rune(node, ['$effect', '$effect.pre']),
);
if (
in_effect &&
in_effect.type === 'CallExpression' &&
(in_effect.callee.type === 'Identifier' || in_effect.callee.type === 'MemberExpression')
) {
if (state.parsed.is_rune(in_effect, ['$effect', '$effect.pre'])) {
to_run();
}
if (in_effect) {
to_run();
}
}
function visitor(
function assign_or_update_visitor(
node: UpdateExpression | AssignmentExpression,
{ state, path }: Context<Node | AST.SvelteNode, AutofixerState>,
{ state, path, next }: Context<Node | AST.SvelteNode, AutofixerState>,
) {
run_if_in_effect(path, state, () => {
function check_if_stateful_id(id: Identifier) {
@@ -58,9 +56,25 @@ function visitor(
}
}
});
next();
}
function call_expression_visitor(
node: CallExpression,
{ state, path, next }: Context<Node | AST.SvelteNode, AutofixerState>,
) {
run_if_in_effect(path, state, () => {
const function_name =
node.callee.type === 'Identifier' ? `the function \`${node.callee.name}\`` : 'a function';
state.output.suggestions.push(
`You are calling ${function_name} inside an $effect. Please check if the function is reassigning a stateful variable because that's considered malpractice and check if it could use \`$derived\` instead. Ignore this suggestion if you are sure this function is not assigning any stateful variable or if you can't check if it does.`,
);
});
next();
}
export const assign_in_effect: Autofixer = {
UpdateExpression: visitor,
AssignmentExpression: visitor,
UpdateExpression: assign_or_update_visitor,
AssignmentExpression: assign_or_update_visitor,
CallExpression: call_expression_visitor,
};

View File

@@ -16,3 +16,4 @@ export * from './wrong-property-access-state.js';
export * from './imported-runes.js';
export * from './derived-with-function.js';
export * from './use-runes-instead-of-store.js';
export * from './suggest-attachments.js';

View File

@@ -0,0 +1,47 @@
import type { Identifier } from 'estree';
import type { Autofixer } from './index.js';
import { left_most_id } from '../ast/utils.js';
export const suggest_attachments: Autofixer = {
SvelteDirective(node, { state, next, path }) {
if (node.kind === 'Binding' && node.key.name.name === 'this') {
const parent_element = path.findLast((p) => p.type === 'SvelteElement');
if (parent_element?.kind === 'html' && parent_element.startTag.attributes.includes(node)) {
let better_an_attachment = ` or even better an \`attachment\``;
if (state.desired_svelte_version === 4) {
better_an_attachment = ``;
}
state.output.suggestions.push(
`The usage of \`bind:this\` can often be replaced with an easier to read \`action\`${better_an_attachment}. Consider using the latter if possible.`,
);
}
} else if (node.kind === 'Action' && state.desired_svelte_version === 5) {
let id: Identifier | null = null;
if (node.key.name.type === 'Identifier') {
id = node.key.name;
} else if (node.key.name.type === 'MemberExpression') {
id = left_most_id(node.key.name);
}
if (id) {
const reference = state.parsed.find_reference_by_id(id);
const definition = reference?.resolved?.defs[0];
console.log(definition);
if (
definition &&
(definition.type === 'Variable' ||
!(definition.type === 'ImportBinding' || definition.type === 'Parameter')) &&
!(
definition.type === 'Variable' &&
definition.node.init?.type === 'CallExpression' &&
state.parsed.is_rune(definition.node.init, ['$props'])
)
) {
state.output.suggestions.push(
`Consider using an \`attachment\` instead of an \`action\` for "${id.name}".`,
);
}
}
}
next();
},
};

View File

@@ -6,7 +6,7 @@ export function setup_svelte_task(server: SvelteMcp) {
server.prompt(
{
name: 'svelte-task-prompt',
title: 'Svelte Task Prompt',
title: 'Svelte-Task-Prompt',
description:
'Use this Prompt to ask for any svelte related task. It will automatically instruct the LLM on how to best use the autofixer and how to query for documentation pages.',
schema: v.object({

View File

@@ -6,7 +6,7 @@ export async function list_sections(server: SvelteMcp) {
server.template(
{
name: 'Svelte Doc Section',
name: 'Svelte-Doc-Section',
description: 'A single documentation section',
list() {
return sections.map((section) => {

View File

@@ -7,7 +7,6 @@ export function get_documentation(server: SvelteMcp) {
server.tool(
{
name: 'get-documentation',
enabled: () => false,
description:
'Retrieves full documentation content for Svelte 5 or SvelteKit sections. Supports flexible search by title (e.g., "$state", "routing") or file path (e.g., "cli/overview"). Can accept a single section name or an array of sections. Before running this, make sure to analyze the users query, as well as the output from list-sections (which should be called first). Then ask for ALL relevant sections the user might require. For example, if the user asks to build anything interactive, you will need to fetch all relevant runes, and so on.',
schema: v.object({

View File

@@ -6,7 +6,6 @@ export function list_sections(server: SvelteMcp) {
server.tool(
{
name: 'list-sections',
enabled: () => false,
description:
'Lists all available Svelte 5 and SvelteKit documentation sections in a structured format. Each section includes a "use_cases" field that describes WHEN this documentation would be useful. You should carefully analyze the use_cases field to determine which sections are relevant for the user\'s query. The use_cases contain comma-separated keywords describing project types (e.g., "e-commerce", "blog"), features (e.g., "authentication", "forms"), components (e.g., "slider", "modal"), development stages (e.g., "deployment", "testing"), or "always" for fundamental concepts. Match these use_cases against the user\'s intent - for example, if building an e-commerce site, fetch sections with use_cases containing "e-commerce", "product listings", "shopping cart", etc. If building a slider, look for "slider", "carousel", "animation", etc. Returns sections as "* title: [section_title], use_cases: [use_cases], path: [file_path]". Always run list-sections FIRST for any Svelte query, then analyze ALL use_cases to identify relevant sections, and finally use get_documentation to fetch ALL relevant sections at once.',
},

View File

@@ -1,5 +1,23 @@
# @sveltejs/mcp
## 0.0.4
### Patch Changes
- fix: allow TS `.svelte.ts` modules ([#49](https://github.com/sveltejs/mcp/pull/49))
## 0.0.3
### Patch Changes
- fix: check effect.pre in assign-in-effect ([#41](https://github.com/sveltejs/mcp/pull/41))
- feat: `use_cases` documentation metadata ([#29](https://github.com/sveltejs/mcp/pull/29))
- fix: change title names to allow for claude code to use the prompt ([`725f785`](https://github.com/sveltejs/mcp/commit/725f785766d04e9ed810a7c3f6bcfdb2e2b8234c))
- fix: enable doc tools ([`cb316c5`](https://github.com/sveltejs/mcp/commit/cb316c5b3ebc712946969d2d57236d159e796d58))
## 0.0.2
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@sveltejs/mcp",
"version": "0.0.2",
"version": "0.0.4",
"type": "module",
"license": "MIT",
"homepage": "https://github.com/sveltejs/mcp#readme",
@@ -33,7 +33,7 @@
"@tmcp/transport-stdio": "^0.3.1",
"@types/node": "^22.15.17",
"publint": "^0.3.13",
"tsdown": "^0.11.9",
"tsdown": "^0.15.0",
"typescript": "^5.8.3",
"vitest": "^3.1.3"
},

661
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff