diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 5a362a6..4acde1e 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": [ { 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..b582914 100644 --- a/.github/workflows/sync-to-main.yml +++ b/.github/workflows/sync-to-main.yml @@ -41,8 +41,11 @@ 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 -- . 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..80750ff 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@

- CI + CI License: MIT Vue 3.5+ Skills: 8 @@ -14,7 +14,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 +32,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 @@ -129,7 +129,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/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.