From 971cc9457a331e68985b3a8167a9252060bda2a8 Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Mon, 2 Feb 2026 15:28:42 +0100 Subject: [PATCH 01/29] cli: Add pluginPackage support to backend-plugin-module template Signed-off-by: Vincenzo Scamporlino --- .changeset/ninety-suits-drum.md | 5 ++ .../collectPortableTemplateInput.test.ts | 66 +++++++++++++++++++ .../collectPortableTemplateInput.ts | 45 ++++++++++++- packages/cli-module-new/src/lib/types.ts | 8 ++- .../backend-plugin-module/package.json.hbs | 3 +- .../package.json.hbs | 3 +- .../portable-template.yaml | 1 + 7 files changed, 127 insertions(+), 4 deletions(-) create mode 100644 .changeset/ninety-suits-drum.md diff --git a/.changeset/ninety-suits-drum.md b/.changeset/ninety-suits-drum.md new file mode 100644 index 0000000000..1eb0a7f1db --- /dev/null +++ b/.changeset/ninety-suits-drum.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +The `new` command now prompts for the plugin package name when creating a backend plugin module, in order to properly populate the `package.json` file. diff --git a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.test.ts b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.test.ts index 905ec0b0c5..ee45f7a708 100644 --- a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.test.ts +++ b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.test.ts @@ -149,4 +149,70 @@ describe('collectTemplateParams', () => { ], }); }); + + describe('backend-plugin-module with pluginPackage', () => { + const backendModuleOptions = { + ...baseOptions, + template: { + name: 'test-module', + role: 'backend-plugin-module' as const, + files: [], + values: {}, + }, + }; + + it('should auto-fill pluginPackage for catalog plugin without prompting', async () => { + await expect( + collectPortableTemplateInput({ + ...backendModuleOptions, + prefilledParams: { + pluginId: 'catalog', + moduleId: 'my-module', + }, + }), + ).resolves.toEqual({ + roleParams: { + role: 'backend-plugin-module', + pluginId: 'catalog', + moduleId: 'my-module', + pluginPackage: '@backstage/plugin-catalog-backend', + }, + owner: undefined, + version: '0.1.0', + license: 'Apache-2.0', + private: true, + packageName: '@internal/plugin-catalog-backend-module-my-module', + packagePath: 'plugins/catalog-backend-module-my-module', + }); + }); + + it('should prompt for pluginPackage for unknown plugins', async () => { + jest.spyOn(inquirer, 'prompt').mockResolvedValueOnce({ + pluginPackage: '@mycompany/plugin-custom-backend', + }); + + await expect( + collectPortableTemplateInput({ + ...backendModuleOptions, + prefilledParams: { + pluginId: 'custom', + moduleId: 'my-extension', + }, + }), + ).resolves.toEqual({ + roleParams: { + role: 'backend-plugin-module', + pluginId: 'custom', + moduleId: 'my-extension', + pluginPackage: '@mycompany/plugin-custom-backend', + }, + owner: undefined, + version: '0.1.0', + license: 'Apache-2.0', + private: true, + packageName: '@internal/plugin-custom-backend-module-my-extension', + packagePath: 'plugins/custom-backend-module-my-extension', + }); + }); + }); }); diff --git a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts index 63e3791a49..d7521407dc 100644 --- a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts +++ b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts @@ -28,6 +28,13 @@ import { import { PortableTemplate } from '../types'; import { resolvePackageParams } from './resolvePackageParams'; +const knownPluginPackages: Record = { + auth: '@backstage/plugin-auth-backend', + catalog: '@backstage/plugin-catalog-backend', + events: '@backstage/plugin-events-backend', + scaffolder: '@backstage/plugin-scaffolder-backend', +}; + type CollectTemplateParamsOptions = { config: PortableTemplateConfig; template: PortableTemplate; @@ -80,11 +87,16 @@ export async function collectPortableTemplateInput( ...promptAnswers, }; + const pluginPackage = + knownPluginPackages[answers.pluginId as string] ?? + (answers.pluginPackage as string); + const roleParams = { role: template.role, name: answers.name, pluginId: answers.pluginId, moduleId: answers.moduleId, + pluginPackage, } as PortableTemplateInputRoleParams; const packageParams = resolvePackageParams({ @@ -153,6 +165,26 @@ export function moduleIdIdPrompt(): DistinctQuestion { }; } +export function pluginPackagePrompt(): DistinctQuestion { + return { + type: 'input', + name: 'pluginPackage', + message: + 'Enter the package name of the plugin this module extends (e.g. @backstage/plugin-catalog-backend) [required]', + validate: (value: string) => { + if (!value) { + return 'Please enter the package name of the plugin'; + } + if (!isValidNpmPackageName(value)) { + return 'Please enter a valid npm package name (e.g. @backstage/plugin-catalog-backend or my-plugin-backend)'; + } + return true; + }, + when: (answers: PortableTemplateParams) => + !knownPluginPackages[answers.pluginId as string], + }; +} + export function getPromptsForRole( role: PortableTemplateRole, ): Array { @@ -169,8 +201,9 @@ export function getPromptsForRole( case 'backend-plugin': return [pluginIdPrompt()]; case 'frontend-plugin-module': - case 'backend-plugin-module': return [pluginIdPrompt(), moduleIdIdPrompt()]; + case 'backend-plugin-module': + return [pluginIdPrompt(), moduleIdIdPrompt(), pluginPackagePrompt()]; default: return []; } @@ -195,3 +228,13 @@ export function ownerPrompt(): DistinctQuestion { }, }; } + +// Reuses the same pattern as namePrompt/pluginIdPrompt but extended to support npm scopes +// Matches: @scope/package-name, @scope/package, package-name, package +const packageNamePattern = /^[a-z0-9]+(-[a-z0-9]+)*$/; +const scopedPackageNamePattern = + /^@[a-z0-9]+(-[a-z0-9]+)*\/[a-z0-9]+(-[a-z0-9]+)*$/; + +function isValidNpmPackageName(name: string) { + return packageNamePattern.test(name) || scopedPackageNamePattern.test(name); +} diff --git a/packages/cli-module-new/src/lib/types.ts b/packages/cli-module-new/src/lib/types.ts index 83a195a43a..913c74b672 100644 --- a/packages/cli-module-new/src/lib/types.ts +++ b/packages/cli-module-new/src/lib/types.ts @@ -94,9 +94,15 @@ export type PortableTemplateInputRoleParams = pluginId: string; } | { - role: 'frontend-plugin-module' | 'backend-plugin-module'; + role: 'frontend-plugin-module'; pluginId: string; moduleId: string; + } + | { + role: 'backend-plugin-module'; + pluginId: string; + moduleId: string; + pluginPackage: string; }; export type PortableTemplateInput = { diff --git a/packages/cli-module-new/templates/backend-plugin-module/package.json.hbs b/packages/cli-module-new/templates/backend-plugin-module/package.json.hbs index c34f7e0646..5e21e5c2eb 100644 --- a/packages/cli-module-new/templates/backend-plugin-module/package.json.hbs +++ b/packages/cli-module-new/templates/backend-plugin-module/package.json.hbs @@ -10,7 +10,8 @@ }, "backstage": { "role": "backend-plugin-module", - "pluginId": "{{pluginId}}" + "pluginId": "{{pluginId}}", + "pluginPackage": "{{pluginPackage}}" }, "scripts": { "start": "backstage-cli package start", diff --git a/packages/cli-module-new/templates/scaffolder-backend-module/package.json.hbs b/packages/cli-module-new/templates/scaffolder-backend-module/package.json.hbs index 72cb370443..bb7704964d 100644 --- a/packages/cli-module-new/templates/scaffolder-backend-module/package.json.hbs +++ b/packages/cli-module-new/templates/scaffolder-backend-module/package.json.hbs @@ -10,7 +10,8 @@ }, "backstage": { "role": "backend-plugin-module", - "pluginId": "scaffolder" + "pluginId": "scaffolder", + "pluginPackage": "@backstage/plugin-scaffolder-backend" }, "scripts": { "start": "backstage-cli package start", diff --git a/packages/cli-module-new/templates/scaffolder-backend-module/portable-template.yaml b/packages/cli-module-new/templates/scaffolder-backend-module/portable-template.yaml index a131c14062..fc7669cef3 100644 --- a/packages/cli-module-new/templates/scaffolder-backend-module/portable-template.yaml +++ b/packages/cli-module-new/templates/scaffolder-backend-module/portable-template.yaml @@ -3,4 +3,5 @@ role: backend-plugin-module description: A module exporting custom actions for @backstage/plugin-scaffolder-backend values: pluginId: scaffolder + pluginPackage: '@backstage/plugin-scaffolder-backend' moduleVar: '{{ camelCase pluginId }}Module{{ upperFirst ( camelCase moduleId ) }}' From 7191abef8662d94ec7e1a46a99320d201c13f94f Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Wed, 11 Feb 2026 15:13:05 +0100 Subject: [PATCH 02/29] Add support for pluginPackage to frontend modules Signed-off-by: Vincenzo Scamporlino --- .../collectPortableTemplateInput.test.ts | 66 +++++++++++++++++++ .../collectPortableTemplateInput.ts | 64 ++++++++++++++---- packages/cli-module-new/src/lib/types.ts | 1 + 3 files changed, 120 insertions(+), 11 deletions(-) diff --git a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.test.ts b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.test.ts index ee45f7a708..c0cb4dd563 100644 --- a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.test.ts +++ b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.test.ts @@ -215,4 +215,70 @@ describe('collectTemplateParams', () => { }); }); }); + + describe('frontend-plugin-module with pluginPackage', () => { + const frontendModuleOptions = { + ...baseOptions, + template: { + name: 'test-module', + role: 'frontend-plugin-module' as const, + files: [], + values: {}, + }, + }; + + it('should auto-fill pluginPackage for catalog plugin without prompting', async () => { + await expect( + collectPortableTemplateInput({ + ...frontendModuleOptions, + prefilledParams: { + pluginId: 'catalog', + moduleId: 'my-module', + }, + }), + ).resolves.toEqual({ + roleParams: { + role: 'frontend-plugin-module', + pluginId: 'catalog', + moduleId: 'my-module', + pluginPackage: '@backstage/plugin-catalog', + }, + owner: undefined, + version: '0.1.0', + license: 'Apache-2.0', + private: true, + packageName: '@internal/plugin-catalog-module-my-module', + packagePath: 'plugins/catalog-module-my-module', + }); + }); + + it('should prompt for pluginPackage for unknown plugins', async () => { + jest.spyOn(inquirer, 'prompt').mockResolvedValueOnce({ + pluginPackage: '@mycompany/plugin-custom', + }); + + await expect( + collectPortableTemplateInput({ + ...frontendModuleOptions, + prefilledParams: { + pluginId: 'custom', + moduleId: 'my-extension', + }, + }), + ).resolves.toEqual({ + roleParams: { + role: 'frontend-plugin-module', + pluginId: 'custom', + moduleId: 'my-extension', + pluginPackage: '@mycompany/plugin-custom', + }, + owner: undefined, + version: '0.1.0', + license: 'Apache-2.0', + private: true, + packageName: '@internal/plugin-custom-module-my-extension', + packagePath: 'plugins/custom-module-my-extension', + }); + }); + }); }); diff --git a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts index d7521407dc..d1676ce931 100644 --- a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts +++ b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts @@ -28,11 +28,32 @@ import { import { PortableTemplate } from '../types'; import { resolvePackageParams } from './resolvePackageParams'; -const knownPluginPackages: Record = { +const knownBackendPluginPackages: Record = { + app: '@backstage/plugin-app-backend', auth: '@backstage/plugin-auth-backend', catalog: '@backstage/plugin-catalog-backend', events: '@backstage/plugin-events-backend', + kubernetes: '@backstage/plugin-kubernetes-backend', + notifications: '@backstage/plugin-notifications-backend', + permission: '@backstage/plugin-permission-backend', + proxy: '@backstage/plugin-proxy-backend', scaffolder: '@backstage/plugin-scaffolder-backend', + search: '@backstage/plugin-search-backend', + techdocs: '@backstage/plugin-techdocs-backend', +}; + +const knownFrontendPluginPackages: Record = { + app: '@backstage/plugin-app', + auth: '@backstage/plugin-auth', + catalog: '@backstage/plugin-catalog', + events: '@backstage/plugin-events', + kubernetes: '@backstage/plugin-kubernetes', + notifications: '@backstage/plugin-notifications', + permission: '@backstage/plugin-permission', + proxy: '@backstage/plugin-proxy', + scaffolder: '@backstage/plugin-scaffolder', + search: '@backstage/plugin-search', + techdocs: '@backstage/plugin-techdocs', }; type CollectTemplateParamsOptions = { @@ -87,9 +108,20 @@ export async function collectPortableTemplateInput( ...promptAnswers, }; - const pluginPackage = - knownPluginPackages[answers.pluginId as string] ?? - (answers.pluginPackage as string); + let pluginPackage: string | undefined; + if ( + template.role === 'backend-plugin-module' || + template.role === 'frontend-plugin-module' + ) { + const knownPackages = + template.role === 'backend-plugin-module' + ? knownBackendPluginPackages + : knownFrontendPluginPackages; + + pluginPackage = + knownPackages[answers.pluginId as string] ?? + (answers.pluginPackage as string); + } const roleParams = { role: template.role, @@ -165,23 +197,34 @@ export function moduleIdIdPrompt(): DistinctQuestion { }; } -export function pluginPackagePrompt(): DistinctQuestion { +export function pluginPackagePrompt( + role: 'backend-plugin-module' | 'frontend-plugin-module', +): DistinctQuestion { + const knownPackages = + role === 'backend-plugin-module' + ? knownBackendPluginPackages + : knownFrontendPluginPackages; + + const examplePackage = + role === 'backend-plugin-module' + ? '@backstage/plugin-catalog-backend' + : '@backstage/plugin-catalog'; + return { type: 'input', name: 'pluginPackage', - message: - 'Enter the package name of the plugin this module extends (e.g. @backstage/plugin-catalog-backend) [required]', + message: `Enter the package name of the plugin this module extends (e.g. ${examplePackage}) [required]`, validate: (value: string) => { if (!value) { return 'Please enter the package name of the plugin'; } if (!isValidNpmPackageName(value)) { - return 'Please enter a valid npm package name (e.g. @backstage/plugin-catalog-backend or my-plugin-backend)'; + return `Please enter a valid npm package name (e.g. ${examplePackage} or my-plugin)`; } return true; }, when: (answers: PortableTemplateParams) => - !knownPluginPackages[answers.pluginId as string], + !knownPackages[answers.pluginId as string], }; } @@ -201,9 +244,8 @@ export function getPromptsForRole( case 'backend-plugin': return [pluginIdPrompt()]; case 'frontend-plugin-module': - return [pluginIdPrompt(), moduleIdIdPrompt()]; case 'backend-plugin-module': - return [pluginIdPrompt(), moduleIdIdPrompt(), pluginPackagePrompt()]; + return [pluginIdPrompt(), moduleIdIdPrompt(), pluginPackagePrompt(role)]; default: return []; } diff --git a/packages/cli-module-new/src/lib/types.ts b/packages/cli-module-new/src/lib/types.ts index 913c74b672..6c6cd8b584 100644 --- a/packages/cli-module-new/src/lib/types.ts +++ b/packages/cli-module-new/src/lib/types.ts @@ -97,6 +97,7 @@ export type PortableTemplateInputRoleParams = role: 'frontend-plugin-module'; pluginId: string; moduleId: string; + pluginPackage: string; } | { role: 'backend-plugin-module'; From a84b9e91dfd6a220ba9d62bd80e4caae50c6aa1e Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Wed, 11 Feb 2026 15:43:35 +0100 Subject: [PATCH 03/29] Added missing pluginPackage Signed-off-by: Vincenzo Scamporlino --- .../lib/preparation/resolvePackageParams.test.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/cli-module-new/src/lib/preparation/resolvePackageParams.test.ts b/packages/cli-module-new/src/lib/preparation/resolvePackageParams.test.ts index f279b702b1..36bb00b324 100644 --- a/packages/cli-module-new/src/lib/preparation/resolvePackageParams.test.ts +++ b/packages/cli-module-new/src/lib/preparation/resolvePackageParams.test.ts @@ -80,14 +80,24 @@ describe.each([ }, ], [ - { role: 'frontend-plugin-module', pluginId: 'test1', moduleId: 'test2' }, + { + role: 'frontend-plugin-module', + pluginId: 'test1', + moduleId: 'test2', + pluginPackage: '@backstage/plugin-test1', + }, { packageName: '@internal/plugin-test1-module-test2', packagePath: 'plugins/test1-module-test2', }, ], [ - { role: 'backend-plugin-module', pluginId: 'test1', moduleId: 'test2' }, + { + role: 'backend-plugin-module', + pluginId: 'test1', + moduleId: 'test2', + pluginPackage: '@backstage/plugin-test1-backend', + }, { packageName: '@internal/plugin-test1-backend-module-test2', packagePath: 'plugins/test1-backend-module-test2', From 14008190ee8c58a98230d1847ebeb6bb19238492 Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Wed, 11 Feb 2026 15:47:54 +0100 Subject: [PATCH 04/29] Update prompt message for plugin package name Signed-off-by: Vincenzo Scamporlino --- .changeset/ninety-suits-drum.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/ninety-suits-drum.md b/.changeset/ninety-suits-drum.md index 1eb0a7f1db..724b46dabf 100644 --- a/.changeset/ninety-suits-drum.md +++ b/.changeset/ninety-suits-drum.md @@ -2,4 +2,4 @@ '@backstage/cli': patch --- -The `new` command now prompts for the plugin package name when creating a backend plugin module, in order to properly populate the `package.json` file. +The `new` command now prompts for the plugin package name when creating plugin modules, in order to properly populate the `package.json` file. From 994b82ca8493fecd74a05bda264c31ef4b32e266 Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Thu, 19 Feb 2026 13:12:06 +0100 Subject: [PATCH 05/29] Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Vincenzo Scamporlino --- .../src/lib/preparation/collectPortableTemplateInput.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts index d1676ce931..9c02cfc540 100644 --- a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts +++ b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts @@ -46,7 +46,7 @@ const knownFrontendPluginPackages: Record = { app: '@backstage/plugin-app', auth: '@backstage/plugin-auth', catalog: '@backstage/plugin-catalog', - events: '@backstage/plugin-events', + kubernetes: '@backstage/plugin-kubernetes', notifications: '@backstage/plugin-notifications', permission: '@backstage/plugin-permission', From 9b261e37ba93cca64995a6297024331a7615bd49 Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Tue, 10 Mar 2026 20:32:35 +0100 Subject: [PATCH 06/29] Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Vincenzo Scamporlino --- .../src/lib/preparation/collectPortableTemplateInput.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts index 9c02cfc540..f4f19d1b4e 100644 --- a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts +++ b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts @@ -46,7 +46,6 @@ const knownFrontendPluginPackages: Record = { app: '@backstage/plugin-app', auth: '@backstage/plugin-auth', catalog: '@backstage/plugin-catalog', - kubernetes: '@backstage/plugin-kubernetes', notifications: '@backstage/plugin-notifications', permission: '@backstage/plugin-permission', From e8ed881fca8ab284934b99183d58e11bf567334f Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Tue, 10 Mar 2026 20:42:47 +0100 Subject: [PATCH 07/29] Update package name validation regex to support additional characters Signed-off-by: Vincenzo Scamporlino --- .../src/lib/preparation/collectPortableTemplateInput.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts index f4f19d1b4e..b40a35da6d 100644 --- a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts +++ b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts @@ -272,9 +272,9 @@ export function ownerPrompt(): DistinctQuestion { // Reuses the same pattern as namePrompt/pluginIdPrompt but extended to support npm scopes // Matches: @scope/package-name, @scope/package, package-name, package -const packageNamePattern = /^[a-z0-9]+(-[a-z0-9]+)*$/; +const packageNamePattern = /^[a-z0-9][a-z0-9._-]*$/; const scopedPackageNamePattern = - /^@[a-z0-9]+(-[a-z0-9]+)*\/[a-z0-9]+(-[a-z0-9]+)*$/; + /^@[a-z0-9][a-z0-9._-]*\/[a-z0-9][a-z0-9._-]*$/; function isValidNpmPackageName(name: string) { return packageNamePattern.test(name) || scopedPackageNamePattern.test(name); From 5ebd4800d7b7c5b6badef0e6791a8efb6f3ae53d Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Tue, 10 Mar 2026 20:45:55 +0100 Subject: [PATCH 08/29] Remove pluginPackage from portable-template.yaml Signed-off-by: Vincenzo Scamporlino --- .../templates/scaffolder-backend-module/portable-template.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/cli-module-new/templates/scaffolder-backend-module/portable-template.yaml b/packages/cli-module-new/templates/scaffolder-backend-module/portable-template.yaml index fc7669cef3..a131c14062 100644 --- a/packages/cli-module-new/templates/scaffolder-backend-module/portable-template.yaml +++ b/packages/cli-module-new/templates/scaffolder-backend-module/portable-template.yaml @@ -3,5 +3,4 @@ role: backend-plugin-module description: A module exporting custom actions for @backstage/plugin-scaffolder-backend values: pluginId: scaffolder - pluginPackage: '@backstage/plugin-scaffolder-backend' moduleVar: '{{ camelCase pluginId }}Module{{ upperFirst ( camelCase moduleId ) }}' From 194d4b11498a47e170189e50691b3879889f0cb6 Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Tue, 10 Mar 2026 20:46:07 +0100 Subject: [PATCH 09/29] Add pluginPackage field to package.json template for frontend plugin module Signed-off-by: Vincenzo Scamporlino --- .../templates/frontend-plugin-module/package.json.hbs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/cli-module-new/templates/frontend-plugin-module/package.json.hbs b/packages/cli-module-new/templates/frontend-plugin-module/package.json.hbs index d0511d96c0..24a6281ff0 100644 --- a/packages/cli-module-new/templates/frontend-plugin-module/package.json.hbs +++ b/packages/cli-module-new/templates/frontend-plugin-module/package.json.hbs @@ -11,7 +11,8 @@ }, "backstage": { "role": "frontend-plugin-module", - "pluginId": "{{pluginId}}" + "pluginId": "{{pluginId}}", + "pluginPackage": "{{pluginPackage}}" }, "sideEffects": false, "scripts": { From 1b1f7a87aa44a461259e8ac34a79cca6453f8d1e Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Tue, 10 Mar 2026 21:12:26 +0100 Subject: [PATCH 10/29] Update packages/cli/src/modules/new/lib/preparation/collectPortableTemplateInput.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Vincenzo Scamporlino --- .../src/lib/preparation/collectPortableTemplateInput.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts index b40a35da6d..c5dddc7df5 100644 --- a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts +++ b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts @@ -118,8 +118,8 @@ export async function collectPortableTemplateInput( : knownFrontendPluginPackages; pluginPackage = - knownPackages[answers.pluginId as string] ?? - (answers.pluginPackage as string); + (answers.pluginPackage as string) ?? + knownPackages[answers.pluginId as string]; } const roleParams = { From 5c7186b5d4d51dd8e7ffe70995af92ea3aa820e1 Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Tue, 10 Mar 2026 21:28:26 +0100 Subject: [PATCH 11/29] Refactor plugin package name handling to use a centralized mapping for backend plugins Signed-off-by: Vincenzo Scamporlino --- .../src/commands/repo/fix.ts | 6 +++--- .../collectPortableTemplateInput.ts | 20 +++---------------- 2 files changed, 6 insertions(+), 20 deletions(-) diff --git a/packages/cli-module-maintenance/src/commands/repo/fix.ts b/packages/cli-module-maintenance/src/commands/repo/fix.ts index 4d6445fe86..399234ff2e 100644 --- a/packages/cli-module-maintenance/src/commands/repo/fix.ts +++ b/packages/cli-module-maintenance/src/commands/repo/fix.ts @@ -347,7 +347,7 @@ export function fixPluginId(pkg: FixablePackage) { } } -const backendPluginPackageNameByPluginId = new Map( +export const knownBackendPluginPackageNameByPluginId = Object.fromEntries( [ 'app', 'auth', @@ -356,6 +356,7 @@ const backendPluginPackageNameByPluginId = new Map( 'kubernetes', 'notifications', 'permission', + 'proxy', 'scaffolder', 'search', 'signals', @@ -415,8 +416,7 @@ export function fixPluginPackages( p => p.packageJson.backstage?.pluginId === pluginId && p.packageJson.backstage?.role === targetRole, - )?.packageJson.name ?? backendPluginPackageNameByPluginId.get(pluginId); - + )?.packageJson.name ?? knownBackendPluginPackageNameByPluginId[pluginId]; if (!pluginPkgName) { // If we can't find a matching package in the repo but one is declared, skip if (pkgBackstage.pluginPackage) { diff --git a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts index c5dddc7df5..e35c58de9f 100644 --- a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts +++ b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts @@ -27,20 +27,7 @@ import { } from '../types'; import { PortableTemplate } from '../types'; import { resolvePackageParams } from './resolvePackageParams'; - -const knownBackendPluginPackages: Record = { - app: '@backstage/plugin-app-backend', - auth: '@backstage/plugin-auth-backend', - catalog: '@backstage/plugin-catalog-backend', - events: '@backstage/plugin-events-backend', - kubernetes: '@backstage/plugin-kubernetes-backend', - notifications: '@backstage/plugin-notifications-backend', - permission: '@backstage/plugin-permission-backend', - proxy: '@backstage/plugin-proxy-backend', - scaffolder: '@backstage/plugin-scaffolder-backend', - search: '@backstage/plugin-search-backend', - techdocs: '@backstage/plugin-techdocs-backend', -}; +import { knownBackendPluginPackageNameByPluginId } from '../../../maintenance/commands/repo/fix'; const knownFrontendPluginPackages: Record = { app: '@backstage/plugin-app', @@ -48,10 +35,9 @@ const knownFrontendPluginPackages: Record = { catalog: '@backstage/plugin-catalog', kubernetes: '@backstage/plugin-kubernetes', notifications: '@backstage/plugin-notifications', - permission: '@backstage/plugin-permission', - proxy: '@backstage/plugin-proxy', scaffolder: '@backstage/plugin-scaffolder', search: '@backstage/plugin-search', + signals: '@backstage/plugin-signals', techdocs: '@backstage/plugin-techdocs', }; @@ -114,7 +100,7 @@ export async function collectPortableTemplateInput( ) { const knownPackages = template.role === 'backend-plugin-module' - ? knownBackendPluginPackages + ? knownBackendPluginPackageNameByPluginId : knownFrontendPluginPackages; pluginPackage = From f22a0822aba60c10a6eae1ae88fda2bc5cbb2174 Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Tue, 10 Mar 2026 22:37:53 +0100 Subject: [PATCH 12/29] Rename knownFrontendPluginPackages to knownFrontendPluginPackageNameByPluginId for consistency Signed-off-by: Vincenzo Scamporlino --- .../src/lib/preparation/collectPortableTemplateInput.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts index e35c58de9f..169a064869 100644 --- a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts +++ b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts @@ -29,7 +29,7 @@ import { PortableTemplate } from '../types'; import { resolvePackageParams } from './resolvePackageParams'; import { knownBackendPluginPackageNameByPluginId } from '../../../maintenance/commands/repo/fix'; -const knownFrontendPluginPackages: Record = { +const knownFrontendPluginPackageNameByPluginId: Record = { app: '@backstage/plugin-app', auth: '@backstage/plugin-auth', catalog: '@backstage/plugin-catalog', @@ -101,7 +101,7 @@ export async function collectPortableTemplateInput( const knownPackages = template.role === 'backend-plugin-module' ? knownBackendPluginPackageNameByPluginId - : knownFrontendPluginPackages; + : knownFrontendPluginPackageNameByPluginId; pluginPackage = (answers.pluginPackage as string) ?? @@ -187,8 +187,8 @@ export function pluginPackagePrompt( ): DistinctQuestion { const knownPackages = role === 'backend-plugin-module' - ? knownBackendPluginPackages - : knownFrontendPluginPackages; + ? knownBackendPluginPackageNameByPluginId + : knownFrontendPluginPackageNameByPluginId; const examplePackage = role === 'backend-plugin-module' From 7f8daf93fb6bd8ba6bea425cd64162fe183b5cbc Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Tue, 10 Mar 2026 23:15:03 +0100 Subject: [PATCH 13/29] Add centralized mapping for known plugin packages in knownPluginPackages.ts Signed-off-by: Vincenzo Scamporlino --- .../src/commands/repo/fix.ts | 18 +------- .../collectPortableTemplateInput.ts | 17 ++------ packages/cli/src/lib/knownPluginPackages.ts | 43 +++++++++++++++++++ 3 files changed, 48 insertions(+), 30 deletions(-) create mode 100644 packages/cli/src/lib/knownPluginPackages.ts diff --git a/packages/cli-module-maintenance/src/commands/repo/fix.ts b/packages/cli-module-maintenance/src/commands/repo/fix.ts index 399234ff2e..34b7c93288 100644 --- a/packages/cli-module-maintenance/src/commands/repo/fix.ts +++ b/packages/cli-module-maintenance/src/commands/repo/fix.ts @@ -30,6 +30,7 @@ import { extname, } from 'node:path'; import { targetPaths } from '@backstage/cli-common'; +import { knownBackendPluginPackageNameByPluginId } from '../../../../lib/knownPluginPackages'; const SCRIPT_EXTS = ['.js', '.jsx', '.ts', '.tsx', '.json']; @@ -347,23 +348,6 @@ export function fixPluginId(pkg: FixablePackage) { } } -export const knownBackendPluginPackageNameByPluginId = Object.fromEntries( - [ - 'app', - 'auth', - 'catalog', - 'events', - 'kubernetes', - 'notifications', - 'permission', - 'proxy', - 'scaffolder', - 'search', - 'signals', - 'techdocs', - ].map(pluginId => [pluginId, `@backstage/plugin-${pluginId}-backend`]), -); - const pluginPackageRoles: Array = [ 'frontend-plugin', 'backend-plugin', diff --git a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts index 169a064869..a65c5f04d2 100644 --- a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts +++ b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts @@ -27,19 +27,10 @@ import { } from '../types'; import { PortableTemplate } from '../types'; import { resolvePackageParams } from './resolvePackageParams'; -import { knownBackendPluginPackageNameByPluginId } from '../../../maintenance/commands/repo/fix'; - -const knownFrontendPluginPackageNameByPluginId: Record = { - app: '@backstage/plugin-app', - auth: '@backstage/plugin-auth', - catalog: '@backstage/plugin-catalog', - kubernetes: '@backstage/plugin-kubernetes', - notifications: '@backstage/plugin-notifications', - scaffolder: '@backstage/plugin-scaffolder', - search: '@backstage/plugin-search', - signals: '@backstage/plugin-signals', - techdocs: '@backstage/plugin-techdocs', -}; +import { + knownBackendPluginPackageNameByPluginId, + knownFrontendPluginPackageNameByPluginId, +} from '../../../../lib/knownPluginPackages'; type CollectTemplateParamsOptions = { config: PortableTemplateConfig; diff --git a/packages/cli/src/lib/knownPluginPackages.ts b/packages/cli/src/lib/knownPluginPackages.ts new file mode 100644 index 0000000000..88bfdf25e0 --- /dev/null +++ b/packages/cli/src/lib/knownPluginPackages.ts @@ -0,0 +1,43 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const knownPluginIds = [ + 'app', + 'auth', + 'catalog', + 'events', + 'kubernetes', + 'notifications', + 'permission', + 'proxy', + 'scaffolder', + 'search', + 'signals', + 'techdocs', +]; + +export const knownBackendPluginPackageNameByPluginId: Record = + Object.fromEntries( + knownPluginIds.map(pluginId => [ + pluginId, + `@backstage/plugin-${pluginId}-backend`, + ]), + ); + +export const knownFrontendPluginPackageNameByPluginId: Record = + Object.fromEntries( + knownPluginIds.map(pluginId => [pluginId, `@backstage/plugin-${pluginId}`]), + ); From 5f0daba1d53c37f90c724fb0e0df4cf6a75a455a Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Mon, 16 Mar 2026 22:57:25 +0100 Subject: [PATCH 14/29] Enhance plugin package handling by pre-populating known packages in collectPortableTemplateInput Signed-off-by: Vincenzo Scamporlino --- .../collectPortableTemplateInput.ts | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts index a65c5f04d2..2e7170f81f 100644 --- a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts +++ b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts @@ -59,12 +59,29 @@ export async function collectPortableTemplateInput( deprecatedParams.pluginId = prefilledParams.id; } - const parameters = { + const parameters: PortableTemplateParams = { ...template.values, ...prefilledParams, ...deprecatedParams, }; + // Pre-populate pluginPackage for known plugins so the prompt is skipped + if ( + (template.role === 'backend-plugin-module' || + template.role === 'frontend-plugin-module') && + parameters.pluginId && + !parameters.pluginPackage + ) { + const knownPackages = + template.role === 'backend-plugin-module' + ? knownBackendPluginPackageNameByPluginId + : knownFrontendPluginPackageNameByPluginId; + const knownPackage = knownPackages[parameters.pluginId as string]; + if (knownPackage) { + parameters.pluginPackage = knownPackage; + } + } + const needsAnswer = []; const prefilledAnswers = {} as PortableTemplateParams; for (const prompt of prompts) { From 11060e329a5beba77cefa8d40521dea969e3843d Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Mon, 16 Mar 2026 22:58:38 +0100 Subject: [PATCH 15/29] Add centralized known plugin package exports and update imports Signed-off-by: Vincenzo Scamporlino --- packages/cli-common/report.api.md | 6 ++++++ packages/cli-common/src/index.ts | 4 ++++ .../src/lib => cli-common/src}/knownPluginPackages.ts | 10 ++++++++++ .../cli-module-maintenance/src/commands/repo/fix.ts | 2 +- .../lib/preparation/collectPortableTemplateInput.ts | 2 +- 5 files changed, 22 insertions(+), 2 deletions(-) rename packages/{cli/src/lib => cli-common/src}/knownPluginPackages.ts (86%) diff --git a/packages/cli-common/report.api.md b/packages/cli-common/report.api.md index ba649cacc9..74d5a24999 100644 --- a/packages/cli-common/report.api.md +++ b/packages/cli-common/report.api.md @@ -28,6 +28,12 @@ export function findPaths(searchDir: string): Paths; // @public export function isChildPath(base: string, path: string): boolean; +// @public +export const knownBackendPluginPackageNameByPluginId: Record; + +// @public +export const knownFrontendPluginPackageNameByPluginId: Record; + // @public export type OwnPaths = { dir: string; diff --git a/packages/cli-common/src/index.ts b/packages/cli-common/src/index.ts index e49eac0ee0..bfa0716097 100644 --- a/packages/cli-common/src/index.ts +++ b/packages/cli-common/src/index.ts @@ -33,3 +33,7 @@ export { type RunOnOutput, } from './run'; export { ExitCodeError } from './errors'; +export { + knownBackendPluginPackageNameByPluginId, + knownFrontendPluginPackageNameByPluginId, +} from './knownPluginPackages'; diff --git a/packages/cli/src/lib/knownPluginPackages.ts b/packages/cli-common/src/knownPluginPackages.ts similarity index 86% rename from packages/cli/src/lib/knownPluginPackages.ts rename to packages/cli-common/src/knownPluginPackages.ts index 88bfdf25e0..ae0d3f8942 100644 --- a/packages/cli/src/lib/knownPluginPackages.ts +++ b/packages/cli-common/src/knownPluginPackages.ts @@ -29,6 +29,11 @@ const knownPluginIds = [ 'techdocs', ]; +/** + * Maps known plugin IDs to their corresponding backend package names. + * + * @public + */ export const knownBackendPluginPackageNameByPluginId: Record = Object.fromEntries( knownPluginIds.map(pluginId => [ @@ -37,6 +42,11 @@ export const knownBackendPluginPackageNameByPluginId: Record = ]), ); +/** + * Maps known plugin IDs to their corresponding frontend package names. + * + * @public + */ export const knownFrontendPluginPackageNameByPluginId: Record = Object.fromEntries( knownPluginIds.map(pluginId => [pluginId, `@backstage/plugin-${pluginId}`]), diff --git a/packages/cli-module-maintenance/src/commands/repo/fix.ts b/packages/cli-module-maintenance/src/commands/repo/fix.ts index 34b7c93288..ffc044f42a 100644 --- a/packages/cli-module-maintenance/src/commands/repo/fix.ts +++ b/packages/cli-module-maintenance/src/commands/repo/fix.ts @@ -30,7 +30,7 @@ import { extname, } from 'node:path'; import { targetPaths } from '@backstage/cli-common'; -import { knownBackendPluginPackageNameByPluginId } from '../../../../lib/knownPluginPackages'; +import { knownBackendPluginPackageNameByPluginId } from '@backstage/cli-common'; const SCRIPT_EXTS = ['.js', '.jsx', '.ts', '.tsx', '.json']; diff --git a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts index 2e7170f81f..a38432a66a 100644 --- a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts +++ b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts @@ -30,7 +30,7 @@ import { resolvePackageParams } from './resolvePackageParams'; import { knownBackendPluginPackageNameByPluginId, knownFrontendPluginPackageNameByPluginId, -} from '../../../../lib/knownPluginPackages'; +} from '@backstage/cli-common'; type CollectTemplateParamsOptions = { config: PortableTemplateConfig; From 769cb030b9c474108523f382c9e6d84de5cc01a4 Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Mon, 16 Mar 2026 23:05:51 +0100 Subject: [PATCH 16/29] Enhance plugin package input handling by clearing empty/invalid values and updating pre-population logic Signed-off-by: Vincenzo Scamporlino --- .../collectPortableTemplateInput.test.ts | 50 +++++++++++++++++++ .../collectPortableTemplateInput.ts | 32 +++++++----- 2 files changed, 70 insertions(+), 12 deletions(-) diff --git a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.test.ts b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.test.ts index c0cb4dd563..7436793630 100644 --- a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.test.ts +++ b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.test.ts @@ -214,6 +214,56 @@ describe('collectTemplateParams', () => { packagePath: 'plugins/custom-backend-module-my-extension', }); }); + + it('should re-prompt when pluginPackage is prefilled with an empty string', async () => { + jest.spyOn(inquirer, 'prompt').mockResolvedValueOnce({ + pluginPackage: '@mycompany/plugin-custom-backend', + }); + + await expect( + collectPortableTemplateInput({ + ...backendModuleOptions, + prefilledParams: { + pluginId: 'custom', + moduleId: 'my-extension', + pluginPackage: '', + }, + }), + ).resolves.toEqual( + expect.objectContaining({ + roleParams: expect.objectContaining({ + pluginPackage: '@mycompany/plugin-custom-backend', + }), + }), + ); + + expect(inquirer.prompt).toHaveBeenCalled(); + }); + + it('should re-prompt when pluginPackage is prefilled with an invalid name', async () => { + jest.spyOn(inquirer, 'prompt').mockResolvedValueOnce({ + pluginPackage: '@mycompany/plugin-custom-backend', + }); + + await expect( + collectPortableTemplateInput({ + ...backendModuleOptions, + prefilledParams: { + pluginId: 'custom', + moduleId: 'my-extension', + pluginPackage: 'INVALID PACKAGE NAME!', + }, + }), + ).resolves.toEqual( + expect.objectContaining({ + roleParams: expect.objectContaining({ + pluginPackage: '@mycompany/plugin-custom-backend', + }), + }), + ); + + expect(inquirer.prompt).toHaveBeenCalled(); + }); }); describe('frontend-plugin-module with pluginPackage', () => { diff --git a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts index a38432a66a..a80ade8942 100644 --- a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts +++ b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts @@ -65,20 +65,28 @@ export async function collectPortableTemplateInput( ...deprecatedParams, }; - // Pre-populate pluginPackage for known plugins so the prompt is skipped + // Pre-populate pluginPackage for known plugins so the prompt is skipped. + // Also clear out empty/invalid values so they don't bypass the prompt. if ( - (template.role === 'backend-plugin-module' || - template.role === 'frontend-plugin-module') && - parameters.pluginId && - !parameters.pluginPackage + template.role === 'backend-plugin-module' || + template.role === 'frontend-plugin-module' ) { - const knownPackages = - template.role === 'backend-plugin-module' - ? knownBackendPluginPackageNameByPluginId - : knownFrontendPluginPackageNameByPluginId; - const knownPackage = knownPackages[parameters.pluginId as string]; - if (knownPackage) { - parameters.pluginPackage = knownPackage; + if ( + parameters.pluginPackage && + !isValidNpmPackageName(parameters.pluginPackage as string) + ) { + delete parameters.pluginPackage; + } + + if (parameters.pluginId && !parameters.pluginPackage) { + const knownPackages = + template.role === 'backend-plugin-module' + ? knownBackendPluginPackageNameByPluginId + : knownFrontendPluginPackageNameByPluginId; + const knownPackage = knownPackages[parameters.pluginId as string]; + if (knownPackage) { + parameters.pluginPackage = knownPackage; + } } } From 72737430e7f89b769b836b31f7583e6fc66454e3 Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Tue, 17 Mar 2026 09:22:03 +0100 Subject: [PATCH 17/29] Enhance fixPluginPackages to support frontend plugin package names Signed-off-by: Vincenzo Scamporlino --- .../cli-module-maintenance/src/commands/repo/fix.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/cli-module-maintenance/src/commands/repo/fix.ts b/packages/cli-module-maintenance/src/commands/repo/fix.ts index ffc044f42a..906b39b94b 100644 --- a/packages/cli-module-maintenance/src/commands/repo/fix.ts +++ b/packages/cli-module-maintenance/src/commands/repo/fix.ts @@ -30,7 +30,10 @@ import { extname, } from 'node:path'; import { targetPaths } from '@backstage/cli-common'; -import { knownBackendPluginPackageNameByPluginId } from '@backstage/cli-common'; +import { + knownBackendPluginPackageNameByPluginId, + knownFrontendPluginPackageNameByPluginId, +} from '@backstage/cli-common'; const SCRIPT_EXTS = ['.js', '.jsx', '.ts', '.tsx', '.json']; @@ -400,7 +403,10 @@ export function fixPluginPackages( p => p.packageJson.backstage?.pluginId === pluginId && p.packageJson.backstage?.role === targetRole, - )?.packageJson.name ?? knownBackendPluginPackageNameByPluginId[pluginId]; + )?.packageJson.name ?? + (role === 'backend-plugin-module' + ? knownBackendPluginPackageNameByPluginId[pluginId] + : knownFrontendPluginPackageNameByPluginId[pluginId]); if (!pluginPkgName) { // If we can't find a matching package in the repo but one is declared, skip if (pkgBackstage.pluginPackage) { From 6e451dc85cb4a8e1e13a1b2f4d3151396757d39d Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Tue, 17 Mar 2026 10:01:32 +0100 Subject: [PATCH 18/29] Refactor known plugin IDs to separate backend and frontend packages Signed-off-by: Vincenzo Scamporlino --- .../cli-common/src/knownPluginPackages.ts | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/packages/cli-common/src/knownPluginPackages.ts b/packages/cli-common/src/knownPluginPackages.ts index ae0d3f8942..2566247bd8 100644 --- a/packages/cli-common/src/knownPluginPackages.ts +++ b/packages/cli-common/src/knownPluginPackages.ts @@ -14,8 +14,7 @@ * limitations under the License. */ -const knownPluginIds = [ - 'app', +const knownBackendPluginIds = [ 'auth', 'catalog', 'events', @@ -29,6 +28,19 @@ const knownPluginIds = [ 'techdocs', ]; +// Some plugin IDs only have backend packages and no corresponding frontend package +const knownFrontendPluginIds = [ + 'app', + 'auth', + 'catalog', + 'kubernetes', + 'notifications', + 'scaffolder', + 'search', + 'signals', + 'techdocs', +]; + /** * Maps known plugin IDs to their corresponding backend package names. * @@ -36,7 +48,7 @@ const knownPluginIds = [ */ export const knownBackendPluginPackageNameByPluginId: Record = Object.fromEntries( - knownPluginIds.map(pluginId => [ + knownBackendPluginIds.map(pluginId => [ pluginId, `@backstage/plugin-${pluginId}-backend`, ]), @@ -49,5 +61,8 @@ export const knownBackendPluginPackageNameByPluginId: Record = */ export const knownFrontendPluginPackageNameByPluginId: Record = Object.fromEntries( - knownPluginIds.map(pluginId => [pluginId, `@backstage/plugin-${pluginId}`]), + knownFrontendPluginIds.map(pluginId => [ + pluginId, + `@backstage/plugin-${pluginId}`, + ]), ); From 58fb21967a52dace9756c9f65ff467fb0b3fbc1d Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Tue, 17 Mar 2026 10:32:51 +0100 Subject: [PATCH 19/29] Include additional parameters in answers Signed-off-by: Vincenzo Scamporlino --- .../src/lib/preparation/collectPortableTemplateInput.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts index a80ade8942..0c89eff6f9 100644 --- a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts +++ b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts @@ -105,6 +105,7 @@ export async function collectPortableTemplateInput( ); const answers = { + ...parameters, ...prefilledAnswers, ...promptAnswers, }; From e6675123d88d04f83cb80bb6a1da1fe1553d43c8 Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Tue, 17 Mar 2026 10:37:38 +0100 Subject: [PATCH 20/29] Refactor plugin package validation to trim and check for valid npm package names Signed-off-by: Vincenzo Scamporlino --- .../preparation/collectPortableTemplateInput.test.ts | 12 ++++++++++-- .../lib/preparation/collectPortableTemplateInput.ts | 6 ++---- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.test.ts b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.test.ts index 7436793630..f76fec6329 100644 --- a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.test.ts +++ b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.test.ts @@ -237,7 +237,11 @@ describe('collectTemplateParams', () => { }), ); - expect(inquirer.prompt).toHaveBeenCalled(); + expect(inquirer.prompt).toHaveBeenCalledWith( + expect.arrayContaining([ + expect.objectContaining({ name: 'pluginPackage' }), + ]), + ); }); it('should re-prompt when pluginPackage is prefilled with an invalid name', async () => { @@ -262,7 +266,11 @@ describe('collectTemplateParams', () => { }), ); - expect(inquirer.prompt).toHaveBeenCalled(); + expect(inquirer.prompt).toHaveBeenCalledWith( + expect.arrayContaining([ + expect.objectContaining({ name: 'pluginPackage' }), + ]), + ); }); }); diff --git a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts index 0c89eff6f9..415774d6ac 100644 --- a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts +++ b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts @@ -71,10 +71,8 @@ export async function collectPortableTemplateInput( template.role === 'backend-plugin-module' || template.role === 'frontend-plugin-module' ) { - if ( - parameters.pluginPackage && - !isValidNpmPackageName(parameters.pluginPackage as string) - ) { + const pluginPkg = (parameters.pluginPackage as string | undefined)?.trim(); + if (!pluginPkg || !isValidNpmPackageName(pluginPkg)) { delete parameters.pluginPackage; } From 733dd3447e1e739d51b9b1b48a2ad7b57c48de3b Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Tue, 17 Mar 2026 10:58:56 +0100 Subject: [PATCH 21/29] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Vincenzo Scamporlino --- .../src/lib/preparation/collectPortableTemplateInput.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts index 415774d6ac..fc1e8f083d 100644 --- a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts +++ b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts @@ -271,8 +271,8 @@ export function ownerPrompt(): DistinctQuestion { }; } -// Reuses the same pattern as namePrompt/pluginIdPrompt but extended to support npm scopes -// Matches: @scope/package-name, @scope/package, package-name, package +// Based on the same pattern as namePrompt/pluginIdPrompt, but extended to support npm scopes +// and additional allowed characters ('.' and '_'). Matches: @scope/package-name, @scope/package, const packageNamePattern = /^[a-z0-9][a-z0-9._-]*$/; const scopedPackageNamePattern = /^@[a-z0-9][a-z0-9._-]*\/[a-z0-9][a-z0-9._-]*$/; From db13e5f52fd6d075ab8359df63d067401534b8db Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Tue, 17 Mar 2026 11:02:07 +0100 Subject: [PATCH 22/29] Fix plugin package handling by trimming and validating input; add .node-version file Signed-off-by: Vincenzo Scamporlino --- .../src/lib/preparation/collectPortableTemplateInput.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts index fc1e8f083d..8ba29ba152 100644 --- a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts +++ b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts @@ -74,6 +74,8 @@ export async function collectPortableTemplateInput( const pluginPkg = (parameters.pluginPackage as string | undefined)?.trim(); if (!pluginPkg || !isValidNpmPackageName(pluginPkg)) { delete parameters.pluginPackage; + } else { + parameters.pluginPackage = pluginPkg; } if (parameters.pluginId && !parameters.pluginPackage) { From f189d8fc63ba161883ed8f92472db5165cee1e71 Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Tue, 17 Mar 2026 11:50:54 +0100 Subject: [PATCH 23/29] Expose known plugin package names for auto-filling in plugin creation Signed-off-by: Vincenzo Scamporlino --- .changeset/clever-insects-tan.md | 6 ++++++ .changeset/ninety-suits-drum.md | 1 + 2 files changed, 7 insertions(+) create mode 100644 .changeset/clever-insects-tan.md diff --git a/.changeset/clever-insects-tan.md b/.changeset/clever-insects-tan.md new file mode 100644 index 0000000000..502882e116 --- /dev/null +++ b/.changeset/clever-insects-tan.md @@ -0,0 +1,6 @@ +--- +'@backstage/cli-module-maintenance': patch +'@backstage/cli-common': patch +--- + +Exposes `knownBackendPluginPackageNameByPluginId` and `knownFrontendPluginPackageNameByPluginId` from `@backstage/cli-common` for auto-filling plugin package names. diff --git a/.changeset/ninety-suits-drum.md b/.changeset/ninety-suits-drum.md index 724b46dabf..d2a0caf7ba 100644 --- a/.changeset/ninety-suits-drum.md +++ b/.changeset/ninety-suits-drum.md @@ -1,4 +1,5 @@ --- +'@backstage/cli-module-new': patch '@backstage/cli': patch --- From 00328c1321242cbcda64ffdda292f074c64d24ea Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Tue, 17 Mar 2026 11:51:03 +0100 Subject: [PATCH 24/29] Add tests to auto-fill pluginPackage for catalog plugins without prompting Signed-off-by: Vincenzo Scamporlino --- .../preparation/collectPortableTemplateInput.test.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.test.ts b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.test.ts index f76fec6329..cf1122d785 100644 --- a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.test.ts +++ b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.test.ts @@ -162,6 +162,8 @@ describe('collectTemplateParams', () => { }; it('should auto-fill pluginPackage for catalog plugin without prompting', async () => { + const promptSpy = jest.spyOn(inquirer, 'prompt'); + await expect( collectPortableTemplateInput({ ...backendModuleOptions, @@ -184,6 +186,9 @@ describe('collectTemplateParams', () => { packageName: '@internal/plugin-catalog-backend-module-my-module', packagePath: 'plugins/catalog-backend-module-my-module', }); + + const questions = promptSpy.mock.calls[0][0] as Array<{ name?: string }>; + expect(questions.some(q => q.name === 'pluginPackage')).toBe(false); }); it('should prompt for pluginPackage for unknown plugins', async () => { @@ -286,6 +291,8 @@ describe('collectTemplateParams', () => { }; it('should auto-fill pluginPackage for catalog plugin without prompting', async () => { + const promptSpy = jest.spyOn(inquirer, 'prompt'); + await expect( collectPortableTemplateInput({ ...frontendModuleOptions, @@ -308,6 +315,9 @@ describe('collectTemplateParams', () => { packageName: '@internal/plugin-catalog-module-my-module', packagePath: 'plugins/catalog-module-my-module', }); + + const questions = promptSpy.mock.calls[0][0] as Array<{ name?: string }>; + expect(questions.some(q => q.name === 'pluginPackage')).toBe(false); }); it('should prompt for pluginPackage for unknown plugins', async () => { From 6ae0f41c5699c22571c22866e54a3a8b2612e0ba Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 17 Mar 2026 11:51:21 +0100 Subject: [PATCH 25/29] Apply suggestions from code review Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Patrik Oldsberg --- packages/cli-common/src/knownPluginPackages.ts | 3 ++- .../src/lib/preparation/collectPortableTemplateInput.ts | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/cli-common/src/knownPluginPackages.ts b/packages/cli-common/src/knownPluginPackages.ts index 2566247bd8..43e33f4cc2 100644 --- a/packages/cli-common/src/knownPluginPackages.ts +++ b/packages/cli-common/src/knownPluginPackages.ts @@ -15,6 +15,7 @@ */ const knownBackendPluginIds = [ + 'app', 'auth', 'catalog', 'events', @@ -28,7 +29,7 @@ const knownBackendPluginIds = [ 'techdocs', ]; -// Some plugin IDs only have backend packages and no corresponding frontend package +// Only includes plugin IDs that have a corresponding frontend package; some plugins are backend-only and not listed here. const knownFrontendPluginIds = [ 'app', 'auth', diff --git a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts index 8ba29ba152..14b6e77e89 100644 --- a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts +++ b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts @@ -274,7 +274,7 @@ export function ownerPrompt(): DistinctQuestion { } // Based on the same pattern as namePrompt/pluginIdPrompt, but extended to support npm scopes -// and additional allowed characters ('.' and '_'). Matches: @scope/package-name, @scope/package, +// and additional allowed characters ('.' and '_'). Matches examples like: package-name, my.package_name, @scope/package-name, @scope/package. const packageNamePattern = /^[a-z0-9][a-z0-9._-]*$/; const scopedPackageNamePattern = /^@[a-z0-9][a-z0-9._-]*\/[a-z0-9][a-z0-9._-]*$/; From aaf97bdccb59e2c924bf45486a2ea381d4b2fe11 Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Tue, 17 Mar 2026 12:12:48 +0100 Subject: [PATCH 26/29] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Vincenzo Scamporlino --- .../lib/preparation/collectPortableTemplateInput.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts index 14b6e77e89..9239b95e18 100644 --- a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts +++ b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts @@ -16,7 +16,11 @@ import inquirer, { DistinctQuestion } from 'inquirer'; import { getCodeownersFilePath, parseOwnerIds } from '../codeowners'; -import { targetPaths } from '@backstage/cli-common'; +import { + targetPaths, + knownBackendPluginPackageNameByPluginId, + knownFrontendPluginPackageNameByPluginId, +} from '@backstage/cli-common'; import { PortableTemplateConfig, @@ -27,10 +31,6 @@ import { } from '../types'; import { PortableTemplate } from '../types'; import { resolvePackageParams } from './resolvePackageParams'; -import { - knownBackendPluginPackageNameByPluginId, - knownFrontendPluginPackageNameByPluginId, -} from '@backstage/cli-common'; type CollectTemplateParamsOptions = { config: PortableTemplateConfig; From ee8e31320a63830d122e066c6af45e10b2927441 Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Tue, 17 Mar 2026 12:12:59 +0100 Subject: [PATCH 27/29] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Vincenzo Scamporlino --- packages/cli-module-maintenance/src/commands/repo/fix.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli-module-maintenance/src/commands/repo/fix.ts b/packages/cli-module-maintenance/src/commands/repo/fix.ts index 906b39b94b..81e7a37d80 100644 --- a/packages/cli-module-maintenance/src/commands/repo/fix.ts +++ b/packages/cli-module-maintenance/src/commands/repo/fix.ts @@ -29,8 +29,8 @@ import { relative as relativePath, extname, } from 'node:path'; -import { targetPaths } from '@backstage/cli-common'; import { + targetPaths, knownBackendPluginPackageNameByPluginId, knownFrontendPluginPackageNameByPluginId, } from '@backstage/cli-common'; From a0bc38b83cc91b3556adea4d491293b6117cc25d Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Tue, 17 Mar 2026 13:34:39 +0100 Subject: [PATCH 28/29] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Vincenzo Scamporlino --- .../src/lib/preparation/collectPortableTemplateInput.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts index 9239b95e18..b2b89262a2 100644 --- a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts +++ b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts @@ -215,6 +215,7 @@ export function pluginPackagePrompt( return { type: 'input', name: 'pluginPackage', + filter: (value: string) => value.trim(), message: `Enter the package name of the plugin this module extends (e.g. ${examplePackage}) [required]`, validate: (value: string) => { if (!value) { From b46970c8800548c15fd0e59e124a3214aacb3c27 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 17 Mar 2026 20:55:10 +0100 Subject: [PATCH 29/29] Move known plugin package constants from cli-common to cli-internal The known plugin package ID mappings don't need to be part of the public API surface. Move them to @internal/cli and update consumers. Signed-off-by: Patrik Oldsberg Made-with: Cursor --- .changeset/clever-insects-tan.md | 3 +-- packages/cli-common/report.api.md | 6 ------ packages/cli-common/src/index.ts | 4 ---- packages/cli-internal/src/index.ts | 4 ++++ .../{cli-common => cli-internal}/src/knownPluginPackages.ts | 4 ---- packages/cli-module-maintenance/package.json | 4 ++-- packages/cli-module-maintenance/src/commands/repo/fix.ts | 4 ++-- .../src/lib/preparation/collectPortableTemplateInput.ts | 4 ++-- 8 files changed, 11 insertions(+), 22 deletions(-) rename packages/{cli-common => cli-internal}/src/knownPluginPackages.ts (98%) diff --git a/.changeset/clever-insects-tan.md b/.changeset/clever-insects-tan.md index 502882e116..c04490a833 100644 --- a/.changeset/clever-insects-tan.md +++ b/.changeset/clever-insects-tan.md @@ -1,6 +1,5 @@ --- '@backstage/cli-module-maintenance': patch -'@backstage/cli-common': patch --- -Exposes `knownBackendPluginPackageNameByPluginId` and `knownFrontendPluginPackageNameByPluginId` from `@backstage/cli-common` for auto-filling plugin package names. +Added auto-fill of `backstage.pluginPackage` metadata for known plugins during `repo fix`. diff --git a/packages/cli-common/report.api.md b/packages/cli-common/report.api.md index 74d5a24999..ba649cacc9 100644 --- a/packages/cli-common/report.api.md +++ b/packages/cli-common/report.api.md @@ -28,12 +28,6 @@ export function findPaths(searchDir: string): Paths; // @public export function isChildPath(base: string, path: string): boolean; -// @public -export const knownBackendPluginPackageNameByPluginId: Record; - -// @public -export const knownFrontendPluginPackageNameByPluginId: Record; - // @public export type OwnPaths = { dir: string; diff --git a/packages/cli-common/src/index.ts b/packages/cli-common/src/index.ts index bfa0716097..e49eac0ee0 100644 --- a/packages/cli-common/src/index.ts +++ b/packages/cli-common/src/index.ts @@ -33,7 +33,3 @@ export { type RunOnOutput, } from './run'; export { ExitCodeError } from './errors'; -export { - knownBackendPluginPackageNameByPluginId, - knownFrontendPluginPackageNameByPluginId, -} from './knownPluginPackages'; diff --git a/packages/cli-internal/src/index.ts b/packages/cli-internal/src/index.ts index 281b998d92..dfd8968c6a 100644 --- a/packages/cli-internal/src/index.ts +++ b/packages/cli-internal/src/index.ts @@ -31,3 +31,7 @@ export { resetSecretStore, type SecretStore, } from './secretStore'; +export { + knownBackendPluginPackageNameByPluginId, + knownFrontendPluginPackageNameByPluginId, +} from './knownPluginPackages'; diff --git a/packages/cli-common/src/knownPluginPackages.ts b/packages/cli-internal/src/knownPluginPackages.ts similarity index 98% rename from packages/cli-common/src/knownPluginPackages.ts rename to packages/cli-internal/src/knownPluginPackages.ts index 43e33f4cc2..c5d13beef1 100644 --- a/packages/cli-common/src/knownPluginPackages.ts +++ b/packages/cli-internal/src/knownPluginPackages.ts @@ -44,8 +44,6 @@ const knownFrontendPluginIds = [ /** * Maps known plugin IDs to their corresponding backend package names. - * - * @public */ export const knownBackendPluginPackageNameByPluginId: Record = Object.fromEntries( @@ -57,8 +55,6 @@ export const knownBackendPluginPackageNameByPluginId: Record = /** * Maps known plugin IDs to their corresponding frontend package names. - * - * @public */ export const knownFrontendPluginPackageNameByPluginId: Record = Object.fromEntries( diff --git a/packages/cli-module-maintenance/package.json b/packages/cli-module-maintenance/package.json index 24f7a9b70a..585de9d6cd 100644 --- a/packages/cli-module-maintenance/package.json +++ b/packages/cli-module-maintenance/package.json @@ -19,6 +19,7 @@ "license": "Apache-2.0", "main": "src/index.ts", "types": "src/index.ts", + "bin": "bin/backstage-cli-module-maintenance", "files": [ "dist", "bin" @@ -42,6 +43,5 @@ "devDependencies": { "@backstage/cli": "workspace:^", "@types/fs-extra": "^11.0.0" - }, - "bin": "bin/backstage-cli-module-maintenance" + } } diff --git a/packages/cli-module-maintenance/src/commands/repo/fix.ts b/packages/cli-module-maintenance/src/commands/repo/fix.ts index 81e7a37d80..c9e6a965bf 100644 --- a/packages/cli-module-maintenance/src/commands/repo/fix.ts +++ b/packages/cli-module-maintenance/src/commands/repo/fix.ts @@ -29,11 +29,11 @@ import { relative as relativePath, extname, } from 'node:path'; +import { targetPaths } from '@backstage/cli-common'; import { - targetPaths, knownBackendPluginPackageNameByPluginId, knownFrontendPluginPackageNameByPluginId, -} from '@backstage/cli-common'; +} from '@internal/cli'; const SCRIPT_EXTS = ['.js', '.jsx', '.ts', '.tsx', '.json']; diff --git a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts index b2b89262a2..341caae504 100644 --- a/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts +++ b/packages/cli-module-new/src/lib/preparation/collectPortableTemplateInput.ts @@ -16,11 +16,11 @@ import inquirer, { DistinctQuestion } from 'inquirer'; import { getCodeownersFilePath, parseOwnerIds } from '../codeowners'; +import { targetPaths } from '@backstage/cli-common'; import { - targetPaths, knownBackendPluginPackageNameByPluginId, knownFrontendPluginPackageNameByPluginId, -} from '@backstage/cli-common'; +} from '@internal/cli'; import { PortableTemplateConfig,