(
plugin: string,
options: { scope?: string; cowork?: boolean },
)
| 628 | |
| 629 | // plugin install (lines 5690–5721) |
| 630 | export async function pluginInstallHandler( |
| 631 | plugin: string, |
| 632 | options: { scope?: string; cowork?: boolean }, |
| 633 | ): Promise<void> { |
| 634 | if (options.cowork) setUseCoworkPlugins(true) |
| 635 | const scope = options.scope || 'user' |
| 636 | if (options.cowork && scope !== 'user') { |
| 637 | cliError('--cowork can only be used with user scope') |
| 638 | } |
| 639 | if ( |
| 640 | !VALID_INSTALLABLE_SCOPES.includes( |
| 641 | scope as (typeof VALID_INSTALLABLE_SCOPES)[number], |
| 642 | ) |
| 643 | ) { |
| 644 | cliError( |
| 645 | `Invalid scope: ${scope}. Must be one of: ${VALID_INSTALLABLE_SCOPES.join(', ')}.`, |
| 646 | ) |
| 647 | } |
| 648 | // _PROTO_* routes to PII-tagged plugin_name/marketplace_name BQ columns. |
| 649 | // Unredacted plugin arg was previously logged to general-access |
| 650 | // additional_metadata for all users — dropped in favor of the privileged |
| 651 | // column route. marketplace may be undefined (fires before resolution). |
| 652 | const { name, marketplace } = parsePluginIdentifier(plugin) |
| 653 | logEvent('tengu_plugin_install_command', { |
| 654 | _PROTO_plugin_name: name as AnalyticsMetadata_I_VERIFIED_THIS_IS_PII_TAGGED, |
| 655 | ...(marketplace && { |
| 656 | _PROTO_marketplace_name: |
| 657 | marketplace as AnalyticsMetadata_I_VERIFIED_THIS_IS_PII_TAGGED, |
| 658 | }), |
| 659 | scope: scope as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, |
| 660 | }) |
| 661 | |
| 662 | await installPlugin(plugin, scope as 'user' | 'project' | 'local') |
| 663 | } |
| 664 | |
| 665 | // plugin uninstall (lines 5738–5769) |
| 666 | export async function pluginUninstallHandler( |
no test coverage detected