claudelint


Nameclaudelint JSON
Version 0.3.2 PyPI version JSON
download
home_pageNone
SummaryA configurable, rule-based linter for Claude Code plugins
upload_time2025-11-03 19:50:34
maintainerNone
docs_urlNone
authorNone
requires_python>=3.8
licenseApache-2.0
keywords claude claude-code linter plugin validation
VCS
bugtrack_url
requirements PyYAML
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # claudelint

A configurable, rule-based linter for [Claude Code](https://docs.claude.com/en/docs/claude-code) [plugins](https://docs.claude.com/en/docs/claude-code/plugins) and [plugin marketplaces](https://docs.claude.com/en/docs/claude-code/plugin-marketplaces).

## Features

✨ **Context-Aware** - Automatically detects single plugin vs marketplace repositories  
🎯 **Rule-Based** - Enable/disable individual rules with configurable severity levels  
🔌 **Extensible** - Load custom rules from Python files  
📋 **Comprehensive** - Validates plugin structure, metadata, command format, and more  
🐳 **Containerized** - Run via Docker for consistent, isolated linting  
⚡ **Fast** - Efficient validation with clear, actionable output

## Installation

### Via uvx (easiest - no install required)

```bash
# From git (works before PyPI release)
uvx --from 'git+https://github.com/stbenjam/claudelint' claudelint

# Once published to PyPI, simply:
uvx claudelint

# With specific path
uvx --from 'git+https://github.com/stbenjam/claudelint' claudelint /path/to/plugin
```

### Via pip (recommended for regular use)

```bash
pip install claudelint
```

### From source

```bash
git clone https://github.com/stbenjam/claudelint.git
cd claudelint
pip install -e .
```

### Using Docker

```bash
docker pull ghcr.io/stbenjam/claudelint:latest

# Run on current directory
docker run -v $(pwd):/workspace ghcr.io/stbenjam/claudelint
```

## Quick Start

```bash
# Lint current directory
claudelint

# Lint specific directory
claudelint /path/to/plugin

# Verbose output
claudelint -v

# Strict mode (warnings as errors)
claudelint --strict

# Generate default config
claudelint --init

# List all available rules
claudelint --list-rules
```

## Repository Types

claudelint automatically detects your repository structure:

### Single Plugin
```
my-plugin/
├── .claude-plugin/
│   └── plugin.json
├── commands/
│   └── my-command.md
└── README.md
```

### Marketplace (Multiple Plugins)

claudelint supports multiple marketplace structures per the [Claude Code specification](https://docs.claude.com/en/docs/claude-code/plugin-marketplaces):

#### Traditional Structure (plugins/ directory)
```
marketplace/
├── .claude-plugin/
│   └── marketplace.json
└── plugins/
    ├── plugin-one/
    │   ├── .claude-plugin/
    │   └── commands/
    └── plugin-two/
        ├── .claude-plugin/
        └── commands/
```

#### Flat Structure (root-level plugin)
```
marketplace/
├── .claude-plugin/
│   └── marketplace.json    # source: "./"
├── commands/                # Plugin components at root
│   └── my-command.md
└── skills/
    └── my-skill/
```

#### Custom Paths
```
marketplace/
├── .claude-plugin/
│   └── marketplace.json    # source: "./custom/my-plugin"
└── custom/
    └── my-plugin/
        ├── commands/
        └── skills/
```

#### Mixed Structures
Plugins from `plugins/`, custom paths, and remote sources can coexist in one marketplace. Only local sources are validated.

## Marketplace Features

### Flexible Plugin Sources

claudelint understands all [plugin source types](https://docs.claude.com/en/docs/claude-code/plugin-marketplaces#plugin-sources) and validates any sources that resolve to local paths:

- **Relative paths**: `"source": "./"` (flat structure), `"source": "./custom/path"`
- **GitHub repositories**: `"source": {"source": "github", "repo": "owner/repo"}`
- **Git URLs**: `"source": {"source": "url", "url": "https://..."}`

Remote sources (GitHub, git URLs) are logged and skipped during local validation. They are valid per spec but cannot be checked until the plugin is fetched locally.

### Strict Mode

The `strict` field in marketplace entries controls validation behavior:

```json5
{
  "name": "my-plugin",
  "source": "./",
  "strict": false,    // plugin.json becomes optional
  "description": "Plugin description can be in marketplace.json"
}
```

When `strict: false`:
- `plugin.json` is optional
- Marketplace entry serves as the complete plugin manifest
- Plugin metadata is validated from marketplace.json
- Skills, commands, and other components work normally

When `strict: true` (default):
- `plugin.json` is required
- Marketplace entry supplements plugin.json metadata

## Configuration

Create `.claudelint.yaml` in your repository root:

```yaml
# Enable/disable rules
rules:
  plugin-json-required:
    enabled: true
    severity: error
  
  plugin-naming:
    enabled: true
    severity: warning
  
  command-sections:
    enabled: true
    severity: warning
  
  # 'auto' enables only for marketplace repos
  marketplace-registration:
    enabled: auto
    severity: error

# Load custom rules
custom-rules:
  - ./my-custom-rules.py

# Exclude patterns
exclude:
  - "**/node_modules/**"
  - "**/.git/**"

# Treat warnings as errors
strict: false
```

### Generating Default Config

```bash
claudelint --init
```

This creates `.claudelint.yaml` with all builtin rules enabled.

## Builtin Rules

### Plugin Structure

| Rule ID | Description | Default Severity | Notes |
|---------|-------------|------------------|-------|
| `plugin-json-required` | Plugin must have `.claude-plugin/plugin.json` | error | Skipped when `strict: false` in marketplace |
| `plugin-json-valid` | Plugin.json must be valid with required fields | error | |
| `plugin-naming` | Plugin names should use kebab-case | warning | |
| `commands-dir-required` | Plugin should have a commands directory | warning (disabled by default) | |
| `commands-exist` | Plugin should have at least one command file | info (disabled by default) | |
| `plugin-readme` | Plugin should have a README.md file | warning | |

### Command Format

| Rule ID | Description | Default Severity |
|---------|-------------|------------------|
| `command-naming` | Command files should use kebab-case | warning |
| `command-frontmatter` | Command files must have valid frontmatter | error |
| `command-sections` | Commands should have Name, Synopsis, Description, Implementation sections | warning |
| `command-name-format` | Command Name section should be `plugin:command` format | warning |

### Marketplace

| Rule ID | Description | Default Severity | Notes |
|---------|-------------|------------------|-------|
| `marketplace-json-valid` | Marketplace.json must be valid JSON | error (auto) | |
| `marketplace-registration` | Plugins must be registered in marketplace.json | error (auto) | Supports flat structures, custom paths, and remote sources |

### Skills

| Rule ID | Description | Default Severity |
|---------|-------------|------------------|
| `skill-frontmatter` | SKILL.md files should have frontmatter | warning |

### Agents

| Rule ID | Description | Default Severity |
|---------|-------------|------------------|
| `agent-frontmatter` | Agent files must have valid frontmatter with description and capabilities | error |

### Hooks

| Rule ID | Description | Default Severity |
|---------|-------------|------------------|
| `hooks-json-valid` | hooks.json must be valid JSON with proper hook configuration structure | error |

### MCP (Model Context Protocol)

| Rule ID | Description | Default Severity | Notes |
|---------|-------------|------------------|-------|
| `mcp-valid-json` | MCP configuration must be valid JSON with proper mcpServers structure | error | Validates both `.mcp.json` and `mcpServers` in `plugin.json` |
| `mcp-prohibited` | Plugins should not enable MCP servers | error (disabled by default) | Security/policy rule - enable to prohibit MCP usage |

## Custom Rules

Create custom validation rules by extending the `Rule` base class:

```python
# my_custom_rules.py
from pathlib import Path
from typing import List
from claudelint import Rule, RuleViolation, Severity, RepositoryContext

class NoTodoCommentsRule(Rule):
    @property
    def rule_id(self) -> str:
        return "no-todo-comments"
    
    @property
    def description(self) -> str:
        return "Command files should not contain TODO comments"
    
    def default_severity(self) -> Severity:
        return Severity.WARNING
    
    def check(self, context: RepositoryContext) -> List[RuleViolation]:
        violations = []
        
        for plugin_path in context.plugins:
            commands_dir = plugin_path / "commands"
            if not commands_dir.exists():
                continue
            
            for cmd_file in commands_dir.glob("*.md"):
                with open(cmd_file, 'r') as f:
                    content = f.read()
                    if 'TODO' in content:
                        violations.append(
                            self.violation(
                                "Found TODO comment in command file",
                                file_path=cmd_file
                            )
                        )
        
        return violations
```

Then reference it in `.claudelint.yaml`:

```yaml
custom-rules:
  - ./my_custom_rules.py

rules:
  no-todo-comments:
    enabled: true
    severity: warning
```

## CI/CD Integration

### GitHub Actions

```yaml
name: Lint Claude Plugins

on: [pull_request, push]

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.x'
      
      - name: Install claudelint
        run: pip install claudelint
      
      - name: Run linter
        run: claudelint --strict
```

### GitLab CI

```yaml
lint-plugins:
  image: python:3.11
  script:
    - pip install claudelint
    - claudelint --strict
```

### Docker

```bash
docker run -v $(pwd):/workspace -w /workspace ghcr.io/stbenjam/claudelint --strict
```

## Exit Codes

- `0` - Success (no errors, or warnings only in non-strict mode)
- `1` - Failure (errors found, or warnings in strict mode)

## Examples

### Example Output

```
Linting Claude plugins in: /path/to/marketplace

Errors:
  ✗ ERROR [plugins/git/.claude-plugin/plugin.json]: Missing plugin.json
  ✗ ERROR [.claude-plugin/marketplace.json]: Plugin 'new-plugin' not registered

Warnings:
  ⚠ WARNING [plugins/utils]: Missing README.md (recommended)
  ⚠ WARNING [plugins/jira/commands/solve.md]: Missing recommended section '## Implementation'

Summary:
  Errors:   2
  Warnings: 2
```

### Disabling Specific Rules

```yaml
rules:
  plugin-readme:
    enabled: false  # Don't require README files
  
  command-sections:
    enabled: false  # Don't check for specific sections
```

### Changing Severity

```yaml
rules:
  plugin-naming:
    severity: error  # Make naming violations errors instead of warnings
  
  command-name-format:
    severity: info   # Downgrade to info level
```

## Development

### Running Tests

```bash
pytest tests/
```

### Building Docker Image

```bash
docker build -t claudelint .
```

### Project Structure

```
claudelint/
├── src/
│   ├── rule.py          # Base Rule class
│   ├── context.py       # Repository detection
│   ├── config.py        # Configuration management
│   └── linter.py        # Main linter orchestration
├── rules/
│   └── builtin/         # Builtin validation rules
├── tests/               # Test suite
├── examples/            # Example configs and custom rules
├── claudelint           # CLI entry point
├── Dockerfile           # Container image
└── pyproject.toml       # Package metadata
```

## Contributing

Contributions welcome! Please:

1. Fork the repository
2. Create a feature branch
3. Add tests for new functionality
4. Ensure all tests pass
5. Submit a pull request

## License

Apache 2.0 - See [LICENSE](LICENSE) for details.

## See Also

- [Claude Code Documentation](https://docs.claude.com/en/docs/claude-code)
- [Claude Code Plugins Reference](https://docs.claude.com/en/docs/claude-code/plugins-reference)
- [AI Helpers Marketplace](https://github.com/openshift-eng/ai-helpers) - Example repository using claudelint

## Support

- **Issues**: https://github.com/stbenjam/claudelint/issues
- **Discussions**: https://github.com/stbenjam/claudelint/discussions


            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "claudelint",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": null,
    "keywords": "claude, claude-code, linter, plugin, validation",
    "author": null,
    "author_email": "OpenShift Engineering <openshift-eng@redhat.com>",
    "download_url": "https://files.pythonhosted.org/packages/83/b1/73b4ded3f12f030d6bb5c68e3bb1f4cc5140af5b76b50be55f8da4f25a3a/claudelint-0.3.2.tar.gz",
    "platform": null,
    "description": "# claudelint\n\nA configurable, rule-based linter for [Claude Code](https://docs.claude.com/en/docs/claude-code) [plugins](https://docs.claude.com/en/docs/claude-code/plugins) and [plugin marketplaces](https://docs.claude.com/en/docs/claude-code/plugin-marketplaces).\n\n## Features\n\n\u2728 **Context-Aware** - Automatically detects single plugin vs marketplace repositories  \n\ud83c\udfaf **Rule-Based** - Enable/disable individual rules with configurable severity levels  \n\ud83d\udd0c **Extensible** - Load custom rules from Python files  \n\ud83d\udccb **Comprehensive** - Validates plugin structure, metadata, command format, and more  \n\ud83d\udc33 **Containerized** - Run via Docker for consistent, isolated linting  \n\u26a1 **Fast** - Efficient validation with clear, actionable output\n\n## Installation\n\n### Via uvx (easiest - no install required)\n\n```bash\n# From git (works before PyPI release)\nuvx --from 'git+https://github.com/stbenjam/claudelint' claudelint\n\n# Once published to PyPI, simply:\nuvx claudelint\n\n# With specific path\nuvx --from 'git+https://github.com/stbenjam/claudelint' claudelint /path/to/plugin\n```\n\n### Via pip (recommended for regular use)\n\n```bash\npip install claudelint\n```\n\n### From source\n\n```bash\ngit clone https://github.com/stbenjam/claudelint.git\ncd claudelint\npip install -e .\n```\n\n### Using Docker\n\n```bash\ndocker pull ghcr.io/stbenjam/claudelint:latest\n\n# Run on current directory\ndocker run -v $(pwd):/workspace ghcr.io/stbenjam/claudelint\n```\n\n## Quick Start\n\n```bash\n# Lint current directory\nclaudelint\n\n# Lint specific directory\nclaudelint /path/to/plugin\n\n# Verbose output\nclaudelint -v\n\n# Strict mode (warnings as errors)\nclaudelint --strict\n\n# Generate default config\nclaudelint --init\n\n# List all available rules\nclaudelint --list-rules\n```\n\n## Repository Types\n\nclaudelint automatically detects your repository structure:\n\n### Single Plugin\n```\nmy-plugin/\n\u251c\u2500\u2500 .claude-plugin/\n\u2502   \u2514\u2500\u2500 plugin.json\n\u251c\u2500\u2500 commands/\n\u2502   \u2514\u2500\u2500 my-command.md\n\u2514\u2500\u2500 README.md\n```\n\n### Marketplace (Multiple Plugins)\n\nclaudelint supports multiple marketplace structures per the [Claude Code specification](https://docs.claude.com/en/docs/claude-code/plugin-marketplaces):\n\n#### Traditional Structure (plugins/ directory)\n```\nmarketplace/\n\u251c\u2500\u2500 .claude-plugin/\n\u2502   \u2514\u2500\u2500 marketplace.json\n\u2514\u2500\u2500 plugins/\n    \u251c\u2500\u2500 plugin-one/\n    \u2502   \u251c\u2500\u2500 .claude-plugin/\n    \u2502   \u2514\u2500\u2500 commands/\n    \u2514\u2500\u2500 plugin-two/\n        \u251c\u2500\u2500 .claude-plugin/\n        \u2514\u2500\u2500 commands/\n```\n\n#### Flat Structure (root-level plugin)\n```\nmarketplace/\n\u251c\u2500\u2500 .claude-plugin/\n\u2502   \u2514\u2500\u2500 marketplace.json    # source: \"./\"\n\u251c\u2500\u2500 commands/                # Plugin components at root\n\u2502   \u2514\u2500\u2500 my-command.md\n\u2514\u2500\u2500 skills/\n    \u2514\u2500\u2500 my-skill/\n```\n\n#### Custom Paths\n```\nmarketplace/\n\u251c\u2500\u2500 .claude-plugin/\n\u2502   \u2514\u2500\u2500 marketplace.json    # source: \"./custom/my-plugin\"\n\u2514\u2500\u2500 custom/\n    \u2514\u2500\u2500 my-plugin/\n        \u251c\u2500\u2500 commands/\n        \u2514\u2500\u2500 skills/\n```\n\n#### Mixed Structures\nPlugins from `plugins/`, custom paths, and remote sources can coexist in one marketplace. Only local sources are validated.\n\n## Marketplace Features\n\n### Flexible Plugin Sources\n\nclaudelint understands all [plugin source types](https://docs.claude.com/en/docs/claude-code/plugin-marketplaces#plugin-sources) and validates any sources that resolve to local paths:\n\n- **Relative paths**: `\"source\": \"./\"` (flat structure), `\"source\": \"./custom/path\"`\n- **GitHub repositories**: `\"source\": {\"source\": \"github\", \"repo\": \"owner/repo\"}`\n- **Git URLs**: `\"source\": {\"source\": \"url\", \"url\": \"https://...\"}`\n\nRemote sources (GitHub, git URLs) are logged and skipped during local validation. They are valid per spec but cannot be checked until the plugin is fetched locally.\n\n### Strict Mode\n\nThe `strict` field in marketplace entries controls validation behavior:\n\n```json5\n{\n  \"name\": \"my-plugin\",\n  \"source\": \"./\",\n  \"strict\": false,    // plugin.json becomes optional\n  \"description\": \"Plugin description can be in marketplace.json\"\n}\n```\n\nWhen `strict: false`:\n- `plugin.json` is optional\n- Marketplace entry serves as the complete plugin manifest\n- Plugin metadata is validated from marketplace.json\n- Skills, commands, and other components work normally\n\nWhen `strict: true` (default):\n- `plugin.json` is required\n- Marketplace entry supplements plugin.json metadata\n\n## Configuration\n\nCreate `.claudelint.yaml` in your repository root:\n\n```yaml\n# Enable/disable rules\nrules:\n  plugin-json-required:\n    enabled: true\n    severity: error\n  \n  plugin-naming:\n    enabled: true\n    severity: warning\n  \n  command-sections:\n    enabled: true\n    severity: warning\n  \n  # 'auto' enables only for marketplace repos\n  marketplace-registration:\n    enabled: auto\n    severity: error\n\n# Load custom rules\ncustom-rules:\n  - ./my-custom-rules.py\n\n# Exclude patterns\nexclude:\n  - \"**/node_modules/**\"\n  - \"**/.git/**\"\n\n# Treat warnings as errors\nstrict: false\n```\n\n### Generating Default Config\n\n```bash\nclaudelint --init\n```\n\nThis creates `.claudelint.yaml` with all builtin rules enabled.\n\n## Builtin Rules\n\n### Plugin Structure\n\n| Rule ID | Description | Default Severity | Notes |\n|---------|-------------|------------------|-------|\n| `plugin-json-required` | Plugin must have `.claude-plugin/plugin.json` | error | Skipped when `strict: false` in marketplace |\n| `plugin-json-valid` | Plugin.json must be valid with required fields | error | |\n| `plugin-naming` | Plugin names should use kebab-case | warning | |\n| `commands-dir-required` | Plugin should have a commands directory | warning (disabled by default) | |\n| `commands-exist` | Plugin should have at least one command file | info (disabled by default) | |\n| `plugin-readme` | Plugin should have a README.md file | warning | |\n\n### Command Format\n\n| Rule ID | Description | Default Severity |\n|---------|-------------|------------------|\n| `command-naming` | Command files should use kebab-case | warning |\n| `command-frontmatter` | Command files must have valid frontmatter | error |\n| `command-sections` | Commands should have Name, Synopsis, Description, Implementation sections | warning |\n| `command-name-format` | Command Name section should be `plugin:command` format | warning |\n\n### Marketplace\n\n| Rule ID | Description | Default Severity | Notes |\n|---------|-------------|------------------|-------|\n| `marketplace-json-valid` | Marketplace.json must be valid JSON | error (auto) | |\n| `marketplace-registration` | Plugins must be registered in marketplace.json | error (auto) | Supports flat structures, custom paths, and remote sources |\n\n### Skills\n\n| Rule ID | Description | Default Severity |\n|---------|-------------|------------------|\n| `skill-frontmatter` | SKILL.md files should have frontmatter | warning |\n\n### Agents\n\n| Rule ID | Description | Default Severity |\n|---------|-------------|------------------|\n| `agent-frontmatter` | Agent files must have valid frontmatter with description and capabilities | error |\n\n### Hooks\n\n| Rule ID | Description | Default Severity |\n|---------|-------------|------------------|\n| `hooks-json-valid` | hooks.json must be valid JSON with proper hook configuration structure | error |\n\n### MCP (Model Context Protocol)\n\n| Rule ID | Description | Default Severity | Notes |\n|---------|-------------|------------------|-------|\n| `mcp-valid-json` | MCP configuration must be valid JSON with proper mcpServers structure | error | Validates both `.mcp.json` and `mcpServers` in `plugin.json` |\n| `mcp-prohibited` | Plugins should not enable MCP servers | error (disabled by default) | Security/policy rule - enable to prohibit MCP usage |\n\n## Custom Rules\n\nCreate custom validation rules by extending the `Rule` base class:\n\n```python\n# my_custom_rules.py\nfrom pathlib import Path\nfrom typing import List\nfrom claudelint import Rule, RuleViolation, Severity, RepositoryContext\n\nclass NoTodoCommentsRule(Rule):\n    @property\n    def rule_id(self) -> str:\n        return \"no-todo-comments\"\n    \n    @property\n    def description(self) -> str:\n        return \"Command files should not contain TODO comments\"\n    \n    def default_severity(self) -> Severity:\n        return Severity.WARNING\n    \n    def check(self, context: RepositoryContext) -> List[RuleViolation]:\n        violations = []\n        \n        for plugin_path in context.plugins:\n            commands_dir = plugin_path / \"commands\"\n            if not commands_dir.exists():\n                continue\n            \n            for cmd_file in commands_dir.glob(\"*.md\"):\n                with open(cmd_file, 'r') as f:\n                    content = f.read()\n                    if 'TODO' in content:\n                        violations.append(\n                            self.violation(\n                                \"Found TODO comment in command file\",\n                                file_path=cmd_file\n                            )\n                        )\n        \n        return violations\n```\n\nThen reference it in `.claudelint.yaml`:\n\n```yaml\ncustom-rules:\n  - ./my_custom_rules.py\n\nrules:\n  no-todo-comments:\n    enabled: true\n    severity: warning\n```\n\n## CI/CD Integration\n\n### GitHub Actions\n\n```yaml\nname: Lint Claude Plugins\n\non: [pull_request, push]\n\njobs:\n  lint:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      \n      - name: Set up Python\n        uses: actions/setup-python@v5\n        with:\n          python-version: '3.x'\n      \n      - name: Install claudelint\n        run: pip install claudelint\n      \n      - name: Run linter\n        run: claudelint --strict\n```\n\n### GitLab CI\n\n```yaml\nlint-plugins:\n  image: python:3.11\n  script:\n    - pip install claudelint\n    - claudelint --strict\n```\n\n### Docker\n\n```bash\ndocker run -v $(pwd):/workspace -w /workspace ghcr.io/stbenjam/claudelint --strict\n```\n\n## Exit Codes\n\n- `0` - Success (no errors, or warnings only in non-strict mode)\n- `1` - Failure (errors found, or warnings in strict mode)\n\n## Examples\n\n### Example Output\n\n```\nLinting Claude plugins in: /path/to/marketplace\n\nErrors:\n  \u2717 ERROR [plugins/git/.claude-plugin/plugin.json]: Missing plugin.json\n  \u2717 ERROR [.claude-plugin/marketplace.json]: Plugin 'new-plugin' not registered\n\nWarnings:\n  \u26a0 WARNING [plugins/utils]: Missing README.md (recommended)\n  \u26a0 WARNING [plugins/jira/commands/solve.md]: Missing recommended section '## Implementation'\n\nSummary:\n  Errors:   2\n  Warnings: 2\n```\n\n### Disabling Specific Rules\n\n```yaml\nrules:\n  plugin-readme:\n    enabled: false  # Don't require README files\n  \n  command-sections:\n    enabled: false  # Don't check for specific sections\n```\n\n### Changing Severity\n\n```yaml\nrules:\n  plugin-naming:\n    severity: error  # Make naming violations errors instead of warnings\n  \n  command-name-format:\n    severity: info   # Downgrade to info level\n```\n\n## Development\n\n### Running Tests\n\n```bash\npytest tests/\n```\n\n### Building Docker Image\n\n```bash\ndocker build -t claudelint .\n```\n\n### Project Structure\n\n```\nclaudelint/\n\u251c\u2500\u2500 src/\n\u2502   \u251c\u2500\u2500 rule.py          # Base Rule class\n\u2502   \u251c\u2500\u2500 context.py       # Repository detection\n\u2502   \u251c\u2500\u2500 config.py        # Configuration management\n\u2502   \u2514\u2500\u2500 linter.py        # Main linter orchestration\n\u251c\u2500\u2500 rules/\n\u2502   \u2514\u2500\u2500 builtin/         # Builtin validation rules\n\u251c\u2500\u2500 tests/               # Test suite\n\u251c\u2500\u2500 examples/            # Example configs and custom rules\n\u251c\u2500\u2500 claudelint           # CLI entry point\n\u251c\u2500\u2500 Dockerfile           # Container image\n\u2514\u2500\u2500 pyproject.toml       # Package metadata\n```\n\n## Contributing\n\nContributions welcome! Please:\n\n1. Fork the repository\n2. Create a feature branch\n3. Add tests for new functionality\n4. Ensure all tests pass\n5. Submit a pull request\n\n## License\n\nApache 2.0 - See [LICENSE](LICENSE) for details.\n\n## See Also\n\n- [Claude Code Documentation](https://docs.claude.com/en/docs/claude-code)\n- [Claude Code Plugins Reference](https://docs.claude.com/en/docs/claude-code/plugins-reference)\n- [AI Helpers Marketplace](https://github.com/openshift-eng/ai-helpers) - Example repository using claudelint\n\n## Support\n\n- **Issues**: https://github.com/stbenjam/claudelint/issues\n- **Discussions**: https://github.com/stbenjam/claudelint/discussions\n\n",
    "bugtrack_url": null,
    "license": "Apache-2.0",
    "summary": "A configurable, rule-based linter for Claude Code plugins",
    "version": "0.3.2",
    "project_urls": {
        "Documentation": "https://github.com/stbenjam/claudelint#readme",
        "Homepage": "https://github.com/stbenjam/claudelint",
        "Issues": "https://github.com/stbenjam/claudelint/issues",
        "Repository": "https://github.com/stbenjam/claudelint"
    },
    "split_keywords": [
        "claude",
        " claude-code",
        " linter",
        " plugin",
        " validation"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "a2de77f7915372b1caaea2a20c26c0bee898938707c66b4c11ba52aa5d49df3c",
                "md5": "bf32e0e9df49db2376314ce23644df0a",
                "sha256": "5e78bb9f2806a687106608d54df9b11d1b4728908fe48ddfa213330aedfc4011"
            },
            "downloads": -1,
            "filename": "claudelint-0.3.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "bf32e0e9df49db2376314ce23644df0a",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 29350,
            "upload_time": "2025-11-03T19:50:33",
            "upload_time_iso_8601": "2025-11-03T19:50:33.403075Z",
            "url": "https://files.pythonhosted.org/packages/a2/de/77f7915372b1caaea2a20c26c0bee898938707c66b4c11ba52aa5d49df3c/claudelint-0.3.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "83b173b4ded3f12f030d6bb5c68e3bb1f4cc5140af5b76b50be55f8da4f25a3a",
                "md5": "323bea72e892f6a422a4442c526e9758",
                "sha256": "33126a9667b6562ad8eef9edf2fc8df598dc591ab729f2e16fd3c2932881ba20"
            },
            "downloads": -1,
            "filename": "claudelint-0.3.2.tar.gz",
            "has_sig": false,
            "md5_digest": "323bea72e892f6a422a4442c526e9758",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 34356,
            "upload_time": "2025-11-03T19:50:34",
            "upload_time_iso_8601": "2025-11-03T19:50:34.879930Z",
            "url": "https://files.pythonhosted.org/packages/83/b1/73b4ded3f12f030d6bb5c68e3bb1f4cc5140af5b76b50be55f8da4f25a3a/claudelint-0.3.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-11-03 19:50:34",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "stbenjam",
    "github_project": "claudelint#readme",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [
        {
            "name": "PyYAML",
            "specs": [
                [
                    ">=",
                    "6.0"
                ]
            ]
        }
    ],
    "lcname": "claudelint"
}
        
Elapsed time: 1.35573s