diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 5a362a6..d16f2bc 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -2,8 +2,8 @@ "name": "vue3-best-practices", "description": "A collection of skills for Vue.js development.", "owner": { - "name": "Pythoughts-labs", - "url": "https://github.com/Pythoughts-labs/vue3-best-practices" + "name": "PyModel", + "url": "https://github.com/PyModel/vue3-best-practices" }, "plugins": [ { @@ -39,7 +39,7 @@ { "name": "vue-router-best-practices", "source": "./skills/vue-router-best-practices", - "description": "Vue Router 4 patterns, navigation guards, route params, and route-component lifecycle interactions." + "description": "Vue Router 4/5 patterns, navigation guards, route params, file-based routing, and route-component lifecycle interactions." }, { "name": "vue-testing-best-practices", diff --git a/.github/workflows/eval-smoke.yml b/.github/workflows/eval-smoke.yml new file mode 100644 index 0000000..2f49125 --- /dev/null +++ b/.github/workflows/eval-smoke.yml @@ -0,0 +1,33 @@ +name: Eval smoke + +# Dry-builds every eval scenario (no LLM calls) so boilerplate rot — +# a broken stub, tsconfig, or App.vue shell — fails a PR instead of a paid eval run. +# Only fires when the eval suite or its harness changes. +on: + pull_request: + paths: + - 'evals/**' + - 'package.json' + push: + branches: [dev] + paths: + - 'evals/**' + - 'package.json' + +permissions: + contents: read + +jobs: + dry: + name: Eval dry build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + - uses: pnpm/action-setup@v4 + with: + version: 10 + - uses: actions/setup-node@v6 + with: + node-version: '24' + - name: Dry-build all eval scenarios + run: pnpm eval --all --dry diff --git a/.github/workflows/sync-to-main.yml b/.github/workflows/sync-to-main.yml index 39e6a47..e89c87c 100644 --- a/.github/workflows/sync-to-main.yml +++ b/.github/workflows/sync-to-main.yml @@ -41,15 +41,21 @@ jobs: BRANCH="sync/dev-to-main-$(date +%Y%m%d%H%M%S)" git checkout -b "$BRANCH" - # Create a merge commit, but don't commit yet - git merge --no-ff --no-commit origin/dev + # Create a merge commit, but don't commit yet. + # This is only here to record dev as a second parent — the merge's + # own content is thrown away by the restore below, so conflicts are + # expected and must not fail the step (the shell runs with -e). + git merge --no-ff --no-commit origin/dev || true # Reset everything back to main... git restore --source=ORIG_HEAD --staged --worktree -- . # ...then re-apply only whitelisted paths from dev + # mcp/ must stay in this list: .github/ is synced, so main runs the + # MCP server job, and without mcp/ that job tests a stale tree (old + # package name, old version, unpatched lockfile) and always fails. git restore --source=origin/dev --staged --worktree -- \ - skills/ evals/ package.json .github/ .claude-plugin/ README.md AGENTS.md CLAUDE.md LICENSE + skills/ evals/ mcp/ package.json .github/ .claude-plugin/ README.md AGENTS.md CLAUDE.md LICENSE git add -A if git diff --staged --quiet; then diff --git a/AGENTS.md b/AGENTS.md index a251c33..b6be633 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -10,18 +10,21 @@ | Branch | Purpose | Direct commits | |--------|---------|----------------| -| `main` | Publishing (`npx skills add Pythoughts-labs/vue3-best-practices`) | Forbidden | +| `main` | Publishing (`npx skills add PyModel/vue3-best-practices`) | Forbidden | | `dev` | Development, tests, experiments | Via PR only | ## Development Workflow -After completing any task, run: +After completing any task, run the repo's structure and server checks: ```bash -pnpm typecheck +node --test scripts/validate-skills.test.mjs # skill front matter, references, marketplace +npm --prefix mcp test # MCP server smoke test ``` -This ensures TypeScript types are correct before committing. +There is no root TypeScript project, so there is no root `typecheck` script. +Eval scenarios carry their own `vue-tsc` setup and are type-checked by their own +`pnpm run build` inside the eval run. ## Skill Scopes @@ -31,7 +34,7 @@ This ensures TypeScript types are correct before committing. | **vue-options-api-best-practices** | Vue 3 Options API style (`data()`, `methods`, `this` context). Each rule shows Options API solution only. | | **vue-jsx-best-practices** | JSX syntax in Vue (e.g., `class` vs `className`, JSX plugin config). | | **vue-testing-best-practices** | Testing with Vitest, Vue Test Utils, and Playwright for E2E. | -| **vue-router-best-practices** | Vue Router 4 patterns, navigation guards, route params, and route-component lifecycle interactions. | +| **vue-router-best-practices** | Vue Router 4/5 patterns, navigation guards, route params, file-based routing, and route-component lifecycle interactions. | | **vue-pinia-best-practices** | Pinia stores, state management patterns, store setup, and reactivity with stores. | | **vue-debug-guides** | Debugging and troubleshooting Vue 3: runtime errors, warnings, async error handling, SSR hydration issues. | @@ -250,8 +253,8 @@ pnpm eval computed-vs-methods --dry # Verbose output (keep temp dir, show details) pnpm eval computed-vs-methods --verbose -# Type check evals library -pnpm --filter @vue-skills/evals typecheck +# Validate skill structure (front matter, references, marketplace registration) +node --test scripts/validate-skills.test.mjs ``` **Skip logic:** @@ -273,16 +276,12 @@ pnpm --filter @vue-skills/evals typecheck | Eval | Skill | Tests | |------|-------|-------| -| `computed-vs-methods` | vue-best-practices | Uses computed() for derived data | -| `no-v-if-with-v-for` | vue-best-practices | Separates v-if and v-for | -| `v-for-key-attribute` | vue-best-practices | Uses :key with unique id | -| `testing-vitest` | vue-testing-best-practices | Uses Vitest + Vue Test Utils | -| `testing-async-flushpromises` | vue-testing-best-practices | Uses flushPromises for async | -| `router-param-change` | vue-router-best-practices | Watches route params | -| `pinia-store-destructuring` | vue-pinia-best-practices | Uses storeToRefs | -| `no-arrow-functions-methods` | vue-options-api-best-practices | Regular function syntax | -| `jsx-vue-vs-react` | vue-jsx-best-practices | Uses class not className | -| `create-composable` | vue-best-practices | Creates reusable composable | +| `reactive-props-destructure` | vue-best-practices | Reactive props destructure with defaults | +| `vue-3-5-helpers` | vue-best-practices | Vue 3.5 helpers (useTemplateRef, useId, onWatcherCleanup) | +| `streaming-chat-ui` | vue-ai-apps | Streaming chat with Vercel AI SDK useChat | +| `tool-calling` | vue-ai-apps | Tool calling with useChat | +| `structured-output` | vue-ai-apps | Structured output generation | +| `error-handling-and-abort` | vue-ai-apps | Abort handling and error states in chat UI | ### Full Eval Matrix diff --git a/LICENSE b/LICENSE index 702a757..11f071f 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2026 Pythoughts-labs, Mohamed Elkholy (elkaix) +Copyright (c) 2026 PyModel, Mohamed Elkholy (elkaix) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 82848d5..19116bd 100644 --- a/README.md +++ b/README.md @@ -3,10 +3,12 @@

- CI + CI + skills.sh + npm + npm downloads License: MIT Vue 3.5+ - Skills: 8 MCP server TypeScript PRs welcome @@ -14,7 +16,7 @@

Agent skills that teach AI coding agents current Vue 3 patterns, validated with automated evals.
- Maintained by Pythoughts-labs. + Maintained by PyModel.

@@ -32,14 +34,14 @@ Add the skills to any agent that supports the `skills` registry: ```bash -npx skills add Pythoughts-labs/vue3-best-practices +npx skills add PyModel/vue3-best-practices ``` ### Claude Code marketplace ```bash # Add the marketplace -/plugin marketplace add Pythoughts-labs/vue3-best-practices +/plugin marketplace add PyModel/vue3-best-practices # Install everything at once /plugin install vue-skills-bundle@vue3-best-practices @@ -63,6 +65,14 @@ Without the prefix, triggering depends on how closely the prompt matches a skill For agents that consume MCP instead of the skills registry, [`mcp/`](mcp/) exposes every skill as MCP tools. The agent calls `vue_best_practices` when it detects Vue work, then pulls individual reference files on demand. +The server is published as [`@pymodel/vue-skills-mcp`](https://www.npmjs.com/package/@pymodel/vue-skills-mcp) with the skills bundled, so no clone is needed: + +```bash +claude mcp add vue-skills -- npx -y @pymodel/vue-skills-mcp +``` + +To run it from a local clone instead: + ```bash cd mcp && npm install ``` @@ -129,7 +139,7 @@ claude mcp add vue-skills -- node /mcp/index.mjs |-------|-------------|--------| | **vue-best-practices** | Vue 3 + Composition API + TypeScript | Reactivity, SFC structure, data flow, composables, SSR, performance | | **vue-options-api-best-practices** | Options API (`data()`, `methods`) | `this` context, lifecycle, TypeScript with Options API | -| **vue-router-best-practices** | Vue Router 4 | Navigation guards, route params, route-component lifecycle | +| **vue-router-best-practices** | Vue Router 4/5 | Navigation guards, route params, file-based routing, route-component lifecycle | | **vue-pinia-best-practices** | Pinia state management | Store setup, reactivity, `storeToRefs`, state patterns | | **vue-testing-best-practices** | Component or E2E tests | Vitest, Vue Test Utils, Playwright | | **vue-jsx-best-practices** | JSX in Vue | Syntax differences from React JSX, plugin config | diff --git a/evals/README.md b/evals/README.md index 9fac9d2..52c0890 100644 --- a/evals/README.md +++ b/evals/README.md @@ -29,10 +29,12 @@ Each scenario is a self-contained Vue + Vite + Vitest project: ### Verified vs. requires budget - **Verified:** `--dry` (install + build) passes on all scenarios; arg validation; results.json I/O. + CI runs `pnpm eval --all --dry` (no LLM, no cost) on any PR touching `evals/**`, so stub/boilerplate + rot fails the PR instead of a paid eval run — see `.github/workflows/eval-smoke.yml`. - **Requires API budget + `claude` CLI:** the four LLM tiers (`baseline`, `with-skill`, `with-skill-prompt`, `with-agents-md`). These are billed and user-triggered — not run in CI. - Skill install for the `with-skill*` tiers uses `npx skills add` against - `$VUE_SKILLS_SOURCE` (default `Pythoughts-labs/vue3-best-practices`); override for local setups. + `$VUE_SKILLS_SOURCE` (default `PyModel/vue3-best-practices`); override for local setups. ## Covered references diff --git a/evals/suites/skills/vue-ai-apps/error-handling-and-abort/scenario-1/package.json b/evals/suites/skills/vue-ai-apps/error-handling-and-abort/scenario-1/package.json index e39f24c..04d1272 100644 --- a/evals/suites/skills/vue-ai-apps/error-handling-and-abort/scenario-1/package.json +++ b/evals/suites/skills/vue-ai-apps/error-handling-and-abort/scenario-1/package.json @@ -8,13 +8,13 @@ "test": "vitest run" }, "dependencies": { - "vue": "^3.5.13" + "vue": "^3.5.41" }, "devDependencies": { - "@vitejs/plugin-vue": "^5.2.1", - "typescript": "^5.7.0", - "vite": "^6.0.0", - "vitest": "^3.0.0", - "vue-tsc": "^2.2.0" + "@vitejs/plugin-vue": "^6.0.8", + "typescript": "^5.9.3", + "vite": "^8.2.1", + "vitest": "^4.1.10", + "vue-tsc": "^3.3.10" } } diff --git a/evals/suites/skills/vue-ai-apps/error-handling-and-abort/scenario-2/package.json b/evals/suites/skills/vue-ai-apps/error-handling-and-abort/scenario-2/package.json index 3a200a2..459194f 100644 --- a/evals/suites/skills/vue-ai-apps/error-handling-and-abort/scenario-2/package.json +++ b/evals/suites/skills/vue-ai-apps/error-handling-and-abort/scenario-2/package.json @@ -8,13 +8,13 @@ "test": "vitest run" }, "dependencies": { - "vue": "^3.5.13" + "vue": "^3.5.41" }, "devDependencies": { - "@vitejs/plugin-vue": "^5.2.1", - "typescript": "^5.7.0", - "vite": "^6.0.0", - "vitest": "^3.0.0", - "vue-tsc": "^2.2.0" + "@vitejs/plugin-vue": "^6.0.8", + "typescript": "^5.9.3", + "vite": "^8.2.1", + "vitest": "^4.1.10", + "vue-tsc": "^3.3.10" } } diff --git a/evals/suites/skills/vue-ai-apps/error-handling-and-abort/scenario-3/package.json b/evals/suites/skills/vue-ai-apps/error-handling-and-abort/scenario-3/package.json index 3a3b6ed..5b15067 100644 --- a/evals/suites/skills/vue-ai-apps/error-handling-and-abort/scenario-3/package.json +++ b/evals/suites/skills/vue-ai-apps/error-handling-and-abort/scenario-3/package.json @@ -8,13 +8,13 @@ "test": "vitest run" }, "dependencies": { - "vue": "^3.5.13" + "vue": "^3.5.41" }, "devDependencies": { - "@vitejs/plugin-vue": "^5.2.1", - "typescript": "^5.7.0", - "vite": "^6.0.0", - "vitest": "^3.0.0", - "vue-tsc": "^2.2.0" + "@vitejs/plugin-vue": "^6.0.8", + "typescript": "^5.9.3", + "vite": "^8.2.1", + "vitest": "^4.1.10", + "vue-tsc": "^3.3.10" } } diff --git a/evals/suites/skills/vue-ai-apps/streaming-chat-ui/scenario-1/package.json b/evals/suites/skills/vue-ai-apps/streaming-chat-ui/scenario-1/package.json index 903d8e3..5254950 100644 --- a/evals/suites/skills/vue-ai-apps/streaming-chat-ui/scenario-1/package.json +++ b/evals/suites/skills/vue-ai-apps/streaming-chat-ui/scenario-1/package.json @@ -8,13 +8,13 @@ "test": "vitest run" }, "dependencies": { - "vue": "^3.5.13" + "vue": "^3.5.41" }, "devDependencies": { - "@vitejs/plugin-vue": "^5.2.1", - "typescript": "^5.7.0", - "vite": "^6.0.0", - "vitest": "^3.0.0", - "vue-tsc": "^2.2.0" + "@vitejs/plugin-vue": "^6.0.8", + "typescript": "^5.9.3", + "vite": "^8.2.1", + "vitest": "^4.1.10", + "vue-tsc": "^3.3.10" } } diff --git a/evals/suites/skills/vue-ai-apps/streaming-chat-ui/scenario-2/package.json b/evals/suites/skills/vue-ai-apps/streaming-chat-ui/scenario-2/package.json index e0216f1..c942c96 100644 --- a/evals/suites/skills/vue-ai-apps/streaming-chat-ui/scenario-2/package.json +++ b/evals/suites/skills/vue-ai-apps/streaming-chat-ui/scenario-2/package.json @@ -8,13 +8,13 @@ "test": "vitest run" }, "dependencies": { - "vue": "^3.5.13" + "vue": "^3.5.41" }, "devDependencies": { - "@vitejs/plugin-vue": "^5.2.1", - "typescript": "^5.7.0", - "vite": "^6.0.0", - "vitest": "^3.0.0", - "vue-tsc": "^2.2.0" + "@vitejs/plugin-vue": "^6.0.8", + "typescript": "^5.9.3", + "vite": "^8.2.1", + "vitest": "^4.1.10", + "vue-tsc": "^3.3.10" } } diff --git a/evals/suites/skills/vue-ai-apps/streaming-chat-ui/scenario-3/package.json b/evals/suites/skills/vue-ai-apps/streaming-chat-ui/scenario-3/package.json index 7177ae7..e862221 100644 --- a/evals/suites/skills/vue-ai-apps/streaming-chat-ui/scenario-3/package.json +++ b/evals/suites/skills/vue-ai-apps/streaming-chat-ui/scenario-3/package.json @@ -8,13 +8,13 @@ "test": "vitest run" }, "dependencies": { - "vue": "^3.5.13" + "vue": "^3.5.41" }, "devDependencies": { - "@vitejs/plugin-vue": "^5.2.1", - "typescript": "^5.7.0", - "vite": "^6.0.0", - "vitest": "^3.0.0", - "vue-tsc": "^2.2.0" + "@vitejs/plugin-vue": "^6.0.8", + "typescript": "^5.9.3", + "vite": "^8.2.1", + "vitest": "^4.1.10", + "vue-tsc": "^3.3.10" } } diff --git a/evals/suites/skills/vue-ai-apps/structured-output/scenario-1/package.json b/evals/suites/skills/vue-ai-apps/structured-output/scenario-1/package.json index 3b8d115..aaf720e 100644 --- a/evals/suites/skills/vue-ai-apps/structured-output/scenario-1/package.json +++ b/evals/suites/skills/vue-ai-apps/structured-output/scenario-1/package.json @@ -8,13 +8,13 @@ "test": "vitest run" }, "dependencies": { - "vue": "^3.5.13" + "vue": "^3.5.41" }, "devDependencies": { - "@vitejs/plugin-vue": "^5.2.1", - "typescript": "^5.7.0", - "vite": "^6.0.0", - "vitest": "^3.0.0", - "vue-tsc": "^2.2.0" + "@vitejs/plugin-vue": "^6.0.8", + "typescript": "^5.9.3", + "vite": "^8.2.1", + "vitest": "^4.1.10", + "vue-tsc": "^3.3.10" } } diff --git a/evals/suites/skills/vue-ai-apps/structured-output/scenario-2/package.json b/evals/suites/skills/vue-ai-apps/structured-output/scenario-2/package.json index 544d4fb..cf1e677 100644 --- a/evals/suites/skills/vue-ai-apps/structured-output/scenario-2/package.json +++ b/evals/suites/skills/vue-ai-apps/structured-output/scenario-2/package.json @@ -8,13 +8,13 @@ "test": "vitest run" }, "dependencies": { - "vue": "^3.5.13" + "vue": "^3.5.41" }, "devDependencies": { - "@vitejs/plugin-vue": "^5.2.1", - "typescript": "^5.7.0", - "vite": "^6.0.0", - "vitest": "^3.0.0", - "vue-tsc": "^2.2.0" + "@vitejs/plugin-vue": "^6.0.8", + "typescript": "^5.9.3", + "vite": "^8.2.1", + "vitest": "^4.1.10", + "vue-tsc": "^3.3.10" } } diff --git a/evals/suites/skills/vue-ai-apps/structured-output/scenario-3/package.json b/evals/suites/skills/vue-ai-apps/structured-output/scenario-3/package.json index 53613ab..b875541 100644 --- a/evals/suites/skills/vue-ai-apps/structured-output/scenario-3/package.json +++ b/evals/suites/skills/vue-ai-apps/structured-output/scenario-3/package.json @@ -8,13 +8,13 @@ "test": "vitest run" }, "dependencies": { - "vue": "^3.5.13" + "vue": "^3.5.41" }, "devDependencies": { - "@vitejs/plugin-vue": "^5.2.1", - "typescript": "^5.7.0", - "vite": "^6.0.0", - "vitest": "^3.0.0", - "vue-tsc": "^2.2.0" + "@vitejs/plugin-vue": "^6.0.8", + "typescript": "^5.9.3", + "vite": "^8.2.1", + "vitest": "^4.1.10", + "vue-tsc": "^3.3.10" } } diff --git a/evals/suites/skills/vue-ai-apps/tool-calling/scenario-1/package.json b/evals/suites/skills/vue-ai-apps/tool-calling/scenario-1/package.json index d3bd7dc..85c20d7 100644 --- a/evals/suites/skills/vue-ai-apps/tool-calling/scenario-1/package.json +++ b/evals/suites/skills/vue-ai-apps/tool-calling/scenario-1/package.json @@ -8,13 +8,13 @@ "test": "vitest run" }, "dependencies": { - "vue": "^3.5.13" + "vue": "^3.5.41" }, "devDependencies": { - "@vitejs/plugin-vue": "^5.2.1", - "typescript": "^5.7.0", - "vite": "^6.0.0", - "vitest": "^3.0.0", - "vue-tsc": "^2.2.0" + "@vitejs/plugin-vue": "^6.0.8", + "typescript": "^5.9.3", + "vite": "^8.2.1", + "vitest": "^4.1.10", + "vue-tsc": "^3.3.10" } } diff --git a/evals/suites/skills/vue-ai-apps/tool-calling/scenario-2/package.json b/evals/suites/skills/vue-ai-apps/tool-calling/scenario-2/package.json index 23f6b42..47677da 100644 --- a/evals/suites/skills/vue-ai-apps/tool-calling/scenario-2/package.json +++ b/evals/suites/skills/vue-ai-apps/tool-calling/scenario-2/package.json @@ -8,13 +8,13 @@ "test": "vitest run" }, "dependencies": { - "vue": "^3.5.13" + "vue": "^3.5.41" }, "devDependencies": { - "@vitejs/plugin-vue": "^5.2.1", - "typescript": "^5.7.0", - "vite": "^6.0.0", - "vitest": "^3.0.0", - "vue-tsc": "^2.2.0" + "@vitejs/plugin-vue": "^6.0.8", + "typescript": "^5.9.3", + "vite": "^8.2.1", + "vitest": "^4.1.10", + "vue-tsc": "^3.3.10" } } diff --git a/evals/suites/skills/vue-ai-apps/tool-calling/scenario-3/package.json b/evals/suites/skills/vue-ai-apps/tool-calling/scenario-3/package.json index 8514cee..69a6381 100644 --- a/evals/suites/skills/vue-ai-apps/tool-calling/scenario-3/package.json +++ b/evals/suites/skills/vue-ai-apps/tool-calling/scenario-3/package.json @@ -8,13 +8,13 @@ "test": "vitest run" }, "dependencies": { - "vue": "^3.5.13" + "vue": "^3.5.41" }, "devDependencies": { - "@vitejs/plugin-vue": "^5.2.1", - "typescript": "^5.7.0", - "vite": "^6.0.0", - "vitest": "^3.0.0", - "vue-tsc": "^2.2.0" + "@vitejs/plugin-vue": "^6.0.8", + "typescript": "^5.9.3", + "vite": "^8.2.1", + "vitest": "^4.1.10", + "vue-tsc": "^3.3.10" } } diff --git a/evals/suites/skills/vue-best-practices/reactive-props-destructure/scenario-1/package.json b/evals/suites/skills/vue-best-practices/reactive-props-destructure/scenario-1/package.json index 9f09bbd..832df6e 100644 --- a/evals/suites/skills/vue-best-practices/reactive-props-destructure/scenario-1/package.json +++ b/evals/suites/skills/vue-best-practices/reactive-props-destructure/scenario-1/package.json @@ -8,13 +8,13 @@ "test": "vitest run" }, "dependencies": { - "vue": "^3.5.13" + "vue": "^3.5.41" }, "devDependencies": { - "@vitejs/plugin-vue": "^5.2.1", - "typescript": "^5.7.0", - "vite": "^6.0.0", - "vitest": "^3.0.0", - "vue-tsc": "^2.2.0" + "@vitejs/plugin-vue": "^6.0.8", + "typescript": "^5.9.3", + "vite": "^8.2.1", + "vitest": "^4.1.10", + "vue-tsc": "^3.3.10" } } diff --git a/evals/suites/skills/vue-best-practices/reactive-props-destructure/scenario-2/package.json b/evals/suites/skills/vue-best-practices/reactive-props-destructure/scenario-2/package.json index 0c8f147..2cf92cc 100644 --- a/evals/suites/skills/vue-best-practices/reactive-props-destructure/scenario-2/package.json +++ b/evals/suites/skills/vue-best-practices/reactive-props-destructure/scenario-2/package.json @@ -8,13 +8,13 @@ "test": "vitest run" }, "dependencies": { - "vue": "^3.5.13" + "vue": "^3.5.41" }, "devDependencies": { - "@vitejs/plugin-vue": "^5.2.1", - "typescript": "^5.7.0", - "vite": "^6.0.0", - "vitest": "^3.0.0", - "vue-tsc": "^2.2.0" + "@vitejs/plugin-vue": "^6.0.8", + "typescript": "^5.9.3", + "vite": "^8.2.1", + "vitest": "^4.1.10", + "vue-tsc": "^3.3.10" } } diff --git a/evals/suites/skills/vue-best-practices/reactive-props-destructure/scenario-3/package.json b/evals/suites/skills/vue-best-practices/reactive-props-destructure/scenario-3/package.json index b345fca..370797e 100644 --- a/evals/suites/skills/vue-best-practices/reactive-props-destructure/scenario-3/package.json +++ b/evals/suites/skills/vue-best-practices/reactive-props-destructure/scenario-3/package.json @@ -8,13 +8,13 @@ "test": "vitest run" }, "dependencies": { - "vue": "^3.5.13" + "vue": "^3.5.41" }, "devDependencies": { - "@vitejs/plugin-vue": "^5.2.1", - "typescript": "^5.7.0", - "vite": "^6.0.0", - "vitest": "^3.0.0", - "vue-tsc": "^2.2.0" + "@vitejs/plugin-vue": "^6.0.8", + "typescript": "^5.9.3", + "vite": "^8.2.1", + "vitest": "^4.1.10", + "vue-tsc": "^3.3.10" } } diff --git a/evals/suites/skills/vue-best-practices/vue-3-5-helpers/scenario-1/package.json b/evals/suites/skills/vue-best-practices/vue-3-5-helpers/scenario-1/package.json index 719de6d..7ec79e1 100644 --- a/evals/suites/skills/vue-best-practices/vue-3-5-helpers/scenario-1/package.json +++ b/evals/suites/skills/vue-best-practices/vue-3-5-helpers/scenario-1/package.json @@ -8,13 +8,13 @@ "test": "vitest run" }, "dependencies": { - "vue": "^3.5.13" + "vue": "^3.5.41" }, "devDependencies": { - "@vitejs/plugin-vue": "^5.2.1", - "typescript": "^5.7.0", - "vite": "^6.0.0", - "vitest": "^3.0.0", - "vue-tsc": "^2.2.0" + "@vitejs/plugin-vue": "^6.0.8", + "typescript": "^5.9.3", + "vite": "^8.2.1", + "vitest": "^4.1.10", + "vue-tsc": "^3.3.10" } } diff --git a/evals/suites/skills/vue-best-practices/vue-3-5-helpers/scenario-2/package.json b/evals/suites/skills/vue-best-practices/vue-3-5-helpers/scenario-2/package.json index bbac13f..c0a19ad 100644 --- a/evals/suites/skills/vue-best-practices/vue-3-5-helpers/scenario-2/package.json +++ b/evals/suites/skills/vue-best-practices/vue-3-5-helpers/scenario-2/package.json @@ -8,13 +8,13 @@ "test": "vitest run" }, "dependencies": { - "vue": "^3.5.13" + "vue": "^3.5.41" }, "devDependencies": { - "@vitejs/plugin-vue": "^5.2.1", - "typescript": "^5.7.0", - "vite": "^6.0.0", - "vitest": "^3.0.0", - "vue-tsc": "^2.2.0" + "@vitejs/plugin-vue": "^6.0.8", + "typescript": "^5.9.3", + "vite": "^8.2.1", + "vitest": "^4.1.10", + "vue-tsc": "^3.3.10" } } diff --git a/evals/suites/skills/vue-best-practices/vue-3-5-helpers/scenario-3/package.json b/evals/suites/skills/vue-best-practices/vue-3-5-helpers/scenario-3/package.json index 69bc88a..55e7217 100644 --- a/evals/suites/skills/vue-best-practices/vue-3-5-helpers/scenario-3/package.json +++ b/evals/suites/skills/vue-best-practices/vue-3-5-helpers/scenario-3/package.json @@ -8,13 +8,13 @@ "test": "vitest run" }, "dependencies": { - "vue": "^3.5.13" + "vue": "^3.5.41" }, "devDependencies": { - "@vitejs/plugin-vue": "^5.2.1", - "typescript": "^5.7.0", - "vite": "^6.0.0", - "vitest": "^3.0.0", - "vue-tsc": "^2.2.0" + "@vitejs/plugin-vue": "^6.0.8", + "typescript": "^5.9.3", + "vite": "^8.2.1", + "vitest": "^4.1.10", + "vue-tsc": "^3.3.10" } } diff --git a/mcp/README.md b/mcp/README.md index 8417736..cfbaa6d 100644 --- a/mcp/README.md +++ b/mcp/README.md @@ -1,6 +1,6 @@ # vue-skills MCP server -Part of [Pythoughts-labs/vue3-best-practices](https://github.com/Pythoughts-labs/vue3-best-practices). +Part of [PyModel/vue3-best-practices](https://github.com/PyModel/vue3-best-practices). Exposes the Vue 3 best-practice skills in this repo as MCP tools, so any MCP coding agent can fetch them while working on Vue. diff --git a/mcp/package-lock.json b/mcp/package-lock.json index b0f673f..bba0fd9 100644 --- a/mcp/package-lock.json +++ b/mcp/package-lock.json @@ -1,12 +1,12 @@ { - "name": "@pythoughts/vue-skills-mcp", - "version": "0.1.0", + "name": "@pymodel/vue-skills-mcp", + "version": "0.3.2", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "@pythoughts/vue-skills-mcp", - "version": "0.1.0", + "name": "@pymodel/vue-skills-mcp", + "version": "0.3.2", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.12.0", @@ -17,9 +17,9 @@ } }, "node_modules/@hono/node-server": { - "version": "1.19.14", - "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.14.tgz", - "integrity": "sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw==", + "version": "1.19.17", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.17.tgz", + "integrity": "sha512-dSneS5qhiauZWGDCeK4o695Xd9nUNjviSZCMQrj10eetr8Uln1ucn6bbphOM6UynAMMtNIzZNSpL9vnASJwrPQ==", "license": "MIT", "engines": { "node": ">=18.14.1" @@ -449,9 +449,9 @@ "license": "MIT" }, "node_modules/fast-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz", - "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.5.tgz", + "integrity": "sha512-gHwA1O9LDIcKunMKhObS/HimwtehO1nPUECKAu5TpKgaO19fcWEl4bliWe1jWxVFvIXztJjjQ4L8XQ1EU9f7Jw==", "funding": [ { "type": "github", @@ -586,9 +586,9 @@ } }, "node_modules/hono": { - "version": "4.12.27", - "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.27.tgz", - "integrity": "sha512-1yrb/+w6HWQJrUCLkJ2IF5jNIPvvFkblV5RNOYl6bV+OA6p9GLcMpHFFGTosSvHvcAUibuUukRqhlYI4z32C7Q==", + "version": "4.13.2", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.13.2.tgz", + "integrity": "sha512-JydRilDRkYBQMt9qR9U92mXxmbGqsqSn/IKOrh4e7/gEbn+0zSr8igTu0obwJoNGN4sez28DIql7FBHWydoJpA==", "license": "MIT", "engines": { "node": ">=16.9.0" @@ -637,9 +637,9 @@ "license": "ISC" }, "node_modules/ip-address": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.2.0.tgz", - "integrity": "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.5.0.tgz", + "integrity": "sha512-R5SnVLJmgYYvf2F2ZgwSBnelz5G4q5AxIC277GDfUaNbrZKNANcBC7RHqYYePlszf4kBolVkJauG0ZjHHFh55g==", "license": "MIT", "engines": { "node": ">= 12" diff --git a/mcp/package.json b/mcp/package.json index 48ec207..c486781 100644 --- a/mcp/package.json +++ b/mcp/package.json @@ -1,14 +1,14 @@ { - "name": "@pythoughts/vue-skills-mcp", - "version": "0.1.0", + "name": "@pymodel/vue-skills-mcp", + "version": "0.3.2", "type": "module", "description": "MCP server exposing the Vue 3 best-practice skills so any MCP coding agent can fetch them automatically on Vue work.", "author": "Mohamed Elkholy (elkaix)", "license": "MIT", - "homepage": "https://github.com/Pythoughts-labs/vue3-best-practices", + "homepage": "https://github.com/PyModel/vue3-best-practices", "repository": { "type": "git", - "url": "git+https://github.com/Pythoughts-labs/vue3-best-practices.git", + "url": "git+https://github.com/PyModel/vue3-best-practices.git", "directory": "mcp" }, "bin": { diff --git a/skills/vue-ai-apps/SKILL.md b/skills/vue-ai-apps/SKILL.md index fea1023..58c6fc8 100644 --- a/skills/vue-ai-apps/SKILL.md +++ b/skills/vue-ai-apps/SKILL.md @@ -3,7 +3,7 @@ name: vue-ai-apps description: "Building AI/LLM and agent apps with Vue 3 and Nuxt: streaming chat UIs, the Vercel AI SDK (`ai` + `@ai-sdk/vue`), `useChat`, tool calling, structured output, and abort/error handling. Load for AI chatbots, assistant UIs, LLM streaming, or agent frontends in Vue or Nuxt." version: "1.1.1" license: MIT -author: github.com/Pythoughts-labs +author: github.com/PyModel --- # Vue AI Apps Workflow diff --git a/skills/vue-best-practices/SKILL.md b/skills/vue-best-practices/SKILL.md index 13a2aa7..51476b7 100644 --- a/skills/vue-best-practices/SKILL.md +++ b/skills/vue-best-practices/SKILL.md @@ -3,7 +3,7 @@ name: vue-best-practices description: MUST be used for Vue.js tasks. Strongly recommends Composition API with ` +``` + +## Upgrade Notes + +1. **v4 → v5 is drop-in for plain Router 4 projects.** Their only packaging change: the IIFE build no longer bundles `@vue/devtools-api` (v8). +2. **`unplugin-vue-router` users must migrate.** Remove the dependency, then repoint its imports at the core package: + - `unplugin-vue-router/vite` → `vue-router/vite` + - `unplugin-vue-router/data-loaders/*` → `vue-router/experimental` + - `unplugin-vue-router` → `vue-router/unplugin` + - `unplugin-vue-router/volar/*` → `vue-router/volar/*` + - drop `unplugin-vue-router/client` from `tsconfig.json`'s type references + + Route generation, `definePage()`, and typed `RouteNamedMap` now ship from the core package. +3. **`next()` deprecation**: v5.0.3 added a deprecation warning for the `next()` callback. See [router-navigation-guard-next-deprecated](router-navigation-guard-next-deprecated.md). +4. **Data loaders** (`defineLoader`, `defineBasicLoader`) are experimental — the API may change between releases. Use them for feedback, not as a load-bearing pattern. +5. **`reroute()`** replaces the deprecated `NavigationResult` for programmatic redirect decisions inside guards. + +## Key Points + +1. **Upgrade freely without `unplugin-vue-router`** — v5 breaks nothing from plain v4; treat it as v4 plus file-based routing in core +2. **One package** — file-based routing no longer needs `unplugin-vue-router`, but existing users must remove it and repoint imports (see Upgrade Notes) +3. **Return-based guards** — `next()` warns in v5; migrate during the upgrade +4. **Keep data loaders experimental** — don't standardize on them yet + +## Reference +- [Migrating to Vue Router 5](https://router.vuejs.org/guide/migration/v4-to-v5) +- [Vue Router Releases](https://github.com/vuejs/router/releases) diff --git a/skills/vue-router-best-practices/reference/router-navigation-guard-next-deprecated.md b/skills/vue-router-best-practices/reference/router-navigation-guard-next-deprecated.md index 9cabf03..2f4bf13 100644 --- a/skills/vue-router-best-practices/reference/router-navigation-guard-next-deprecated.md +++ b/skills/vue-router-best-practices/reference/router-navigation-guard-next-deprecated.md @@ -8,7 +8,7 @@ tags: [vue3, vue-router, navigation-guards, migration, async] # Vue Router Navigation Guard next() Function Deprecated -**Impact: HIGH** - The third `next()` argument in navigation guards is deprecated in Vue Router 4. While still supported for backward compatibility, using it incorrectly is one of the most common sources of bugs: calling it multiple times, forgetting to call it, or calling it conditionally without proper logic. +**Impact: HIGH** - The third `next()` argument in navigation guards is deprecated. In Vue Router 4 it was merely discouraged; since Vue Router 5.0.3 the `next()` callback itself emits a deprecation warning. Using it incorrectly is one of the most common sources of bugs: calling it multiple times, forgetting to call it, or calling it conditionally without proper logic. ## Task Checklist @@ -49,7 +49,7 @@ router.beforeEach(async (to, from, next) => { ## Solution: Use Return-Based Guards ```javascript -// CORRECT: Return-based syntax (modern Vue Router 4+) +// CORRECT: Return-based syntax (modern Vue Router 4+, required to avoid warnings in 5) router.beforeEach((to, from) => { if (!isAuthenticated) { return '/login' // Redirect diff --git a/skills/vue-router-best-practices/reference/router-use-vue-router-for-production.md b/skills/vue-router-best-practices/reference/router-use-vue-router-for-production.md index 1e60304..5c50de2 100644 --- a/skills/vue-router-best-practices/reference/router-use-vue-router-for-production.md +++ b/skills/vue-router-best-practices/reference/router-use-vue-router-for-production.md @@ -149,7 +149,7 @@ createApp(App) ## Modern Vue Router Features (2025+) ```javascript -// Data Loading API (Vue Router 4.2+) +// Data Loading API (experimental since Vue Router 4.2, still experimental in 5 — do not standardize on it) const routes = [ { path: '/users/:id', diff --git a/skills/vue-testing-best-practices/SKILL.md b/skills/vue-testing-best-practices/SKILL.md index 92fc0bd..f0a611b 100644 --- a/skills/vue-testing-best-practices/SKILL.md +++ b/skills/vue-testing-best-practices/SKILL.md @@ -1,9 +1,9 @@ --- name: vue-testing-best-practices -version: 1.0.0 +version: 1.1.0 license: MIT -author: github.com/Pythoughts-labs -description: Use for Vue.js testing. Covers Vitest, Vue Test Utils, component testing, mocking, testing patterns, and Playwright for E2E testing. +author: github.com/PyModel +description: Use for Vue.js testing. Covers Vitest 4, Vue Test Utils, component testing, mocking, testing patterns, and Playwright for E2E testing. --- Vue.js testing best practices, patterns, and common gotchas.