# pants-claude-plugins

A [Pants](https://www.pantsbuild.org/) plugin for installing [Claude Code](https://claude.ai/code) plugins into your projects.

Define `claude_plugin` targets in your BUILD files, then run `pants claude-install ::` to install them all.

## Installation

### From PyPI

```toml
# pants.toml
[GLOBAL]
plugins = ["jaymd96-pants-claude-plugins==0.2.0"]
backend_packages = ["pants_claude_plugins"]
```

### From Source (in-repo)

```toml
# pants.toml
[GLOBAL]
pythonpath = ["%(buildroot)s/pants-plugins/pants-claude-plugins/src"]
backend_packages = ["pants_claude_plugins"]
```

## Quick Start

1. **Add a marketplace** (if not using the official one):

   ```bash
   claude /plugin marketplace add anthropics/claude-code
   ```

2. **Define plugins in BUILD files**:

   ```python
   # tools/claude/BUILD
   claude_plugin(
       name="github-integration",
       plugin="github",
       marketplace="claude-plugins-official",
       scope="project",
       description="GitHub integration for PR workflows",
   )

   claude_plugin(
       name="commit-commands",
       plugin="commit-commands",
       marketplace="anthropics-claude-code",
       scope="project",
       tags=["workflow"],
   )
   ```

3. **Install all plugins**:

   ```bash
   pants claude-install ::
   ```

## Target Reference

### `claude_plugin`

Defines a Claude Code plugin to be installed.

| Field | Type | Required | Default | Description |
|-------|------|----------|---------|-------------|
| `plugin` | string | ✓ | - | Plugin name (e.g., "github", "commit-commands") |
| `marketplace` | string | ✓ | - | Marketplace identifier (e.g., "claude-plugins-official") |
| `scope` | string | | subsystem default | Installation scope: "project", "user", or "local" |
| `enabled` | bool | | `True` | Whether to install this plugin |
| `description` | string | | | Human-readable description |
| `tags` | list[string] | | | Tags for filtering |

### Installation Scopes

- **project**: Install for all collaborators (adds to `.claude/settings.json`)
- **user**: Install for the current user across all projects
- **local**: Install for yourself in this repository only

## Configuration

Configure the plugin in `pants.toml`:

```toml
[claude-plugins]
# Default scope when not specified per-target
default_scope = "project"

# Path to claude binary (or leave as "claude" to use $PATH)
claude_binary = "claude"

# Skip installation entirely (useful for CI without Claude)
skip = false

# Fail the build if any plugin installation fails
fail_on_error = true

# Preview what would be installed without installing
dry_run = false

# Include plugins bundled with other Pants backends
include_bundled = false
```

## Usage Examples

### Install All Plugins

```bash
pants claude-install ::
```

### Install Plugins in a Directory

```bash
pants claude-install tools/claude:
```

### Install Specific Plugin

```bash
pants claude-install tools/claude:github-integration
```

### Dry Run (Preview)

```bash
pants claude-install --dry-run ::
```

### Skip in CI

```bash
# In CI where Claude isn't installed
pants claude-install --skip ::
```

### Filter by Tags

```bash
pants --tag=required claude-install ::
```

### Include Bundled Plugins

Some Pants plugins bundle recommended Claude Code plugins. Install them with:

```bash
pants claude-install --include-bundled ::
```

## Example Project Structure

```
my-project/
├── pants.toml
├── tools/
│   └── claude/
│       └── BUILD
├── src/
│   └── ...
└── .claude/
    └── settings.json  # Updated by claude-install
```

### Example BUILD File

```python
# tools/claude/BUILD

# Official Anthropic plugins
claude_plugin(
    name="github",
    plugin="github",
    marketplace="claude-plugins-official",
    scope="project",
    description="GitHub integration for issues and PRs",
)

claude_plugin(
    name="typescript-lsp",
    plugin="typescript-lsp",
    marketplace="claude-plugins-official",
    scope="project",
    description="TypeScript language server for code intelligence",
)

# Demo marketplace plugins
claude_plugin(
    name="commit-commands",
    plugin="commit-commands",
    marketplace="anthropics-claude-code",
    scope="project",
    tags=["workflow"],
)

# Disabled plugin (kept for documentation)
claude_plugin(
    name="experimental",
    plugin="some-experimental-plugin",
    marketplace="my-org-marketplace",
    enabled=False,
    description="Not ready for team use yet",
)
```

## Bundling Claude Plugins with Your Pants Plugin

If you're a Pants plugin author, you can bundle recommended Claude Code plugins with your plugin.

Create a `bundled_claude_plugins.py` file in your plugin package:

```python
# src/your_plugin/bundled_claude_plugins.py

# Marketplaces to add before installing plugins (GitHub repos, git URLs, etc.)
# These are automatically added when users run --include-bundled
BUNDLED_MARKETPLACES = [
    "anthropics/claude-code",  # GitHub owner/repo format
    # "https://gitlab.com/company/plugins.git",  # Full git URL also supported
]

BUNDLED_CLAUDE_PLUGINS = [
    {
        "plugin": "github",
        "marketplace": "claude-plugins-official",
        "scope": "project",  # optional
        "description": "GitHub integration",  # optional
    },
    {
        "plugin": "commit-commands",
        "marketplace": "anthropics-claude-code",  # This marketplace is auto-added above
    },
]
```

When users install your plugin and run `pants claude-install --include-bundled ::`:
1. Any bundled marketplaces are automatically added
2. Then the bundled plugins are installed from those marketplaces

## Requirements

- Pants 2.18.0 or later
- Python 3.11+
- Claude Code CLI installed and available in `$PATH`

## Contributing

1. Clone the repository
2. Install development dependencies: `hatch env create`
3. Run tests: `hatch run test`
4. Format code: `hatch run fmt`
5. Check linting: `hatch run lint`

## License

MIT License - see [LICENSE](LICENSE) for details.
