Skip to content

Commit e2f314a

Browse files
committed
feat: add v3 to v4 upgrade guide and breaking changes tools
Add support for Vuetify 3 → 4 migration: - Add v3 entry to UPGRADE_FROM_VERSIONS (fetches from next branch) - Add V4_BREAKING_CHANGES with 13 categories of breaking changes - Add get_upgrade_guide tool to expose upgrade documentation - Add get_v4_breaking_changes tool with optional category filtering
1 parent f4320ea commit e2f314a

File tree

2 files changed

+277
-3
lines changed

2 files changed

+277
-3
lines changed

src/services/documentation.ts

Lines changed: 254 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,8 +436,228 @@ export const UPGRADE_FROM_VERSIONS = {
436436
\`\`\`
437437
`,
438438
},
439+
'v3': {
440+
name: 'Vuetify v3 Upgrade',
441+
description: 'Upgrade from Vuetify v3.x to v4.0',
442+
path: 'packages/docs/src/pages/en/getting-started/upgrade-guide.md',
443+
markdown: `
444+
# Dependencies
445+
\`\`\`bash
446+
[npm|pnpm|yarn|bun] install vuetify@^4.0.0
447+
\`\`\`
448+
`,
449+
},
439450
} as const
440451

452+
export const V4_BREAKING_CHANGES = {
453+
'styles': {
454+
name: 'CSS & Styles',
455+
description: 'CSS architecture changes including layers, reset, and entry points',
456+
changes: [
457+
{
458+
title: 'CSS Layers are now mandatory',
459+
description: 'Vuetify 4 always uses CSS layers for all styles. This changes how specificity works - you may need to adjust custom overrides that relied on !important or specificity hacks.',
460+
migration: 'Replace !important overrides with layer-aware CSS. Use @layer to control specificity.',
461+
issue: 'https://github.com/vuetifyjs/vuetify/issues/3400',
462+
},
463+
{
464+
title: 'Flattened layer names',
465+
description: 'CSS layer names have been flattened for simpler organization.',
466+
migration: 'Update any custom CSS that references Vuetify layer names.',
467+
issue: 'https://github.com/vuetifyjs/vuetify/issues/22443',
468+
},
469+
{
470+
title: 'Reduced CSS reset',
471+
description: 'The CSS reset has been cut down significantly.',
472+
migration: 'If you relied on Vuetify\'s reset for certain elements, you may need to add your own reset styles.',
473+
issue: 'https://github.com/vuetifyjs/vuetify/issues/17633',
474+
},
475+
{
476+
title: 'Removed overflow-y from reset',
477+
description: 'The overflow-y rule has been removed from the CSS reset.',
478+
migration: 'Add your own overflow-y styles if needed.',
479+
issue: 'https://github.com/vuetifyjs/vuetify/issues/1197',
480+
},
481+
{
482+
title: 'Separate style entry points',
483+
description: 'New granular style entry points: vuetify/styles, vuetify/styles/main, vuetify/styles/generic.',
484+
migration: 'Optionally use specific entry points for smaller bundles.',
485+
issue: 'https://github.com/vuetifyjs/vuetify/issues/20100',
486+
},
487+
{
488+
title: 'Opt-out from misc styles',
489+
description: 'You can now opt-out from miscellaneous utility styles.',
490+
migration: 'Use createVuetify({ styles: { misc: false } }) if desired.',
491+
issue: null,
492+
},
493+
],
494+
},
495+
'theme': {
496+
name: 'Theme',
497+
description: 'Theme system changes',
498+
changes: [
499+
{
500+
title: 'Default theme changed to "system"',
501+
description: 'The default theme is now "system" instead of "light", respecting user\'s OS preference.',
502+
migration: 'If you need explicit light theme, set defaultTheme: "light" in createVuetify().',
503+
issue: null,
504+
},
505+
{
506+
title: 'Removed "unimportant" option',
507+
description: 'The theme.unimportant option has been removed (no longer needed with CSS layers).',
508+
migration: 'Remove any unimportant: true configuration.',
509+
issue: null,
510+
},
511+
{
512+
title: 'Transparent color support',
513+
description: 'Theme colors now support transparency.',
514+
migration: 'No migration needed - this is a new feature.',
515+
issue: 'https://github.com/vuetifyjs/vuetify/issues/10299',
516+
},
517+
],
518+
},
519+
'display': {
520+
name: 'Display & Breakpoints',
521+
description: 'Breakpoint and display changes',
522+
changes: [
523+
{
524+
title: 'Reduced default breakpoint sizes',
525+
description: 'Default breakpoint values have been reduced to better match modern device sizes.',
526+
migration: 'If you have layouts depending on specific breakpoint values, review and adjust accordingly or override the breakpoints in your Vuetify config.',
527+
issue: 'https://github.com/vuetifyjs/vuetify/issues/19759',
528+
},
529+
],
530+
},
531+
'grid': {
532+
name: 'Grid System',
533+
description: 'Grid system overhaul',
534+
changes: [
535+
{
536+
title: 'Grid system overhaul',
537+
description: 'The grid system (v-container, v-row, v-col) has been overhauled.',
538+
migration: 'Review grid usage and test layouts. Some class names or behaviors may have changed.',
539+
issue: 'https://github.com/vuetifyjs/vuetify/issues/8611',
540+
},
541+
],
542+
},
543+
'typography': {
544+
name: 'Typography',
545+
description: 'Typography system changes',
546+
changes: [
547+
{
548+
title: 'MD3 typography',
549+
description: 'Typography now follows Material Design 3 specifications.',
550+
migration: 'Review text styling - font sizes, weights, and line heights may differ.',
551+
issue: 'https://github.com/vuetifyjs/vuetify/issues/22557',
552+
},
553+
],
554+
},
555+
'elevation': {
556+
name: 'Elevation',
557+
description: 'Elevation system changes',
558+
changes: [
559+
{
560+
title: 'MD3 elevation levels',
561+
description: 'Elevation now uses Material Design 3 levels.',
562+
migration: 'Shadows may appear different. Review components using elevation prop.',
563+
issue: 'https://github.com/vuetifyjs/vuetify/issues/14198',
564+
},
565+
],
566+
},
567+
'v-btn': {
568+
name: 'VBtn',
569+
description: 'Button component changes',
570+
changes: [
571+
{
572+
title: 'Removed default text transform',
573+
description: 'Buttons no longer have uppercase text by default.',
574+
migration: 'Add text-transform: uppercase in CSS if you want the old behavior.',
575+
issue: 'https://github.com/vuetifyjs/vuetify/issues/21079',
576+
},
577+
{
578+
title: 'Display changed from grid to flex',
579+
description: 'VBtn internal layout changed from CSS grid to flexbox.',
580+
migration: 'If you had custom CSS targeting button internals, review and adjust.',
581+
issue: null,
582+
},
583+
],
584+
},
585+
'v-snackbar': {
586+
name: 'VSnackbar',
587+
description: 'Snackbar component changes',
588+
changes: [
589+
{
590+
title: 'Removed multi-line prop',
591+
description: 'The multi-line prop has been removed.',
592+
migration: 'Use CSS to style multi-line content instead.',
593+
issue: 'https://github.com/vuetifyjs/vuetify/issues/15996',
594+
},
595+
],
596+
},
597+
'v-select': {
598+
name: 'VSelect / VAutocomplete / VCombobox',
599+
description: 'Select component changes',
600+
changes: [
601+
{
602+
title: 'Renamed item to internalItem in slots',
603+
description: 'The "item" slot prop has been renamed to "internalItem" for clarity.',
604+
migration: 'Update slot templates: #item="{ item }" becomes #item="{ internalItem }".',
605+
issue: 'https://github.com/vuetifyjs/vuetify/issues/18354',
606+
},
607+
],
608+
},
609+
'v-date-picker': {
610+
name: 'VDatePicker',
611+
description: 'Date picker component changes',
612+
changes: [
613+
{
614+
title: 'Range picker only emits start and end values',
615+
description: 'When using range selection, the picker now only emits start and end values, not intermediate states.',
616+
migration: 'Update range picker handlers if they relied on intermediate value emissions.',
617+
issue: 'https://github.com/vuetifyjs/vuetify/issues/18701',
618+
},
619+
],
620+
},
621+
'v-form': {
622+
name: 'VForm',
623+
description: 'Form component changes',
624+
changes: [
625+
{
626+
title: 'Slot props are unreffed',
627+
description: 'VForm slot props are now unreffed (raw values instead of refs).',
628+
migration: 'Remove .value access from form slot props if you were using them as refs.',
629+
issue: 'https://github.com/vuetifyjs/vuetify/issues/18355',
630+
},
631+
],
632+
},
633+
'v-img': {
634+
name: 'VImg',
635+
description: 'Image component changes',
636+
changes: [
637+
{
638+
title: 'Attributes pass through to img element',
639+
description: 'VImg now passes attributes to the underlying <img> element.',
640+
migration: 'Review any custom attributes - they will now apply to the img tag.',
641+
issue: 'https://github.com/vuetifyjs/vuetify/issues/18860',
642+
},
643+
],
644+
},
645+
'nested': {
646+
name: 'Nested / Tree',
647+
description: 'Nested component changes',
648+
changes: [
649+
{
650+
title: 'Added branch select strategy',
651+
description: 'New "branch" select strategy for tree/nested components.',
652+
migration: 'No migration needed - this is a new feature.',
653+
issue: 'https://github.com/vuetifyjs/vuetify/issues/22404',
654+
},
655+
],
656+
},
657+
} as const
658+
659+
export type V4BreakingChangeCategory = keyof typeof V4_BREAKING_CHANGES
660+
441661
export const AVAILABLE_FEATURES = {
442662
'accessibility': 'Web accessibility (a11y for short), is the inclusive practice of ensuring there are no barriers that prevent the interaction with, or access to, websites on the World Wide Web by people with disabilities.',
443663
'aliasing': 'Create virtual components that extend built-in Vuetify components using custom aliases.',
@@ -532,10 +752,14 @@ export function createDocumentationService () {
532752
getUpgradeGuide: async ({ version }: { version: UpgradeFromVersion }) => {
533753
const guide = UPGRADE_FROM_VERSIONS[version]
534754

755+
// For v3 upgrade, fetch from next.vuetifyjs.com docs (v4 branch)
756+
const ref = version === 'v3' ? 'next' : undefined
757+
535758
const { data } = await octokit.rest.repos.getContent({
536759
owner: 'vuetifyjs',
537760
repo: 'vuetify',
538-
path: `packages/docs/src/pages/en/features/${guide.path}`,
761+
path: guide.path,
762+
ref,
539763
mediaType: {
540764
format: 'raw',
541765
},
@@ -550,6 +774,35 @@ export function createDocumentationService () {
550774
],
551775
}
552776
},
777+
getV4BreakingChanges: async ({ category }: { category?: V4BreakingChangeCategory }) => {
778+
if (category) {
779+
const cat = V4_BREAKING_CHANGES[category]
780+
if (!cat) {
781+
throw new Error(`Breaking change category "${category}" not found.`)
782+
}
783+
784+
const text = `# ${cat.name}\n\n${cat.description}\n\n` + cat.changes.map(change => (
785+
`## ${change.title}\n\n${change.description}\n\n**Migration:** ${change.migration}`
786+
+ (change.issue ? `\n\n**Related issue:** ${change.issue}` : '')
787+
)).join('\n\n---\n\n')
788+
789+
return {
790+
content: [{ type: 'text', text } as const],
791+
}
792+
}
793+
794+
// Return all categories summary
795+
const text = `# Vuetify 4 Breaking Changes\n\n`
796+
+ `Upgrade guide: https://next.vuetifyjs.com/en/getting-started/upgrade-guide/\n\n`
797+
+ Object.entries(V4_BREAKING_CHANGES).map(([key, cat]) => (
798+
`## ${cat.name} (${key})\n\n${cat.description}\n\n`
799+
+ cat.changes.map(c => `- **${c.title}**: ${c.description}`).join('\n')
800+
)).join('\n\n---\n\n')
801+
802+
return {
803+
content: [{ type: 'text', text } as const],
804+
}
805+
},
553806
getExposedExports: async () => {
554807
const { data } = await octokit.rest.repos.getContent({
555808
owner: 'vuetifyjs',

src/tools/documentation.ts

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,16 @@
66
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
77
import { z } from 'zod'
88

9-
import { AVAILABLE_FEATURES, createDocumentationService, INSTALLATION_PLATFORMS } from '#services/documentation'
10-
import type { InstallationPlatform, AvailableFeature } from '#services/documentation'
9+
import { AVAILABLE_FEATURES, createDocumentationService, INSTALLATION_PLATFORMS, UPGRADE_FROM_VERSIONS, V4_BREAKING_CHANGES } from '#services/documentation'
10+
import type { InstallationPlatform, AvailableFeature, UpgradeFromVersion, V4BreakingChangeCategory } from '#services/documentation'
1111
import { createVuetify0Service, VUETIFY0_COMPOSABLES, VUETIFY0_COMPONENTS } from '#services/vuetify0'
1212
import type { Vuetify0Category, Vuetify0Component } from '#services/vuetify0'
1313

1414
export async function registerDocumentationTools (server: McpServer) {
1515
const platforms = Object.keys(INSTALLATION_PLATFORMS) as [InstallationPlatform, ...InstallationPlatform[]]
1616
const features = Object.keys(AVAILABLE_FEATURES) as [AvailableFeature, ...AvailableFeature[]]
17+
const upgradeVersions = Object.keys(UPGRADE_FROM_VERSIONS) as [UpgradeFromVersion, ...UpgradeFromVersion[]]
18+
const breakingChangeCategories = Object.keys(V4_BREAKING_CHANGES) as [V4BreakingChangeCategory, ...V4BreakingChangeCategory[]]
1719

1820
const documentation = createDocumentationService()
1921
const vuetify0 = createVuetify0Service()
@@ -72,6 +74,25 @@ export async function registerDocumentationTools (server: McpServer) {
7274
documentation.getVuetifyOneInstallationGuide,
7375
)
7476

77+
// Upgrade Tools
78+
server.tool(
79+
'get_upgrade_guide',
80+
'Get the upgrade guide for migrating between Vuetify major versions (v1.5→v2, v2.7→v3, v3→v4).',
81+
{
82+
version: z.enum(upgradeVersions).describe(`The source Vuetify version to upgrade from. Available versions: ${upgradeVersions.join(', ')}`),
83+
},
84+
documentation.getUpgradeGuide,
85+
)
86+
87+
server.tool(
88+
'get_v4_breaking_changes',
89+
'Get Vuetify 4 breaking changes, optionally filtered by category. Returns migration guidance for each change.',
90+
{
91+
category: z.enum(breakingChangeCategories).optional().describe(`Optional category to filter by. Available categories: ${breakingChangeCategories.join(', ')}. Omit to get all breaking changes.`),
92+
},
93+
documentation.getV4BreakingChanges,
94+
)
95+
7596
// Vuetify0 (@vuetify/v0) Tools
7697
server.tool(
7798
'get_vuetify0_installation_guide',

0 commit comments

Comments
 (0)