i18n add extension commands

This commit is contained in:
LaZzyMan 2026-01-20 17:20:20 +08:00
parent ba14e9e531
commit e87376e06c
12 changed files with 440 additions and 67 deletions

View file

@ -8,6 +8,7 @@ import { type CommandModule } from 'yargs';
import { SettingScope } from '../../config/settings.js'; import { SettingScope } from '../../config/settings.js';
import { getErrorMessage } from '../../utils/errors.js'; import { getErrorMessage } from '../../utils/errors.js';
import { getExtensionManager } from './utils.js'; import { getExtensionManager } from './utils.js';
import { t } from '../../i18n/index.js';
interface DisableArgs { interface DisableArgs {
name: string; name: string;
@ -23,7 +24,10 @@ export async function handleDisable(args: DisableArgs) {
extensionManager.disableExtension(args.name, SettingScope.User); extensionManager.disableExtension(args.name, SettingScope.User);
} }
console.log( console.log(
`Extension "${args.name}" successfully disabled for scope "${args.scope}".`, t('Extension "{{name}}" successfully disabled for scope "{{scope}}".', {
name: args.name,
scope: args.scope || SettingScope.User,
}),
); );
} catch (error) { } catch (error) {
console.error(getErrorMessage(error)); console.error(getErrorMessage(error));
@ -33,15 +37,15 @@ export async function handleDisable(args: DisableArgs) {
export const disableCommand: CommandModule = { export const disableCommand: CommandModule = {
command: 'disable [--scope] <name>', command: 'disable [--scope] <name>',
describe: 'Disables an extension.', describe: t('Disables an extension.'),
builder: (yargs) => builder: (yargs) =>
yargs yargs
.positional('name', { .positional('name', {
describe: 'The name of the extension to disable.', describe: t('The name of the extension to disable.'),
type: 'string', type: 'string',
}) })
.option('scope', { .option('scope', {
describe: 'The scope to disable the extenison in.', describe: t('The scope to disable the extenison in.'),
type: 'string', type: 'string',
default: SettingScope.User, default: SettingScope.User,
}) })
@ -53,11 +57,12 @@ export const disableCommand: CommandModule = {
.includes((argv.scope as string).toLowerCase()) .includes((argv.scope as string).toLowerCase())
) { ) {
throw new Error( throw new Error(
`Invalid scope: ${argv.scope}. Please use one of ${Object.values( t('Invalid scope: {{scope}}. Please use one of {{scopes}}.', {
SettingScope, scope: argv.scope as string,
) scopes: Object.values(SettingScope)
.map((s) => s.toLowerCase()) .map((s) => s.toLowerCase())
.join(', ')}.`, .join(', '),
}),
); );
} }
return true; return true;

View file

@ -8,6 +8,7 @@ import { type CommandModule } from 'yargs';
import { FatalConfigError, getErrorMessage } from '@qwen-code/qwen-code-core'; import { FatalConfigError, getErrorMessage } from '@qwen-code/qwen-code-core';
import { SettingScope } from '../../config/settings.js'; import { SettingScope } from '../../config/settings.js';
import { getExtensionManager } from './utils.js'; import { getExtensionManager } from './utils.js';
import { t } from '../../i18n/index.js';
interface EnableArgs { interface EnableArgs {
name: string; name: string;
@ -25,11 +26,16 @@ export async function handleEnable(args: EnableArgs) {
} }
if (args.scope) { if (args.scope) {
console.log( console.log(
`Extension "${args.name}" successfully enabled for scope "${args.scope}".`, t('Extension "{{name}}" successfully enabled for scope "{{scope}}".', {
name: args.name,
scope: args.scope,
}),
); );
} else { } else {
console.log( console.log(
`Extension "${args.name}" successfully enabled in all scopes.`, t('Extension "{{name}}" successfully enabled in all scopes.', {
name: args.name,
}),
); );
} }
} catch (error) { } catch (error) {
@ -39,16 +45,17 @@ export async function handleEnable(args: EnableArgs) {
export const enableCommand: CommandModule = { export const enableCommand: CommandModule = {
command: 'enable [--scope] <name>', command: 'enable [--scope] <name>',
describe: 'Enables an extension.', describe: t('Enables an extension.'),
builder: (yargs) => builder: (yargs) =>
yargs yargs
.positional('name', { .positional('name', {
describe: 'The name of the extension to enable.', describe: t('The name of the extension to enable.'),
type: 'string', type: 'string',
}) })
.option('scope', { .option('scope', {
describe: describe: t(
'The scope to enable the extenison in. If not set, will be enabled in all scopes.', 'The scope to enable the extenison in. If not set, will be enabled in all scopes.',
),
type: 'string', type: 'string',
}) })
.check((argv) => { .check((argv) => {
@ -59,11 +66,12 @@ export const enableCommand: CommandModule = {
.includes((argv.scope as string).toLowerCase()) .includes((argv.scope as string).toLowerCase())
) { ) {
throw new Error( throw new Error(
`Invalid scope: ${argv.scope}. Please use one of ${Object.values( t('Invalid scope: {{scope}}. Please use one of {{scopes}}.', {
SettingScope, scope: argv.scope as string,
) scopes: Object.values(SettingScope)
.map((s) => s.toLowerCase()) .map((s) => s.toLowerCase())
.join(', ')}.`, .join(', '),
}),
); );
} }
return true; return true;

View file

@ -17,6 +17,7 @@ import {
requestConsentOrFail, requestConsentOrFail,
requestConsentNonInteractive, requestConsentNonInteractive,
} from './consent.js'; } from './consent.js';
import { t } from '../../i18n/index.js';
interface InstallArgs { interface InstallArgs {
source: string; source: string;
@ -36,7 +37,9 @@ export async function handleInstall(args: InstallArgs) {
) { ) {
if (args.ref || args.autoUpdate) { if (args.ref || args.autoUpdate) {
throw new Error( throw new Error(
'--ref and --auto-update are not applicable for marketplace extensions.', t(
'--ref and --auto-update are not applicable for marketplace extensions.',
),
); );
} }
} }
@ -64,7 +67,9 @@ export async function handleInstall(args: InstallArgs) {
requestConsent, requestConsent,
); );
console.log( console.log(
`Extension "${extension.name}" installed successfully and enabled.`, t('Extension "{{name}}" installed successfully and enabled.', {
name: extension.name,
}),
); );
} catch (error) { } catch (error) {
console.error(getErrorMessage(error)); console.error(getErrorMessage(error));
@ -74,37 +79,40 @@ export async function handleInstall(args: InstallArgs) {
export const installCommand: CommandModule = { export const installCommand: CommandModule = {
command: 'install <source>', command: 'install <source>',
describe: describe: t(
'Installs an extension from a git repository URL, local path, or claude marketplace (marketplace-url:plugin-name).', 'Installs an extension from a git repository URL, local path, or claude marketplace (marketplace-url:plugin-name).',
),
builder: (yargs) => builder: (yargs) =>
yargs yargs
.positional('source', { .positional('source', {
describe: describe: t(
'The github URL, local path, or marketplace source (marketplace-url:plugin-name) of the extension to install.', 'The github URL, local path, or marketplace source (marketplace-url:plugin-name) of the extension to install.',
),
type: 'string', type: 'string',
demandOption: true, demandOption: true,
}) })
.option('ref', { .option('ref', {
describe: 'The git ref to install from.', describe: t('The git ref to install from.'),
type: 'string', type: 'string',
}) })
.option('auto-update', { .option('auto-update', {
describe: 'Enable auto-update for this extension.', describe: t('Enable auto-update for this extension.'),
type: 'boolean', type: 'boolean',
}) })
.option('pre-release', { .option('pre-release', {
describe: 'Enable pre-release versions for this extension.', describe: t('Enable pre-release versions for this extension.'),
type: 'boolean', type: 'boolean',
}) })
.option('consent', { .option('consent', {
describe: describe: t(
'Acknowledge the security risks of installing an extension and skip the confirmation prompt.', 'Acknowledge the security risks of installing an extension and skip the confirmation prompt.',
),
type: 'boolean', type: 'boolean',
default: false, default: false,
}) })
.check((argv) => { .check((argv) => {
if (!argv.source) { if (!argv.source) {
throw new Error('The source argument must be provided.'); throw new Error(t('The source argument must be provided.'));
} }
return true; return true;
}), }),

View file

@ -12,6 +12,7 @@ import {
requestConsentOrFail, requestConsentOrFail,
} from './consent.js'; } from './consent.js';
import { getExtensionManager } from './utils.js'; import { getExtensionManager } from './utils.js';
import { t } from '../../i18n/index.js';
interface InstallArgs { interface InstallArgs {
path: string; path: string;
@ -30,11 +31,13 @@ export async function handleLink(args: InstallArgs) {
requestConsentOrFail.bind(null, requestConsentNonInteractive), requestConsentOrFail.bind(null, requestConsentNonInteractive),
); );
if (!extension) { if (!extension) {
console.log('Link extension failed to install.'); console.log(t('Link extension failed to install.'));
return; return;
} }
console.log( console.log(
`Extension "${extension.name}" linked successfully and enabled.`, t('Extension "{{name}}" linked successfully and enabled.', {
name: extension.name,
}),
); );
} catch (error) { } catch (error) {
console.error(getErrorMessage(error)); console.error(getErrorMessage(error));
@ -44,12 +47,13 @@ export async function handleLink(args: InstallArgs) {
export const linkCommand: CommandModule = { export const linkCommand: CommandModule = {
command: 'link <path>', command: 'link <path>',
describe: describe: t(
'Links an extension from a local path. Updates made to the local path will always be reflected.', 'Links an extension from a local path. Updates made to the local path will always be reflected.',
),
builder: (yargs) => builder: (yargs) =>
yargs yargs
.positional('path', { .positional('path', {
describe: 'The name of the extension to link.', describe: t('The name of the extension to link.'),
type: 'string', type: 'string',
}) })
.check((_) => true), .check((_) => true),

View file

@ -7,6 +7,7 @@
import type { CommandModule } from 'yargs'; import type { CommandModule } from 'yargs';
import { getErrorMessage } from '../../utils/errors.js'; import { getErrorMessage } from '../../utils/errors.js';
import { getExtensionManager } from './utils.js'; import { getExtensionManager } from './utils.js';
import { t } from '../../i18n/index.js';
export async function handleList() { export async function handleList() {
try { try {
@ -14,7 +15,7 @@ export async function handleList() {
const extensions = extensionManager.getLoadedExtensions(); const extensions = extensionManager.getLoadedExtensions();
if (!extensions || extensions.length === 0) { if (!extensions || extensions.length === 0) {
console.log('No extensions installed.'); console.log(t('No extensions installed.'));
return; return;
} }
console.log( console.log(
@ -32,7 +33,7 @@ export async function handleList() {
export const listCommand: CommandModule = { export const listCommand: CommandModule = {
command: 'list', command: 'list',
describe: 'Lists installed extensions.', describe: t('Lists installed extensions.'),
builder: (yargs) => yargs, builder: (yargs) => yargs,
handler: async () => { handler: async () => {
await handleList(); await handleList();

View file

@ -12,6 +12,7 @@ import {
promptForSetting, promptForSetting,
updateSetting, updateSetting,
} from '@qwen-code/qwen-code-core'; } from '@qwen-code/qwen-code-core';
import { t } from '../../i18n/index.js';
// --- SET COMMAND --- // --- SET COMMAND ---
interface SetArgs { interface SetArgs {
@ -22,21 +23,21 @@ interface SetArgs {
const setCommand: CommandModule<object, SetArgs> = { const setCommand: CommandModule<object, SetArgs> = {
command: 'set [--scope] <name> <setting>', command: 'set [--scope] <name> <setting>',
describe: 'Set a specific setting for an extension.', describe: t('Set a specific setting for an extension.'),
builder: (yargs) => builder: (yargs) =>
yargs yargs
.positional('name', { .positional('name', {
describe: 'Name of the extension to configure.', describe: t('Name of the extension to configure.'),
type: 'string', type: 'string',
demandOption: true, demandOption: true,
}) })
.positional('setting', { .positional('setting', {
describe: 'The setting to configure (name or env var).', describe: t('The setting to configure (name or env var).'),
type: 'string', type: 'string',
demandOption: true, demandOption: true,
}) })
.option('scope', { .option('scope', {
describe: 'The scope to set the setting in.', describe: t('The scope to set the setting in.'),
type: 'string', type: 'string',
choices: ['user', 'workspace'], choices: ['user', 'workspace'],
default: 'user', default: 'user',
@ -49,7 +50,7 @@ const setCommand: CommandModule<object, SetArgs> = {
if (!extensions || extensions.length === 0) return; if (!extensions || extensions.length === 0) return;
const extension = extensions.find((e) => e.name === name); const extension = extensions.find((e) => e.name === name);
if (!extension) { if (!extension) {
console.log(`Extension "${name}" not found.`); console.log(t('Extension "{{name}}" not found.', { name }));
return; return;
} }
await updateSetting( await updateSetting(
@ -69,10 +70,10 @@ interface ListArgs {
const listCommand: CommandModule<object, ListArgs> = { const listCommand: CommandModule<object, ListArgs> = {
command: 'list <name>', command: 'list <name>',
describe: 'List all settings for an extension.', describe: t('List all settings for an extension.'),
builder: (yargs) => builder: (yargs) =>
yargs.positional('name', { yargs.positional('name', {
describe: 'Name of the extension.', describe: t('Name of the extension.'),
type: 'string', type: 'string',
demandOption: true, demandOption: true,
}), }),
@ -84,11 +85,13 @@ const listCommand: CommandModule<object, ListArgs> = {
if (!extensions || extensions.length === 0) return; if (!extensions || extensions.length === 0) return;
const extension = extensions.find((e) => e.name === name); const extension = extensions.find((e) => e.name === name);
if (!extension) { if (!extension) {
console.log(`Extension "${name}" not found.`); console.log(t('Extension "{{name}}" not found.', { name }));
return; return;
} }
if (!extension || !extension.settings || extension.settings.length === 0) { if (!extension || !extension.settings || extension.settings.length === 0) {
console.log(`Extension "${name}" has no settings to configure.`); console.log(
t('Extension "{{name}}" has no settings to configure.', { name }),
);
return; return;
} }
@ -104,29 +107,29 @@ const listCommand: CommandModule<object, ListArgs> = {
); );
const mergedSettings = { ...userSettings, ...workspaceSettings }; const mergedSettings = { ...userSettings, ...workspaceSettings };
console.log(`Settings for "${name}":`); console.log(t('Settings for "{{name}}":', { name }));
for (const setting of extension.settings) { for (const setting of extension.settings) {
const value = mergedSettings[setting.envVar]; const value = mergedSettings[setting.envVar];
let displayValue: string; let displayValue: string;
let scopeInfo = ''; let scopeInfo = '';
if (workspaceSettings[setting.envVar] !== undefined) { if (workspaceSettings[setting.envVar] !== undefined) {
scopeInfo = ' (workspace)'; scopeInfo = ' ' + t('(workspace)');
} else if (userSettings[setting.envVar] !== undefined) { } else if (userSettings[setting.envVar] !== undefined) {
scopeInfo = ' (user)'; scopeInfo = ' ' + t('(user)');
} }
if (value === undefined) { if (value === undefined) {
displayValue = '[not set]'; displayValue = t('[not set]');
} else if (setting.sensitive) { } else if (setting.sensitive) {
displayValue = '[value stored in keychain]'; displayValue = t('[value stored in keychain]');
} else { } else {
displayValue = value; displayValue = value;
} }
console.log(` console.log(`
- ${setting.name} (${setting.envVar})`); - ${setting.name} (${setting.envVar})`);
console.log(` Description: ${setting.description}`); console.log(` ${t('Description:')} ${setting.description}`);
console.log(` Value: ${displayValue}${scopeInfo}`); console.log(` ${t('Value:')} ${displayValue}${scopeInfo}`);
} }
}, },
}; };
@ -134,12 +137,12 @@ const listCommand: CommandModule<object, ListArgs> = {
// --- SETTINGS COMMAND --- // --- SETTINGS COMMAND ---
export const settingsCommand: CommandModule = { export const settingsCommand: CommandModule = {
command: 'settings <command>', command: 'settings <command>',
describe: 'Manage extension settings.', describe: t('Manage extension settings.'),
builder: (yargs) => builder: (yargs) =>
yargs yargs
.command(setCommand) .command(setCommand)
.command(listCommand) .command(listCommand)
.demandCommand(1, 'You need to specify a command (set or list).') .demandCommand(1, t('You need to specify a command (set or list).'))
.version(false), .version(false),
handler: () => { handler: () => {
// This handler is not called when a subcommand is provided. // This handler is not called when a subcommand is provided.

View file

@ -13,6 +13,7 @@ import {
} from './consent.js'; } from './consent.js';
import { isWorkspaceTrusted } from '../../config/trustedFolders.js'; import { isWorkspaceTrusted } from '../../config/trustedFolders.js';
import { loadSettings } from '../../config/settings.js'; import { loadSettings } from '../../config/settings.js';
import { t } from '../../i18n/index.js';
interface UninstallArgs { interface UninstallArgs {
name: string; // can be extension name or source URL. name: string; // can be extension name or source URL.
@ -33,7 +34,9 @@ export async function handleUninstall(args: UninstallArgs) {
}); });
await extensionManager.refreshCache(); await extensionManager.refreshCache();
await extensionManager.uninstallExtension(args.name, false); await extensionManager.uninstallExtension(args.name, false);
console.log(`Extension "${args.name}" successfully uninstalled.`); console.log(
t('Extension "{{name}}" successfully uninstalled.', { name: args.name }),
);
} catch (error) { } catch (error) {
console.error(getErrorMessage(error)); console.error(getErrorMessage(error));
process.exit(1); process.exit(1);
@ -42,17 +45,19 @@ export async function handleUninstall(args: UninstallArgs) {
export const uninstallCommand: CommandModule = { export const uninstallCommand: CommandModule = {
command: 'uninstall <name>', command: 'uninstall <name>',
describe: 'Uninstalls an extension.', describe: t('Uninstalls an extension.'),
builder: (yargs) => builder: (yargs) =>
yargs yargs
.positional('name', { .positional('name', {
describe: 'The name or source path of the extension to uninstall.', describe: t('The name or source path of the extension to uninstall.'),
type: 'string', type: 'string',
}) })
.check((argv) => { .check((argv) => {
if (!argv.name) { if (!argv.name) {
throw new Error( throw new Error(
'Please include the name of the extension to uninstall as a positional argument.', t(
'Please include the name of the extension to uninstall as a positional argument.',
),
); );
} }
return true; return true;

View file

@ -12,6 +12,7 @@ import {
type ExtensionUpdateInfo, type ExtensionUpdateInfo,
} from '@qwen-code/qwen-code-core'; } from '@qwen-code/qwen-code-core';
import { getExtensionManager } from './utils.js'; import { getExtensionManager } from './utils.js';
import { t } from '../../i18n/index.js';
interface UpdateArgs { interface UpdateArgs {
name?: string; name?: string;
@ -19,7 +20,14 @@ interface UpdateArgs {
} }
const updateOutput = (info: ExtensionUpdateInfo) => const updateOutput = (info: ExtensionUpdateInfo) =>
`Extension "${info.name}" successfully updated: ${info.originalVersion}${info.updatedVersion}.`; t(
'Extension "{{name}}" successfully updated: {{oldVersion}} → {{newVersion}}.',
{
name: info.name,
oldVersion: info.originalVersion,
newVersion: info.updatedVersion,
},
);
export async function handleUpdate(args: UpdateArgs) { export async function handleUpdate(args: UpdateArgs) {
const extensionManager = await getExtensionManager(); const extensionManager = await getExtensionManager();
@ -31,12 +39,15 @@ export async function handleUpdate(args: UpdateArgs) {
(extension) => extension.name === args.name, (extension) => extension.name === args.name,
); );
if (!extension) { if (!extension) {
console.log(`Extension "${args.name}" not found.`); console.log(t('Extension "{{name}}" not found.', { name: args.name }));
return; return;
} }
if (!extension.installMetadata) { if (!extension.installMetadata) {
console.log( console.log(
`Unable to install extension "${args.name}" due to missing install metadata`, t(
'Unable to install extension "{{name}}" due to missing install metadata',
{ name: args.name },
),
); );
return; return;
} }
@ -45,7 +56,9 @@ export async function handleUpdate(args: UpdateArgs) {
extensionManager, extensionManager,
); );
if (updateState !== ExtensionUpdateState.UPDATE_AVAILABLE) { if (updateState !== ExtensionUpdateState.UPDATE_AVAILABLE) {
console.log(`Extension "${args.name}" is already up to date.`); console.log(
t('Extension "{{name}}" is already up to date.', { name: args.name }),
);
return; return;
} }
// TODO(chrstnb): we should list extensions if the requested extension is not installed. // TODO(chrstnb): we should list extensions if the requested extension is not installed.
@ -59,10 +72,19 @@ export async function handleUpdate(args: UpdateArgs) {
updatedExtensionInfo.updatedVersion updatedExtensionInfo.updatedVersion
) { ) {
console.log( console.log(
`Extension "${args.name}" successfully updated: ${updatedExtensionInfo.originalVersion}${updatedExtensionInfo.updatedVersion}.`, t(
'Extension "{{name}}" successfully updated: {{oldVersion}} → {{newVersion}}.',
{
name: args.name,
oldVersion: updatedExtensionInfo.originalVersion,
newVersion: updatedExtensionInfo.updatedVersion,
},
),
); );
} else { } else {
console.log(`Extension "${args.name}" is already up to date.`); console.log(
t('Extension "{{name}}" is already up to date.', { name: args.name }),
);
} }
} catch (error) { } catch (error) {
console.error(getErrorMessage(error)); console.error(getErrorMessage(error));
@ -87,7 +109,7 @@ export async function handleUpdate(args: UpdateArgs) {
(info) => info.originalVersion !== info.updatedVersion, (info) => info.originalVersion !== info.updatedVersion,
); );
if (updateInfos.length === 0) { if (updateInfos.length === 0) {
console.log('No extensions to update.'); console.log(t('No extensions to update.'));
return; return;
} }
console.log(updateInfos.map((info) => updateOutput(info)).join('\n')); console.log(updateInfos.map((info) => updateOutput(info)).join('\n'));
@ -99,22 +121,25 @@ export async function handleUpdate(args: UpdateArgs) {
export const updateCommand: CommandModule = { export const updateCommand: CommandModule = {
command: 'update [<name>] [--all]', command: 'update [<name>] [--all]',
describe: describe: t(
'Updates all extensions or a named extension to the latest version.', 'Updates all extensions or a named extension to the latest version.',
),
builder: (yargs) => builder: (yargs) =>
yargs yargs
.positional('name', { .positional('name', {
describe: 'The name of the extension to update.', describe: t('The name of the extension to update.'),
type: 'string', type: 'string',
}) })
.option('all', { .option('all', {
describe: 'Update all extensions.', describe: t('Update all extensions.'),
type: 'boolean', type: 'boolean',
}) })
.conflicts('name', 'all') .conflicts('name', 'all')
.check((argv) => { .check((argv) => {
if (!argv.all && !argv.name) { if (!argv.all && !argv.name) {
throw new Error('Either an extension name or --all must be provided'); throw new Error(
t('Either an extension name or --all must be provided'),
);
} }
return true; return true;
}), }),

View file

@ -412,6 +412,91 @@ export default {
'Diese Erweiterung wird folgende Unteragenten installieren:', 'Diese Erweiterung wird folgende Unteragenten installieren:',
'Installation cancelled for "{{name}}".': 'Installation cancelled for "{{name}}".':
'Installation von "{{name}}" abgebrochen.', 'Installation von "{{name}}" abgebrochen.',
'--ref and --auto-update are not applicable for marketplace extensions.':
'--ref und --auto-update sind nicht anwendbar für Marketplace-Erweiterungen.',
'Extension "{{name}}" installed successfully and enabled.':
'Erweiterung "{{name}}" erfolgreich installiert und aktiviert.',
'Installs an extension from a git repository URL, local path, or claude marketplace (marketplace-url:plugin-name).':
'Installiert eine Erweiterung von einer Git-Repository-URL, einem lokalen Pfad oder dem Claude-Marketplace (marketplace-url:plugin-name).',
'The github URL, local path, or marketplace source (marketplace-url:plugin-name) of the extension to install.':
'Die GitHub-URL, der lokale Pfad oder die Marketplace-Quelle (marketplace-url:plugin-name) der zu installierenden Erweiterung.',
'The git ref to install from.': 'Die Git-Referenz für die Installation.',
'Enable auto-update for this extension.':
'Automatisches Update für diese Erweiterung aktivieren.',
'Enable pre-release versions for this extension.':
'Pre-Release-Versionen für diese Erweiterung aktivieren.',
'Acknowledge the security risks of installing an extension and skip the confirmation prompt.':
'Sicherheitsrisiken der Erweiterungsinstallation bestätigen und Bestätigungsaufforderung überspringen.',
'The source argument must be provided.':
'Das Quellargument muss angegeben werden.',
'Extension "{{name}}" successfully uninstalled.':
'Erweiterung "{{name}}" erfolgreich deinstalliert.',
'Uninstalls an extension.': 'Deinstalliert eine Erweiterung.',
'The name or source path of the extension to uninstall.':
'Der Name oder Quellpfad der zu deinstallierenden Erweiterung.',
'Please include the name of the extension to uninstall as a positional argument.':
'Bitte geben Sie den Namen der zu deinstallierenden Erweiterung als Positionsargument an.',
'Enables an extension.': 'Aktiviert eine Erweiterung.',
'The name of the extension to enable.':
'Der Name der zu aktivierenden Erweiterung.',
'The scope to enable the extenison in. If not set, will be enabled in all scopes.':
'Der Bereich, in dem die Erweiterung aktiviert werden soll. Wenn nicht gesetzt, wird sie in allen Bereichen aktiviert.',
'Extension "{{name}}" successfully enabled for scope "{{scope}}".':
'Erweiterung "{{name}}" erfolgreich für Bereich "{{scope}}" aktiviert.',
'Extension "{{name}}" successfully enabled in all scopes.':
'Erweiterung "{{name}}" erfolgreich in allen Bereichen aktiviert.',
'Invalid scope: {{scope}}. Please use one of {{scopes}}.':
'Ungültiger Bereich: {{scope}}. Bitte verwenden Sie einen von {{scopes}}.',
'Disables an extension.': 'Deaktiviert eine Erweiterung.',
'The name of the extension to disable.':
'Der Name der zu deaktivierenden Erweiterung.',
'The scope to disable the extenison in.':
'Der Bereich, in dem die Erweiterung deaktiviert werden soll.',
'Extension "{{name}}" successfully disabled for scope "{{scope}}".':
'Erweiterung "{{name}}" erfolgreich für Bereich "{{scope}}" deaktiviert.',
'Extension "{{name}}" successfully updated: {{oldVersion}} → {{newVersion}}.':
'Erweiterung "{{name}}" erfolgreich aktualisiert: {{oldVersion}} → {{newVersion}}.',
'Unable to install extension "{{name}}" due to missing install metadata':
'Erweiterung "{{name}}" kann aufgrund fehlender Installationsmetadaten nicht installiert werden',
'Extension "{{name}}" is already up to date.':
'Erweiterung "{{name}}" ist bereits aktuell.',
'Updates all extensions or a named extension to the latest version.':
'Aktualisiert alle Erweiterungen oder eine benannte Erweiterung auf die neueste Version.',
'The name of the extension to update.':
'Der Name der zu aktualisierenden Erweiterung.',
'Update all extensions.': 'Alle Erweiterungen aktualisieren.',
'Either an extension name or --all must be provided':
'Entweder ein Erweiterungsname oder --all muss angegeben werden',
'Lists installed extensions.': 'Listet installierte Erweiterungen auf.',
'Link extension failed to install.':
'Verknüpfte Erweiterung konnte nicht installiert werden.',
'Extension "{{name}}" linked successfully and enabled.':
'Erweiterung "{{name}}" erfolgreich verknüpft und aktiviert.',
'Links an extension from a local path. Updates made to the local path will always be reflected.':
'Verknüpft eine Erweiterung von einem lokalen Pfad. Änderungen am lokalen Pfad werden immer widergespiegelt.',
'The name of the extension to link.':
'Der Name der zu verknüpfenden Erweiterung.',
'Set a specific setting for an extension.':
'Legt eine bestimmte Einstellung für eine Erweiterung fest.',
'Name of the extension to configure.':
'Name der zu konfigurierenden Erweiterung.',
'The setting to configure (name or env var).':
'Die zu konfigurierende Einstellung (Name oder Umgebungsvariable).',
'The scope to set the setting in.':
'Der Bereich, in dem die Einstellung gesetzt werden soll.',
'List all settings for an extension.':
'Listet alle Einstellungen einer Erweiterung auf.',
'Name of the extension.': 'Name der Erweiterung.',
'Extension "{{name}}" has no settings to configure.':
'Erweiterung "{{name}}" hat keine zu konfigurierenden Einstellungen.',
'Settings for "{{name}}":': 'Einstellungen für "{{name}}":',
'(workspace)': '(Arbeitsbereich)',
'(user)': '(Benutzer)',
'[not set]': '[nicht gesetzt]',
'[value stored in keychain]': '[Wert in Schlüsselbund gespeichert]',
'Manage extension settings.': 'Erweiterungseinstellungen verwalten.',
'You need to specify a command (set or list).':
'Sie müssen einen Befehl angeben (set oder list).',
'manage IDE integration': 'IDE-Integration verwalten', 'manage IDE integration': 'IDE-Integration verwalten',
'check status of IDE integration': 'Status der IDE-Integration prüfen', 'check status of IDE integration': 'Status der IDE-Integration prüfen',
'install required IDE companion for {{ideName}}': 'install required IDE companion for {{ideName}}':

View file

@ -406,6 +406,85 @@ export default {
'This extension will install the following subagents:', 'This extension will install the following subagents:',
'Installation cancelled for "{{name}}".': 'Installation cancelled for "{{name}}".':
'Installation cancelled for "{{name}}".', 'Installation cancelled for "{{name}}".',
'--ref and --auto-update are not applicable for marketplace extensions.':
'--ref and --auto-update are not applicable for marketplace extensions.',
'Extension "{{name}}" installed successfully and enabled.':
'Extension "{{name}}" installed successfully and enabled.',
'Installs an extension from a git repository URL, local path, or claude marketplace (marketplace-url:plugin-name).':
'Installs an extension from a git repository URL, local path, or claude marketplace (marketplace-url:plugin-name).',
'The github URL, local path, or marketplace source (marketplace-url:plugin-name) of the extension to install.':
'The github URL, local path, or marketplace source (marketplace-url:plugin-name) of the extension to install.',
'The git ref to install from.': 'The git ref to install from.',
'Enable auto-update for this extension.':
'Enable auto-update for this extension.',
'Enable pre-release versions for this extension.':
'Enable pre-release versions for this extension.',
'Acknowledge the security risks of installing an extension and skip the confirmation prompt.':
'Acknowledge the security risks of installing an extension and skip the confirmation prompt.',
'The source argument must be provided.':
'The source argument must be provided.',
'Extension "{{name}}" successfully uninstalled.':
'Extension "{{name}}" successfully uninstalled.',
'Uninstalls an extension.': 'Uninstalls an extension.',
'The name or source path of the extension to uninstall.':
'The name or source path of the extension to uninstall.',
'Please include the name of the extension to uninstall as a positional argument.':
'Please include the name of the extension to uninstall as a positional argument.',
'Enables an extension.': 'Enables an extension.',
'The name of the extension to enable.':
'The name of the extension to enable.',
'The scope to enable the extenison in. If not set, will be enabled in all scopes.':
'The scope to enable the extenison in. If not set, will be enabled in all scopes.',
'Extension "{{name}}" successfully enabled for scope "{{scope}}".':
'Extension "{{name}}" successfully enabled for scope "{{scope}}".',
'Extension "{{name}}" successfully enabled in all scopes.':
'Extension "{{name}}" successfully enabled in all scopes.',
'Invalid scope: {{scope}}. Please use one of {{scopes}}.':
'Invalid scope: {{scope}}. Please use one of {{scopes}}.',
'Disables an extension.': 'Disables an extension.',
'The name of the extension to disable.':
'The name of the extension to disable.',
'The scope to disable the extenison in.':
'The scope to disable the extenison in.',
'Extension "{{name}}" successfully disabled for scope "{{scope}}".':
'Extension "{{name}}" successfully disabled for scope "{{scope}}".',
'Extension "{{name}}" successfully updated: {{oldVersion}} → {{newVersion}}.':
'Extension "{{name}}" successfully updated: {{oldVersion}} → {{newVersion}}.',
'Unable to install extension "{{name}}" due to missing install metadata':
'Unable to install extension "{{name}}" due to missing install metadata',
'Extension "{{name}}" is already up to date.':
'Extension "{{name}}" is already up to date.',
'Updates all extensions or a named extension to the latest version.':
'Updates all extensions or a named extension to the latest version.',
'Update all extensions.': 'Update all extensions.',
'Either an extension name or --all must be provided':
'Either an extension name or --all must be provided',
'Lists installed extensions.': 'Lists installed extensions.',
'Link extension failed to install.': 'Link extension failed to install.',
'Extension "{{name}}" linked successfully and enabled.':
'Extension "{{name}}" linked successfully and enabled.',
'Links an extension from a local path. Updates made to the local path will always be reflected.':
'Links an extension from a local path. Updates made to the local path will always be reflected.',
'The name of the extension to link.': 'The name of the extension to link.',
'Set a specific setting for an extension.':
'Set a specific setting for an extension.',
'Name of the extension to configure.': 'Name of the extension to configure.',
'The setting to configure (name or env var).':
'The setting to configure (name or env var).',
'The scope to set the setting in.': 'The scope to set the setting in.',
'List all settings for an extension.': 'List all settings for an extension.',
'Name of the extension.': 'Name of the extension.',
'Extension "{{name}}" has no settings to configure.':
'Extension "{{name}}" has no settings to configure.',
'Settings for "{{name}}":': 'Settings for "{{name}}":',
'(workspace)': '(workspace)',
'(user)': '(user)',
'[not set]': '[not set]',
'[value stored in keychain]': '[value stored in keychain]',
'Value:': 'Value:',
'Manage extension settings.': 'Manage extension settings.',
'You need to specify a command (set or list).':
'You need to specify a command (set or list).',
'manage IDE integration': 'manage IDE integration', 'manage IDE integration': 'manage IDE integration',
'check status of IDE integration': 'check status of IDE integration', 'check status of IDE integration': 'check status of IDE integration',
'install required IDE companion for {{ideName}}': 'install required IDE companion for {{ideName}}':

View file

@ -410,6 +410,84 @@ export default {
'This extension will install the following subagents:': 'This extension will install the following subagents:':
'Это расширение установит следующие подагенты:', 'Это расширение установит следующие подагенты:',
'Installation cancelled for "{{name}}".': 'Установка "{{name}}" отменена.', 'Installation cancelled for "{{name}}".': 'Установка "{{name}}" отменена.',
'--ref and --auto-update are not applicable for marketplace extensions.':
'--ref и --auto-update неприменимы для расширений из маркетплейса.',
'Extension "{{name}}" installed successfully and enabled.':
'Расширение "{{name}}" успешно установлено и включено.',
'Installs an extension from a git repository URL, local path, or claude marketplace (marketplace-url:plugin-name).':
'Устанавливает расширение из URL Git-репозитория, локального пути или маркетплейса Claude (marketplace-url:plugin-name).',
'The github URL, local path, or marketplace source (marketplace-url:plugin-name) of the extension to install.':
'URL GitHub, локальный путь или источник в маркетплейсе (marketplace-url:plugin-name) устанавливаемого расширения.',
'The git ref to install from.': 'Git-ссылка для установки.',
'Enable auto-update for this extension.':
'Включить автообновление для этого расширения.',
'Enable pre-release versions for this extension.':
'Включить пре-релизные версии для этого расширения.',
'Acknowledge the security risks of installing an extension and skip the confirmation prompt.':
'Подтвердить риски безопасности установки расширения и пропустить запрос подтверждения.',
'The source argument must be provided.':
'Необходимо указать аргумент источника.',
'Extension "{{name}}" successfully uninstalled.':
'Расширение "{{name}}" успешно удалено.',
'Uninstalls an extension.': 'Удаляет расширение.',
'The name or source path of the extension to uninstall.':
'Имя или путь к источнику удаляемого расширения.',
'Please include the name of the extension to uninstall as a positional argument.':
'Пожалуйста, укажите имя удаляемого расширения как позиционный аргумент.',
'Enables an extension.': 'Включает расширение.',
'The name of the extension to enable.': 'Имя включаемого расширения.',
'The scope to enable the extenison in. If not set, will be enabled in all scopes.':
'Область для включения расширения. Если не задана, будет включено во всех областях.',
'Extension "{{name}}" successfully enabled for scope "{{scope}}".':
'Расширение "{{name}}" успешно включено для области "{{scope}}".',
'Extension "{{name}}" successfully enabled in all scopes.':
'Расширение "{{name}}" успешно включено во всех областях.',
'Invalid scope: {{scope}}. Please use one of {{scopes}}.':
'Недопустимая область: {{scope}}. Пожалуйста, используйте одну из {{scopes}}.',
'Disables an extension.': 'Отключает расширение.',
'The name of the extension to disable.': 'Имя отключаемого расширения.',
'The scope to disable the extenison in.':
'Область для отключения расширения.',
'Extension "{{name}}" successfully disabled for scope "{{scope}}".':
'Расширение "{{name}}" успешно отключено для области "{{scope}}".',
'Extension "{{name}}" successfully updated: {{oldVersion}} → {{newVersion}}.':
'Расширение "{{name}}" успешно обновлено: {{oldVersion}} → {{newVersion}}.',
'Unable to install extension "{{name}}" due to missing install metadata':
'Невозможно установить расширение "{{name}}" из-за отсутствия метаданных установки',
'Extension "{{name}}" is already up to date.':
'Расширение "{{name}}" уже актуально.',
'Updates all extensions or a named extension to the latest version.':
'Обновляет все расширения или указанное расширение до последней версии.',
'The name of the extension to update.': 'Имя обновляемого расширения.',
'Update all extensions.': 'Обновить все расширения.',
'Either an extension name or --all must be provided':
'Необходимо указать имя расширения или --all',
'Lists installed extensions.': 'Показывает установленные расширения.',
'Link extension failed to install.':
'Не удалось установить связанное расширение.',
'Extension "{{name}}" linked successfully and enabled.':
'Расширение "{{name}}" успешно связано и включено.',
'Links an extension from a local path. Updates made to the local path will always be reflected.':
'Связывает расширение из локального пути. Изменения в локальном пути будут всегда отражаться.',
'The name of the extension to link.': 'Имя связываемого расширения.',
'Set a specific setting for an extension.':
'Установить конкретную настройку для расширения.',
'Name of the extension to configure.': 'Имя настраиваемого расширения.',
'The setting to configure (name or env var).':
'Настройка для конфигурирования (имя или переменная окружения).',
'The scope to set the setting in.': 'Область для установки настройки.',
'List all settings for an extension.': 'Показать все настройки расширения.',
'Name of the extension.': 'Имя расширения.',
'Extension "{{name}}" has no settings to configure.':
'Расширение "{{name}}" не имеет настроек для конфигурирования.',
'Settings for "{{name}}":': 'Настройки для "{{name}}":',
'(workspace)': '(рабочее пространство)',
'(user)': '(пользователь)',
'[not set]': '[не задано]',
'[value stored in keychain]': '[значение хранится в связке ключей]',
'Manage extension settings.': 'Управление настройками расширений.',
'You need to specify a command (set or list).':
'Необходимо указать команду (set или list).',
'manage IDE integration': 'Управление интеграцией с IDE', 'manage IDE integration': 'Управление интеграцией с IDE',
'check status of IDE integration': 'Проверить статус интеграции с IDE', 'check status of IDE integration': 'Проверить статус интеграции с IDE',
'install required IDE companion for {{ideName}}': 'install required IDE companion for {{ideName}}':

View file

@ -388,6 +388,78 @@ export default {
'This extension will install the following subagents:': 'This extension will install the following subagents:':
'此扩展将安装以下子代理:', '此扩展将安装以下子代理:',
'Installation cancelled for "{{name}}".': '已取消安装 "{{name}}"。', 'Installation cancelled for "{{name}}".': '已取消安装 "{{name}}"。',
'--ref and --auto-update are not applicable for marketplace extensions.':
'--ref 和 --auto-update 不适用于市场扩展。',
'Extension "{{name}}" installed successfully and enabled.':
'扩展 "{{name}}" 安装成功并已启用。',
'Installs an extension from a git repository URL, local path, or claude marketplace (marketplace-url:plugin-name).':
'从 Git 仓库 URL、本地路径或 Claude 市场marketplace-url:plugin-name安装扩展。',
'The github URL, local path, or marketplace source (marketplace-url:plugin-name) of the extension to install.':
'要安装的扩展的 GitHub URL、本地路径或市场源marketplace-url:plugin-name。',
'The git ref to install from.': '要安装的 Git 引用。',
'Enable auto-update for this extension.': '为此扩展启用自动更新。',
'Enable pre-release versions for this extension.': '为此扩展启用预发布版本。',
'Acknowledge the security risks of installing an extension and skip the confirmation prompt.':
'确认安装扩展的安全风险并跳过确认提示。',
'The source argument must be provided.': '必须提供来源参数。',
'Extension "{{name}}" successfully uninstalled.':
'扩展 "{{name}}" 卸载成功。',
'Uninstalls an extension.': '卸载扩展。',
'The name or source path of the extension to uninstall.':
'要卸载的扩展的名称或源路径。',
'Please include the name of the extension to uninstall as a positional argument.':
'请将要卸载的扩展名称作为位置参数。',
'Enables an extension.': '启用扩展。',
'The name of the extension to enable.': '要启用的扩展名称。',
'The scope to enable the extenison in. If not set, will be enabled in all scopes.':
'启用扩展的作用域。如果未设置,将在所有作用域中启用。',
'Extension "{{name}}" successfully enabled for scope "{{scope}}".':
'扩展 "{{name}}" 已在作用域 "{{scope}}" 中启用。',
'Extension "{{name}}" successfully enabled in all scopes.':
'扩展 "{{name}}" 已在所有作用域中启用。',
'Invalid scope: {{scope}}. Please use one of {{scopes}}.':
'无效的作用域:{{scope}}。请使用 {{scopes}} 之一。',
'Disables an extension.': '禁用扩展。',
'The name of the extension to disable.': '要禁用的扩展名称。',
'The scope to disable the extenison in.': '禁用扩展的作用域。',
'Extension "{{name}}" successfully disabled for scope "{{scope}}".':
'扩展 "{{name}}" 已在作用域 "{{scope}}" 中禁用。',
'Extension "{{name}}" successfully updated: {{oldVersion}} → {{newVersion}}.':
'扩展 "{{name}}" 更新成功:{{oldVersion}} → {{newVersion}}。',
'Unable to install extension "{{name}}" due to missing install metadata':
'由于缺少安装元数据,无法安装扩展 "{{name}}"',
'Extension "{{name}}" is already up to date.':
'扩展 "{{name}}" 已是最新版本。',
'Updates all extensions or a named extension to the latest version.':
'将所有扩展或指定扩展更新到最新版本。',
'The name of the extension to update.': '要更新的扩展名称。',
'Update all extensions.': '更新所有扩展。',
'Either an extension name or --all must be provided':
'必须提供扩展名称或 --all',
'Lists installed extensions.': '列出已安装的扩展。',
'Link extension failed to install.': '链接扩展安装失败。',
'Extension "{{name}}" linked successfully and enabled.':
'扩展 "{{name}}" 链接成功并已启用。',
'Links an extension from a local path. Updates made to the local path will always be reflected.':
'从本地路径链接扩展。对本地路径的更新将始终反映。',
'The name of the extension to link.': '要链接的扩展名称。',
'Set a specific setting for an extension.': '为扩展设置特定配置。',
'Name of the extension to configure.': '要配置的扩展名称。',
'The setting to configure (name or env var).':
'要配置的设置(名称或环境变量)。',
'The scope to set the setting in.': '设置配置的作用域。',
'List all settings for an extension.': '列出扩展的所有设置。',
'Name of the extension.': '扩展名称。',
'Extension "{{name}}" has no settings to configure.':
'扩展 "{{name}}" 没有可配置的设置。',
'Settings for "{{name}}":': '"{{name}}" 的设置:',
'(workspace)': '(工作区)',
'(user)': '(用户)',
'[not set]': '[未设置]',
'[value stored in keychain]': '[值存储在钥匙串中]',
'Manage extension settings.': '管理扩展设置。',
'You need to specify a command (set or list).':
'您需要指定命令set 或 list。',
'manage IDE integration': '管理 IDE 集成', 'manage IDE integration': '管理 IDE 集成',
'check status of IDE integration': '检查 IDE 集成状态', 'check status of IDE integration': '检查 IDE 集成状态',
'install required IDE companion for {{ideName}}': 'install required IDE companion for {{ideName}}':