Skip to main content

CLI Plugin Commands

The CLI provides two levels of plugin management: global user-level plugin configuration (plugins) and work-scoped plugin overrides (work plugins). Both commands present interactive, searchable interfaces for browsing, enabling, and configuring plugins.

Source: apps/cli/src/commands/plugins/ and apps/cli/src/commands/work/plugins.ts

Global Plugin Management

ever-works plugins [options]

Options

OptionDescription
-c, --category <category>Filter plugins by category (e.g. search, ai-provider, deployment)

Interactive Flow

The plugin list is grouped by category and supports type-ahead search. Each plugin shows its status (enabled/disabled/system), category, and description.

Plugin Detail View

When a plugin is selected, the CLI displays:

FieldDescription
IDPlugin identifier
VersionSemantic version
CategoryPlugin category (e.g. search, ai-provider)
StatusSystem, Enabled, or Disabled
AboutPlugin description
ProvidesCapability list (e.g. search, content-extractor)
SettingsField count and required count

Enable Flow

Enabling a plugin follows this sequence:

  1. Check required settings -- Uses getRequiredFields() and validateRequiredSettings() from @ever-works/plugin/api to determine if mandatory fields are missing.
  2. Prompt missing settings -- If required fields are missing, PluginSettingsPromptService collects them before enabling.
  3. Auto-enable for works -- Optionally enables the plugin for all existing works.
  4. API call -- Sends settings and secret settings to apiService.enablePlugin().
// Enable data structure
{
settings?: Record<string, unknown>;
secretSettings?: Record<string, unknown>;
autoEnableForWorks?: boolean;
}

System plugins cannot be enabled or disabled -- they are always active.

Disable Flow

Disabling prompts for confirmation before calling apiService.disablePlugin(). System plugins do not show the disable option.

Configure Settings

The settings flow:

  1. Fetches full plugin details (to load current settings).
  2. Splits settings into regular and secret using splitSettingsBySecret().
  3. Prompts for each visible field using PluginSettingsPromptService.
  4. Validates required fields and constraints.
  5. Saves with confirmation.

Settings can only be configured when the plugin is enabled.

Settings Prompt Service

The PluginSettingsPromptService handles all interactive settings input. It extends BasePromptService from @ever-works/cli-shared.

Source: apps/cli/src/commands/plugins/plugin-settings-prompt.service.ts

Field Type Handling

Schema TypeWidgetPrompt Style
string + x-secret--Password input (masked)
stringmodel-selectFetches models from API, presents as list with context size
string + enum--Select list from enum values
boolean--Yes/No confirmation
number--Numeric input with minimum/maximum validation
string (default)--Text input

Model Selection

When a field uses the model-select widget, the prompt service:

  1. Calls apiService.listPluginModels(pluginId) to fetch available models.
  2. Caches the result per plugin ID for the session.
  3. Displays models sorted alphabetically with context window size (e.g. 128K ctx, 1.0M ctx).
  4. Adds the current value if it is not in the fetched list (marked as (current)).
  5. Offers a "Enter custom model ID" option for unlisted models.

If the API call fails, the prompt falls back to a plain text input.

Conditional Fields

The service supports showIf conditions on schema properties:

if (prop.showIf) {
const refValue = settings[prop.showIf.field] ?? secretSettings[prop.showIf.field];
if (refValue !== prop.showIf.value) continue; // skip this field
}

This allows plugins to show fields conditionally based on other setting values.

Validation

After collecting all fields, two validations run:

ValidationSourceBehavior on Failure
validateRequiredSettings()@ever-works/plugin/apiLists missing fields, offers retry
validateSettingsConstraints()@ever-works/plugin/apiLists constraint errors, offers retry

Settings are sanitized with sanitizeSettingsForSave() before returning.

Work Plugin Management

ever-works work plugins

This command manages plugins at the work level. Work-scoped settings override user-level settings, and plugins can be individually enabled or disabled per work.

Interactive Flow

Capability Providers Display

Before the plugin list, the command shows the current active provider for each capability:

Active Providers
──────────────────────────────────────────────────
search → exa
ai-provider → openai
deployment → vercel

Work Plugin Actions

ActionDescription
Enable for workEnables the plugin at work scope. If the plugin has multiple capabilities, prompts for which one to activate.
Disable for workDisables the plugin at work scope with confirmation.
Set active capabilityShown when a plugin provides more than one capability. Switches which capability is active.
Configure work settingsPrompts for work-scoped settings. Uses user-level settings as fallback defaults (shown as Inherited: value).

Settings Inheritance

Work settings inherit from user-level settings. The prompt shows inherited values and allows overriding:

const promptService = new PluginSettingsPromptService();
const result = await promptService.promptSettings({
pluginId: plugin.pluginId,
schema: plugin.settingsSchema,
currentSettings: regular,
currentSecretSettings: secret,
scope: 'work',
scopes: ['global', 'work'],
fallbackSettings: userPlugin.settings // inherited defaults
});

When scope is 'work' and an inherited value exists, the prompt displays:

Inherited: gpt-5.1

Leaving a field blank preserves the inherited value.

Permission Check

Both plugin commands require the editor role or higher. The canEdit() function validates the user's role:

if (!canEdit(role)) {
console.log('You do not have permission to perform this action.');
console.log(`Your role: ${role}. Required: editor or higher.`);
return;
}

API Methods Used

MethodCommandDescription
getPlugins(options?)pluginsList all plugins, optionally filtered by category
getPlugin(pluginId)pluginsGet full plugin details with settings
enablePlugin(pluginId, data)pluginsEnable a plugin with optional settings
disablePlugin(pluginId)pluginsDisable a plugin
updatePluginSettings(pluginId, data)pluginsSave plugin settings
listPluginModels(pluginId)pluginsFetch available AI models for a plugin
getWorkPlugins(workId)work pluginsList plugins for a specific work
enableWorkPlugin(dirId, pluginId, data)work pluginsEnable a plugin at work scope
disableWorkPlugin(dirId, pluginId)work pluginsDisable a plugin at work scope
setWorkPluginCapability(dirId, pluginId, cap)work pluginsSet the active capability for a plugin
updateWorkPluginSettings(dirId, pluginId, data)work pluginsSave work-level plugin settings

Utility Functions

The CLI plugin commands rely on shared utilities from @ever-works/plugin/api:

FunctionPurpose
getVisibleProperties(schema, scopes)Returns schema properties visible at the given scopes, filtering out hidden and admin-only fields
getRequiredFields(schema, scopes)Returns field names that are required at the given scopes
validateRequiredSettings(regular, secret, schema, scopes, scope)Returns list of missing required field names
splitSettingsBySecret(settings, schema, scopes)Splits a flat settings object into { regular, secret } based on x-secret markers
sanitizeSettingsForSave(settings, scope)Removes undefined values and scope-irrelevant fields
validateSettingsConstraints(merged, props)Validates minimum, maximum, pattern, and other JSON Schema constraints