From 756ab952ce532978c086d704f984cf72485c90a7 Mon Sep 17 00:00:00 2001 From: Roman Date: Fri, 23 Oct 2026 17:52:55 +0100 Subject: [PATCH 1/6] fix(ui): render only the active package manager --- .../Package/Install/AdditionalCommands.vue | 132 +++++------------- app/components/Package/Install/Dropdown.vue | 30 +--- 2 files changed, 37 insertions(+), 125 deletions(-) diff --git a/app/components/Package/Install/AdditionalCommands.vue b/app/components/Package/Install/AdditionalCommands.vue index 712ddb2b3b..eba8928cb4 100644 --- a/app/components/Package/Install/AdditionalCommands.vue +++ b/app/components/Package/Install/AdditionalCommands.vue @@ -16,7 +16,6 @@ const props = defineProps<{ selectedPm: PackageManagerId }>() -// Matches the summary row's copy button style (Package/Install/Dropdown.vue) for visual consistency. const copyButtonClass = 'text-fg-muted bg-bg-subtle/80 border-border transition-all duration-150 hover:scale-105 active:scale-90 select-none' @@ -24,41 +23,41 @@ const devDependencySuggestion = computed( () => props.devDependencySuggestion ?? { recommended: false as const }, ) -function getDevInstallPartsForPM(pmId: PackageManagerId) { +function getDevInstallParts() { return getInstallCommandParts({ packageName: props.packageName, - packageManager: pmId, + packageManager: props.selectedPm, version: props.installVersionOverride ?? props.requestedVersion, jsrInfo: props.jsrInfo, dev: true, }) } -function getTypesInstallPartsForPM(pmId: PackageManagerId) { +function getTypesInstallParts() { if (!props.typesPackageName) return [] return getInstallCommandParts({ packageName: props.typesPackageName, - packageManager: pmId, + packageManager: props.selectedPm, jsrInfo: null, dev: true, }) } -function getRunPartsForPM(pmId: PackageManagerId, command?: string) { +function getRunParts(command?: string) { return getRunCommandParts({ packageName: props.packageName, - packageManager: pmId, + packageManager: props.selectedPm, jsrInfo: props.jsrInfo, command, isBinaryOnly: false, }) } -function getCreatePartsForPM(pmId: PackageManagerId) { +function getCreateParts() { if (!props.createPackageInfo) return [] return getExecuteCommandParts({ packageName: props.createPackageInfo.packageName, - packageManager: pmId, + packageManager: props.selectedPm, jsrInfo: null, isCreatePackage: true, }) @@ -145,24 +144,15 @@ function copyCreateCommand() {

{{ $t('package.get_started.dev_dependency_hint') }}

- ${{ ' ' }} + $ + {{ i > 0 ? ' ' : '' }}{{ part }} + > + @@ -184,24 +174,15 @@ function copyCreateCommand() { {{ $t('package.get_started.types_label') }}

- ${{ ' ' }} + $ + {{ i > 0 ? ' ' : '' }}{{ part }} + > +

{{ $t('package.run.locally') }}

- ${{ ' ' }} + $ + {{ i > 0 ? ' ' : '' }}{{ part }} + > +
@@ -282,47 +254,15 @@ function copyCreateCommand() { - ${{ ' ' }} + $ + {{ i > 0 ? ' ' : '' }}{{ part }} + > + - diff --git a/app/components/Package/Install/Dropdown.vue b/app/components/Package/Install/Dropdown.vue index d5ebca4aef..df6706f9a9 100644 --- a/app/components/Package/Install/Dropdown.vue +++ b/app/components/Package/Install/Dropdown.vue @@ -137,14 +137,11 @@ onPrehydrate(el => { { - From 6493ba169d0266ac9cd1fecf0a08d48014c86853 Mon Sep 17 00:00:00 2001 From: Roman Date: Fri, 23 Oct 2026 17:57:43 +0100 Subject: [PATCH 2/6] fix --- app/components/Package/Install/AdditionalCommands.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/app/components/Package/Install/AdditionalCommands.vue b/app/components/Package/Install/AdditionalCommands.vue index eba8928cb4..2d2371a5a2 100644 --- a/app/components/Package/Install/AdditionalCommands.vue +++ b/app/components/Package/Install/AdditionalCommands.vue @@ -16,6 +16,7 @@ const props = defineProps<{ selectedPm: PackageManagerId }>() +// Matches the summary row's copy button style (Package/Install/Dropdown.vue) for visual consistency. const copyButtonClass = 'text-fg-muted bg-bg-subtle/80 border-border transition-all duration-150 hover:scale-105 active:scale-90 select-none' From 30aa755687bb666feb147f67e5610f1a1514f654 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Fri, 23 Oct 2026 16:59:00 +0000 Subject: [PATCH 3/6] [autofix.ci] apply automated fixes --- app/components/Package/Install/AdditionalCommands.vue | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/app/components/Package/Install/AdditionalCommands.vue b/app/components/Package/Install/AdditionalCommands.vue index 2d2371a5a2..91a18045f1 100644 --- a/app/components/Package/Install/AdditionalCommands.vue +++ b/app/components/Package/Install/AdditionalCommands.vue @@ -180,7 +180,9 @@ function copyCreateCommand() { {{ i > 0 ? ' ' : '' }}{{ part }} @@ -218,7 +220,11 @@ function copyCreateCommand() { {{ i > 0 ? ' ' : '' }}{{ part }} From ecaa4c06e89fc22869a6182e946b5a5fcc53f837 Mon Sep 17 00:00:00 2001 From: Roman Date: Fri, 23 Oct 2026 18:15:41 +0100 Subject: [PATCH 4/6] fix tests and hydration --- .../Package/Install/AdditionalCommands.vue | 40 +++++++++++++++---- test/e2e/create-command.spec.ts | 9 ++--- 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/app/components/Package/Install/AdditionalCommands.vue b/app/components/Package/Install/AdditionalCommands.vue index 91a18045f1..56411ce8fe 100644 --- a/app/components/Package/Install/AdditionalCommands.vue +++ b/app/components/Package/Install/AdditionalCommands.vue @@ -2,6 +2,7 @@ import type { JsrPackageInfo } from '#shared/types/jsr' import type { DevDependencySuggestion } from '#shared/utils/dev-dependency' import type { PackageManagerId } from '~/utils/install-command' +import { getPackageManagerConfig } from '~/utils/install-command' const props = defineProps<{ packageName: string @@ -16,6 +17,13 @@ const props = defineProps<{ selectedPm: PackageManagerId }>() +const resolvedPm = computed(() => { + if (import.meta.server) return 'npm' + return props.selectedPm +}) + +const selectedPackageManagerConfig = computed(() => getPackageManagerConfig(resolvedPm.value)) + // Matches the summary row's copy button style (Package/Install/Dropdown.vue) for visual consistency. const copyButtonClass = 'text-fg-muted bg-bg-subtle/80 border-border transition-all duration-150 hover:scale-105 active:scale-90 select-none' @@ -27,7 +35,7 @@ const devDependencySuggestion = computed( function getDevInstallParts() { return getInstallCommandParts({ packageName: props.packageName, - packageManager: props.selectedPm, + packageManager: selectedPackageManagerConfig.value.id, version: props.installVersionOverride ?? props.requestedVersion, jsrInfo: props.jsrInfo, dev: true, @@ -38,7 +46,7 @@ function getTypesInstallParts() { if (!props.typesPackageName) return [] return getInstallCommandParts({ packageName: props.typesPackageName, - packageManager: props.selectedPm, + packageManager: selectedPackageManagerConfig.value.id, jsrInfo: null, dev: true, }) @@ -47,7 +55,7 @@ function getTypesInstallParts() { function getRunParts(command?: string) { return getRunCommandParts({ packageName: props.packageName, - packageManager: props.selectedPm, + packageManager: selectedPackageManagerConfig.value.id, jsrInfo: props.jsrInfo, command, isBinaryOnly: false, @@ -58,7 +66,7 @@ function getCreateParts() { if (!props.createPackageInfo) return [] return getExecuteCommandParts({ packageName: props.createPackageInfo.packageName, - packageManager: props.selectedPm, + packageManager: selectedPackageManagerConfig.value.id, jsrInfo: null, isCreatePackage: true, }) @@ -145,7 +153,11 @@ function copyCreateCommand() {

{{ $t('package.get_started.dev_dependency_hint') }}

- + $
- + $

{{ $t('package.run.locally') }}

- + $
- + $ { const createCommandSection = page.locator('[data-testid="create-command"]').first() await expect(createCommandSection).toBeVisible() - const activePm = await page.locator('[data-pm]').first().getAttribute('data-pm') - const commandRow = createCommandSection.locator(`[data-pm-additional-cmd="${activePm}"]`) + const commandRow = createCommandSection.locator('code[data-pm-additional-cmd]') await expect(commandRow).toBeVisible() await expect(commandRow).toContainText(/create vite/i) @@ -42,8 +41,7 @@ test.describe('Create Command', () => { const createCommandSection = page.locator('[data-testid="create-command"]').first() await expect(createCommandSection).toBeVisible() - const activePm = await page.locator('[data-pm]').first().getAttribute('data-pm') - const commandRow = createCommandSection.locator(`[data-pm-additional-cmd="${activePm}"]`) + const commandRow = createCommandSection.locator('code[data-pm-additional-cmd]') await expect(commandRow).toBeVisible() await expect(commandRow).toContainText(/create next-app/i) @@ -63,8 +61,7 @@ test.describe('Create Command', () => { // nuxt has create-nuxt package, so command is "npm create nuxt" const createCommandSection = page.locator('[data-testid="create-command"]').first() await expect(createCommandSection).toBeVisible() - const activePm = await page.locator('[data-pm]').first().getAttribute('data-pm') - const commandRow = createCommandSection.locator(`[data-pm-additional-cmd="${activePm}"]`) + const commandRow = createCommandSection.locator('code[data-pm-additional-cmd]') await expect(commandRow).toBeVisible() await expect(commandRow).toContainText(/create nuxt/i) }) From bf168a8550f8ecbfedb5bb7fc18d51064d71338f Mon Sep 17 00:00:00 2001 From: Roman Date: Fri, 23 Oct 2026 18:23:36 +0100 Subject: [PATCH 5/6] fix hydration --- app/components/Package/Install/AdditionalCommands.vue | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/components/Package/Install/AdditionalCommands.vue b/app/components/Package/Install/AdditionalCommands.vue index 56411ce8fe..0e42a13670 100644 --- a/app/components/Package/Install/AdditionalCommands.vue +++ b/app/components/Package/Install/AdditionalCommands.vue @@ -17,9 +17,13 @@ const props = defineProps<{ selectedPm: PackageManagerId }>() +const isMounted = ref(false) +onMounted(() => { + isMounted.value = true +}) + const resolvedPm = computed(() => { - if (import.meta.server) return 'npm' - return props.selectedPm + return isMounted.value ? props.selectedPm : 'npm' }) const selectedPackageManagerConfig = computed(() => getPackageManagerConfig(resolvedPm.value)) From 6be69a7b75456686dee623cd9a774cd70ca1e0ae Mon Sep 17 00:00:00 2001 From: Roman Date: Fri, 23 Oct 2026 18:54:27 +0100 Subject: [PATCH 6/6] try again --- app/components/Package/Install/Dropdown.vue | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/app/components/Package/Install/Dropdown.vue b/app/components/Package/Install/Dropdown.vue index df6706f9a9..43d2270d10 100644 --- a/app/components/Package/Install/Dropdown.vue +++ b/app/components/Package/Install/Dropdown.vue @@ -3,6 +3,7 @@ import type { JsrPackageInfo } from '#shared/types/jsr' import type { SlimPackumentVersion } from '#shared/types' import type { DevDependencySuggestion } from '#shared/utils/dev-dependency' import type { PublishSecurityDowngrade } from '~/utils/publish-security' +import { getPackageManagerConfig } from '~/utils/install-command' const props = defineProps<{ packageName: string @@ -19,6 +20,11 @@ const props = defineProps<{ headingId: string }>() +const isMounted = ref(false) +onMounted(() => { + isMounted.value = true +}) + const { selectedPM, showTypesInInstall, copied, copyInstallCommand } = useInstallCommand( () => props.packageName, () => props.requestedVersion ?? null, @@ -27,6 +33,12 @@ const { selectedPM, showTypesInInstall, copied, copyInstallCommand } = useInstal () => props.installVersionOverride ?? null, ) +const resolvedPM = computed(() => { + return isMounted.value ? selectedPM.value : 'npm' +}) + +const selectedPackageManagerConfig = computed(() => getPackageManagerConfig(resolvedPM.value)) + const { announce } = useCommandPalette() const { polite } = useAnnouncer() async function copyInstallCommandWithAnnounce() { @@ -141,7 +153,7 @@ onPrehydrate(el => { { :show-types="showTypesInInstall" :executable-info="executableInfo" :create-package-info="createPackageInfo" - :selected-pm="selectedPM" + :selected-pm="resolvedPM" />