Download src/services/plugins/pluginCliCommands.ts from chenbhao/codev: direct link, hf CLI and curl.
- Browser
- Download file 10.9 kB
-
https://huggingface.co/chenbhao/codev/resolve/main/src/services/plugins/pluginCliCommands.ts
- Command line
-
hf download hf://chenbhao/codev/src/services/plugins/pluginCliCommands.ts
-
curl -L -o pluginCliCommands.ts https://huggingface.co/chenbhao/codev/resolve/main/src/services/plugins/pluginCliCommands.ts
10.9 kB
| /** | |
| * CLI command wrappers for plugin operations | |
| * | |
| * This module provides thin wrappers around the core plugin operations | |
| * that handle CLI-specific concerns like console output and process exit. | |
| * | |
| * For the core operations (without CLI side effects), see pluginOperations.ts | |
| */ | |
| import figures from 'figures' | |
| import { errorMessage } from '../../utils/errors.js' | |
| import { gracefulShutdown } from '../../utils/gracefulShutdown.js' | |
| import { logError } from '../../utils/log.js' | |
| import { getManagedPluginNames } from '../../utils/plugins/managedPlugins.js' | |
| import { parsePluginIdentifier } from '../../utils/plugins/pluginIdentifier.js' | |
| import type { PluginScope } from '../../utils/plugins/schemas.js' | |
| import { writeToStdout } from '../../utils/process.js' | |
| import { | |
| buildPluginTelemetryFields, | |
| classifyPluginCommandError, | |
| } from '../../utils/telemetry/pluginTelemetry.js' | |
| import { | |
| type AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, | |
| type AnalyticsMetadata_I_VERIFIED_THIS_IS_PII_TAGGED, | |
| logEvent, | |
| } from '../analytics/index.js' | |
| import { | |
| disableAllPluginsOp, | |
| disablePluginOp, | |
| enablePluginOp, | |
| type InstallableScope, | |
| installPluginOp, | |
| uninstallPluginOp, | |
| updatePluginOp, | |
| VALID_INSTALLABLE_SCOPES, | |
| VALID_UPDATE_SCOPES, | |
| } from './pluginOperations.js' | |
| export { VALID_INSTALLABLE_SCOPES, VALID_UPDATE_SCOPES } | |
| type PluginCliCommand = | |
| | 'install' | |
| | 'uninstall' | |
| | 'enable' | |
| | 'disable' | |
| | 'disable-all' | |
| | 'update' | |
| /** | |
| * Generic error handler for plugin CLI commands. Emits | |
| * tengu_plugin_command_failed before exit so dashboards can compute a | |
| * success rate against the corresponding success events. | |
| */ | |
| function handlePluginCommandError( | |
| error: unknown, | |
| command: PluginCliCommand, | |
| plugin?: string, | |
| ): never { | |
| logError(error) | |
| const operation = plugin | |
| ? `${command} plugin "${plugin}"` | |
| : command === 'disable-all' | |
| ? 'disable all plugins' | |
| : `${command} plugins` | |
| // biome-ignore lint/suspicious/noConsole:: intentional console output | |
| console.error( | |
| `${figures.cross} Failed to ${operation}: ${errorMessage(error)}`, | |
| ) | |
| const telemetryFields = plugin | |
| ? (() => { | |
| const { name, marketplace } = parsePluginIdentifier(plugin) | |
| return { | |
| _PROTO_plugin_name: | |
| name as AnalyticsMetadata_I_VERIFIED_THIS_IS_PII_TAGGED, | |
| ...(marketplace && { | |
| _PROTO_marketplace_name: | |
| marketplace as AnalyticsMetadata_I_VERIFIED_THIS_IS_PII_TAGGED, | |
| }), | |
| ...buildPluginTelemetryFields( | |
| name, | |
| marketplace, | |
| getManagedPluginNames(), | |
| ), | |
| } | |
| })() | |
| : {} | |
| logEvent('tengu_plugin_command_failed', { | |
| command: | |
| command as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, | |
| error_category: classifyPluginCommandError( | |
| error, | |
| ) as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, | |
| ...telemetryFields, | |
| }) | |
| // eslint-disable-next-line custom-rules/no-process-exit | |
| process.exit(1) | |
| } | |
| /** | |
| * CLI command: Install a plugin non-interactively | |
| * @param plugin Plugin identifier (name or plugin@marketplace) | |
| * @param scope Installation scope: user, project, or local (defaults to 'user') | |
| */ | |
| export async function installPlugin( | |
| plugin: string, | |
| scope: InstallableScope = 'user', | |
| ): Promise<void> { | |
| try { | |
| // biome-ignore lint/suspicious/noConsole:: intentional console output | |
| console.log(`Installing plugin "${plugin}"...`) | |
| const result = await installPluginOp(plugin, scope) | |
| if (!result.success) { | |
| throw new Error(result.message) | |
| } | |
| // biome-ignore lint/suspicious/noConsole:: intentional console output | |
| console.log(`${figures.tick} ${result.message}`) | |
| // _PROTO_* routes to PII-tagged plugin_name/marketplace_name BQ columns. | |
| // Unredacted plugin_id was previously logged to general-access | |
| // additional_metadata for all users — dropped in favor of the privileged | |
| // column route. | |
| const { name, marketplace } = parsePluginIdentifier( | |
| result.pluginId || plugin, | |
| ) | |
| logEvent('tengu_plugin_installed_cli', { | |
| _PROTO_plugin_name: | |
| name as AnalyticsMetadata_I_VERIFIED_THIS_IS_PII_TAGGED, | |
| ...(marketplace && { | |
| _PROTO_marketplace_name: | |
| marketplace as AnalyticsMetadata_I_VERIFIED_THIS_IS_PII_TAGGED, | |
| }), | |
| scope: (result.scope || | |
| scope) as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, | |
| install_source: | |
| 'cli-explicit' as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, | |
| ...buildPluginTelemetryFields(name, marketplace, getManagedPluginNames()), | |
| }) | |
| // eslint-disable-next-line custom-rules/no-process-exit | |
| process.exit(0) | |
| } catch (error) { | |
| handlePluginCommandError(error, 'install', plugin) | |
| } | |
| } | |
| /** | |
| * CLI command: Uninstall a plugin non-interactively | |
| * @param plugin Plugin name or plugin@marketplace identifier | |
| * @param scope Uninstall from scope: user, project, or local (defaults to 'user') | |
| */ | |
| export async function uninstallPlugin( | |
| plugin: string, | |
| scope: InstallableScope = 'user', | |
| keepData = false, | |
| ): Promise<void> { | |
| try { | |
| const result = await uninstallPluginOp(plugin, scope, !keepData) | |
| if (!result.success) { | |
| throw new Error(result.message) | |
| } | |
| // biome-ignore lint/suspicious/noConsole:: intentional console output | |
| console.log(`${figures.tick} ${result.message}`) | |
| const { name, marketplace } = parsePluginIdentifier( | |
| result.pluginId || plugin, | |
| ) | |
| logEvent('tengu_plugin_uninstalled_cli', { | |
| _PROTO_plugin_name: | |
| name as AnalyticsMetadata_I_VERIFIED_THIS_IS_PII_TAGGED, | |
| ...(marketplace && { | |
| _PROTO_marketplace_name: | |
| marketplace as AnalyticsMetadata_I_VERIFIED_THIS_IS_PII_TAGGED, | |
| }), | |
| scope: (result.scope || | |
| scope) as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, | |
| ...buildPluginTelemetryFields(name, marketplace, getManagedPluginNames()), | |
| }) | |
| // eslint-disable-next-line custom-rules/no-process-exit | |
| process.exit(0) | |
| } catch (error) { | |
| handlePluginCommandError(error, 'uninstall', plugin) | |
| } | |
| } | |
| /** | |
| * CLI command: Enable a plugin non-interactively | |
| * @param plugin Plugin name or plugin@marketplace identifier | |
| * @param scope Optional scope. If not provided, finds the most specific scope for the current project. | |
| */ | |
| export async function enablePlugin( | |
| plugin: string, | |
| scope?: InstallableScope, | |
| ): Promise<void> { | |
| try { | |
| const result = await enablePluginOp(plugin, scope) | |
| if (!result.success) { | |
| throw new Error(result.message) | |
| } | |
| // biome-ignore lint/suspicious/noConsole:: intentional console output | |
| console.log(`${figures.tick} ${result.message}`) | |
| const { name, marketplace } = parsePluginIdentifier( | |
| result.pluginId || plugin, | |
| ) | |
| logEvent('tengu_plugin_enabled_cli', { | |
| _PROTO_plugin_name: | |
| name as AnalyticsMetadata_I_VERIFIED_THIS_IS_PII_TAGGED, | |
| ...(marketplace && { | |
| _PROTO_marketplace_name: | |
| marketplace as AnalyticsMetadata_I_VERIFIED_THIS_IS_PII_TAGGED, | |
| }), | |
| scope: | |
| result.scope as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, | |
| ...buildPluginTelemetryFields(name, marketplace, getManagedPluginNames()), | |
| }) | |
| // eslint-disable-next-line custom-rules/no-process-exit | |
| process.exit(0) | |
| } catch (error) { | |
| handlePluginCommandError(error, 'enable', plugin) | |
| } | |
| } | |
| /** | |
| * CLI command: Disable a plugin non-interactively | |
| * @param plugin Plugin name or plugin@marketplace identifier | |
| * @param scope Optional scope. If not provided, finds the most specific scope for the current project. | |
| */ | |
| export async function disablePlugin( | |
| plugin: string, | |
| scope?: InstallableScope, | |
| ): Promise<void> { | |
| try { | |
| const result = await disablePluginOp(plugin, scope) | |
| if (!result.success) { | |
| throw new Error(result.message) | |
| } | |
| // biome-ignore lint/suspicious/noConsole:: intentional console output | |
| console.log(`${figures.tick} ${result.message}`) | |
| const { name, marketplace } = parsePluginIdentifier( | |
| result.pluginId || plugin, | |
| ) | |
| logEvent('tengu_plugin_disabled_cli', { | |
| _PROTO_plugin_name: | |
| name as AnalyticsMetadata_I_VERIFIED_THIS_IS_PII_TAGGED, | |
| ...(marketplace && { | |
| _PROTO_marketplace_name: | |
| marketplace as AnalyticsMetadata_I_VERIFIED_THIS_IS_PII_TAGGED, | |
| }), | |
| scope: | |
| result.scope as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, | |
| ...buildPluginTelemetryFields(name, marketplace, getManagedPluginNames()), | |
| }) | |
| // eslint-disable-next-line custom-rules/no-process-exit | |
| process.exit(0) | |
| } catch (error) { | |
| handlePluginCommandError(error, 'disable', plugin) | |
| } | |
| } | |
| /** | |
| * CLI command: Disable all enabled plugins non-interactively | |
| */ | |
| export async function disableAllPlugins(): Promise<void> { | |
| try { | |
| const result = await disableAllPluginsOp() | |
| if (!result.success) { | |
| throw new Error(result.message) | |
| } | |
| // biome-ignore lint/suspicious/noConsole:: intentional console output | |
| console.log(`${figures.tick} ${result.message}`) | |
| logEvent('tengu_plugin_disabled_all_cli', {}) | |
| // eslint-disable-next-line custom-rules/no-process-exit | |
| process.exit(0) | |
| } catch (error) { | |
| handlePluginCommandError(error, 'disable-all') | |
| } | |
| } | |
| /** | |
| * CLI command: Update a plugin non-interactively | |
| * @param plugin Plugin name or plugin@marketplace identifier | |
| * @param scope Scope to update | |
| */ | |
| export async function updatePluginCli( | |
| plugin: string, | |
| scope: PluginScope, | |
| ): Promise<void> { | |
| try { | |
| writeToStdout( | |
| `Checking for updates for plugin "${plugin}" at ${scope} scope…\n`, | |
| ) | |
| const result = await updatePluginOp(plugin, scope) | |
| if (!result.success) { | |
| throw new Error(result.message) | |
| } | |
| writeToStdout(`${figures.tick} ${result.message}\n`) | |
| if (!result.alreadyUpToDate) { | |
| const { name, marketplace } = parsePluginIdentifier( | |
| result.pluginId || plugin, | |
| ) | |
| logEvent('tengu_plugin_updated_cli', { | |
| _PROTO_plugin_name: | |
| name as AnalyticsMetadata_I_VERIFIED_THIS_IS_PII_TAGGED, | |
| ...(marketplace && { | |
| _PROTO_marketplace_name: | |
| marketplace as AnalyticsMetadata_I_VERIFIED_THIS_IS_PII_TAGGED, | |
| }), | |
| old_version: (result.oldVersion || | |
| 'unknown') as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, | |
| new_version: (result.newVersion || | |
| 'unknown') as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, | |
| ...buildPluginTelemetryFields( | |
| name, | |
| marketplace, | |
| getManagedPluginNames(), | |
| ), | |
| }) | |
| } | |
| await gracefulShutdown(0) | |
| } catch (error) { | |
| handlePluginCommandError(error, 'update', plugin) | |
| } | |
| } | |