> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zopio.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Plugins

> Extend the Zopio CLI with custom plugins

# Plugins

The Zopio CLI supports a powerful plugin system that allows you to extend its functionality with custom commands and features.

## Using Plugins

Plugins are automatically loaded from the `.zopio/plugins` directory in your project. You can also specify additional plugin directories using the `ZOPIO_PLUGINS_DIR` environment variable.

## Creating Plugins

A Zopio CLI plugin is a TypeScript module that exports a `register` function. This function receives the CLI instance and can register new commands or modify existing ones.

### Basic Plugin Structure

```typescript theme={"system"}
// .zopio/plugins/my-plugin.ts
import { Command } from 'commander';
import { ZopioCLI } from 'zopio-cli';

export function register(cli: ZopioCLI) {
  const command = new Command('my-command')
    .description('My custom command')
    .option('-o, --option <value>', 'Custom option')
    .action((options) => {
      // Command implementation
      console.log('Running my custom command with options:', options);
    });

  cli.addCommand(command);
}
```

### Plugin Configuration

Plugins can include a configuration file that defines metadata and dependencies:

```json theme={"system"}
// .zopio/plugins/my-plugin.config.json
{
  "name": "my-plugin",
  "version": "1.0.0",
  "description": "My custom Zopio CLI plugin",
  "author": "Your Name",
  "dependencies": {
    "lodash": "^4.17.21"
  }
}
```

## Example Plugins

<CodeGroup>
  ```typescript deployment theme={"system"}
  // .zopio/plugins/deployment.ts
  import { Command } from 'commander';
  import { ZopioCLI } from 'zopio-cli';
  import { deploy } from './deployment/utils';

  export function register(cli: ZopioCLI) {
    const command = new Command('deploy')
      .description('Deploy your Zopio application')
      .option('-e, --environment <env>', 'Deployment environment', 'production')
      .option('-c, --config <path>', 'Path to deployment config')
      .action(async (options) => {
        await deploy(options);
      });

    cli.addCommand(command);
  }
  ```

  ```typescript analytics theme={"system"}
  // .zopio/plugins/analytics.ts
  import { Command } from 'commander';
  import { ZopioCLI } from 'zopio-cli';
  import { generateReport } from './analytics/reports';

  export function register(cli: ZopioCLI) {
    const command = new Command('analytics')
      .description('Generate analytics reports')
      .option('-t, --type <type>', 'Report type', 'usage')
      .option('-f, --format <format>', 'Output format', 'json')
      .action(async (options) => {
        await generateReport(options);
      });

    cli.addCommand(command);
  }
  ```
</CodeGroup>

## Hooks

Plugins can also register hooks to extend or modify the behavior of existing commands:

```typescript theme={"system"}
// .zopio/plugins/hooks-example.ts
import { ZopioCLI } from 'zopio-cli';

export function register(cli: ZopioCLI) {
  // Pre-init hook
  cli.hooks.register('pre:init', async (options) => {
    console.log('Before initializing project with options:', options);
  });

  // Post-init hook
  cli.hooks.register('post:init', async (result) => {
    console.log('Project initialized successfully:', result);
  });
}
```

## Available Hooks

| Hook            | Description                       |
| --------------- | --------------------------------- |
| `pre:init`      | Before project initialization     |
| `post:init`     | After project initialization      |
| `pre:generate`  | Before generating a module        |
| `post:generate` | After generating a module         |
| `pre:crud`      | Before generating CRUD operations |
| `post:crud`     | After generating CRUD operations  |
| `pre:job`       | Before creating a job             |
| `post:job`      | After creating a job              |

<Alert type="warning">
  Plugins have full access to the file system and can perform potentially dangerous operations. Only install plugins from trusted sources.
</Alert>

## Publishing Plugins

You can publish your plugins to npm to share them with the community:

```bash theme={"system"}
# Create a new plugin package
mkdir zopio-plugin-myfeature
cd zopio-plugin-myfeature

# Initialize package
npm init -y

# Implement your plugin
# ...

# Publish to npm
npm publish
```

Users can then install your plugin globally or locally:

```bash theme={"system"}
npm install -g zopio-plugin-myfeature
# or
npm install --save-dev zopio-plugin-myfeature
```

<Alert type="tip">
  Follow the naming convention <code>zopio-plugin-{feature}</code> for your plugin packages to make them easier to discover.
</Alert>
