Skip to content
Back to skills

2884 1 Filetype Enum Extension D6d7f8de

ASecurity

``` **Official Schema Sources** (architecture lines 1487-1493): - Hooks: <https://docs.anthropic.com/en/docs/claude-code/hooks.md> - Agents: <https://docs.anthropic.com/en/docs/claude-code/sub-agents.md> - MCP: <https://modelcontextprotocol.io/docs/server> - LSP: <https://docs.anthropic.com/en/docs/claude-code/plugins.md#lsp-servers> - Plugins: <https://docs.anthropic.com/en/docs/claude-code/plugins.md> **Token Counting** (plugin_validator.py lines 44-45): - Library: tiktoken 0.8.0+ - Encodin...

  • 9 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added October 11, 2026
documentationpythongoshelltestingsecurityperformancedocumentation

Works with

  • claude code
  • cli
  • mcp

Security analysis

A100/100

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 2884-1-filetype-enum-extension_d6d7f8de --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 2884 1 Filetype Enum Extension D6d7f8de?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 2884 1 Filetype Enum Extension D6d7f8de
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-2884-1-filetype-enum-extension-d6d7f8de/badge)](https://www.skillsdirectory.com/skills/tools-only-2884-1-filetype-enum-extension-d6d7f8de)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
---
task: "1"
title: "FileType Enum Extension"
status: not-started
agent: "@python-cli-architect"
priority: 1
complexity: s
---

## Context Manifest

_Generated by context-gathering agent on 2026-02-13_

### How This Currently Works: Plugin Validation Architecture

The plugin_validator.py (3045 lines) implements a protocol-based validation framework with 9 existing validators that check skills, agents, commands, and plugin structure. When a file is validated:

1. **File Type Detection** (lines 147-165): `FileType.detect_file_type()` classifies files into 5 types (SKILL, AGENT, COMMAND, PLUGIN, UNKNOWN) based on filename and path patterns
2. **Validator Selection** (lines 2896-2913): Hard-coded dispatch selects validators per file type - skills get 7 validators, agents get 4, commands get 4, plugins get 1
3. **Single-File Read** (optimization needed): Currently multiple validators may re-read same file - architecture spec requires reading once and passing content to all validators (lines 814-836 of architecture spec)
4. **Validation Execution**: Each validator implements the Validator protocol (lines 249-286) with `validate(path: Path) -> ValidationResult`, `can_fix() -> bool`, `fix(path: Path) -> list[str]`
5. **Result Aggregation** (lines 2865-2951): Collects ValidationResult objects from all validators
6. **Report Generation** (lines 2599-2858): Three reporter implementations (Console, CI, Summary) format and display results

**Data Models** (lines 168-242):

- `ValidationIssue` (frozen dataclass): field, severity, message, code, line, suggestion, docs_url
- `ValidationResult` (frozen dataclass): passed, errors, warnings, info
- `ComplexityMetrics` (frozen dataclass): total_tokens, frontmatter_tokens, body_tokens, encoding

**Token-Based Complexity** (lines 1939-2122): ComplexityValidator uses tiktoken library (cl100k_base encoding) to count tokens instead of lines. Thresholds: 4000 tokens warning (SK006), 10000 tokens error (SK007). Architecture at lines 44-45 defines these constants.

**Pydantic Schema Validation** (lines 1030-1236): Three frontmatter models:

- `SkillFrontmatter` (10 fields, all optional, normalizes CSV fields)
- `CommandFrontmatter` (7 fields, description required, normalizes CSV)
- `AgentFrontmatter` (9+ fields, name+description required, uses camelCase per official schema)

**Validation Flow per Validator:**

1. **FrontmatterValidator** (lines 1243-1600): Extracts YAML frontmatter, validates with Pydantic model, converts Pydantic errors to ValidationIssues, auto-fixes YAML arrays→CSV, multiline→single-line, removes name field from plugin skills (Claude Code bug workaround lines 1541-1560)
2. **NameFormatValidator** (lines 1603-1787): Checks name pattern `^[a-z0-9][a-z0-9-]*[a-z0-9]$|^[a-z0-9]$`, no auto-fix
3. **DescriptionValidator** (lines 1790-1936): Checks min 20 chars (SK004), requires trigger phrases (SK005) from REQUIRED_TRIGGER_PHRASES constant (lines 56-64), no auto-fix
4. **ComplexityValidator** (lines 1939-2122): Uses tiktoken to count tokens, splits frontmatter vs body, no auto-fix
5. **InternalLinkValidator** (lines 448-631): Regex extracts markdown links, checks file existence, ignores code blocks (lines 468-490), no auto-fix
6. **ProgressiveDisclosureValidator** (lines 334-441): Checks for references/, examples/, scripts/ directories, INFO severity only, no auto-fix
7. **NamespaceReferenceValidator** (lines 638-1023): Parses namespace-qualified references (Skill(), Task(), @agent, /command), resolves from settings.json, checks target file exists, no auto-fix
8. **PluginStructureValidator** (lines 2125-2414): Validates plugin.json schema, runs `claude plugin validate` CLI if available (lines 2421-2500), no auto-fix

**Known UX Bugs:**

- Lines 2681-2709: ConsoleReporter counts ValidationResult objects not unique files (shows "7 files" for 1 file with 7 validators)
- Lines 904-911: Dead code in NamespaceReferenceValidator after early return (need coverage verification before removal)
- Line 1802: DescriptionValidator fires SK005 on commands (commands don't need trigger phrases since explicitly invoked)

**Error Code Registry** (lines 71-109): 23 existing codes across 6 categories:

- FM001-FM010: Frontmatter errors (10 codes)
- SK001-SK007: Skill errors (7 codes)
- LK001-LK002: Link errors (2 codes)
- PD001-PD003: Progressive disclosure (3 codes)
- PL001-PL005: Plugin errors (5 codes)
- NR001-NR002: Namespace reference errors (2 codes)

### For New Feature Implementation: Hook/MCP/LSP Configuration Validation

**Architecture Requirements** (architect-plugin-linter.md):

Need to add 4 new FileType variants (lines 85-130 of architecture):

- `HOOK_CONFIG` - Detects `hooks.json` exact filename
- `MCP_CONFIG` - Detects `.mcp.json` exact filename
- `LSP_CONFIG` - Detects `.lsp.json` exact filename
- `HOOK_SCRIPT` - Detects `hooks/*.{js,py,sh}` directory pattern

**Detection Priority** (architecture lines 105-130):

1. Exact filename matches (hooks.json, .mcp.json, .lsp.json)
2. Special filenames (SKILL.md, plugin.json)
3. Directory-based (agents/, commands/, hooks/)
4. UNKNOWN fallback

**New Pydantic Models Required** (architecture lines 135-312):

**HookConfig Schema** (architecture lines 135-194, official source: <https://docs.anthropic.com/en/docs/claude-code/hooks.md>):

- 15 valid event types: SessionStart, UserPromptSubmit, PreToolUse, PermissionRequest, PostToolUse, PostToolUseFailure, Notification, SubagentStart, SubagentStop, Stop, TeammateIdle, TaskCompleted, PreCompact, SessionEnd, ToolUseFailure
- 3 hook types: COMMAND (shell execution), PROMPT (LLM injection), AGENT (sub-agent invocation)
- Discriminated union on type field - command/prompt/agent fields required based on type
- Matcher field contains regex pattern (must validate compilation without execution)
- Timeout field must be positive integer if present

**MCPConfig Schema** (architecture lines 196-222, official source: <https://modelcontextprotocol.io/docs/server>):

- Required: command (non-empty string)
- Optional: args (list of strings NOT single string), env (dict[str, str]), cwd (directory path)
- Validation: command existence check with shutil.which() as WARNING only (may not exist at validation time)

**LSPConfig Schema** (architecture lines 224-265, official source: <https://docs.anthropic.com/en/docs/claude-code/plugins.md#lsp-servers>):

- Required: command (non-empty string), extensionToLanguage (non-empty dict)
- Extension keys must start with dot (.py not py or *.py)
- Language values must be lowercase identifiers
- Transport: stdio or socket only
- Timeouts must be positive integers
- maxRestarts must be positive

**AgentFrontmatter Enum Enhancement** (architecture lines 267-312):

Existing AgentFrontmatter model (lines 1167-1235) needs 3 new enum validations:

- `model` field: Add AgentModel enum (sonnet, opus, haiku, inherit)
- `permissionMode` field: Add AgentPermissionMode enum (6 values including default, acceptEdits, dontAsk, etc.)
- `memory` field: Add AgentMemory enum (user, project, local)

**New Validators Required** (architecture lines 360-580):

**HookConfigValidator** (architecture lines 360-420):

- No auto-fix (JSON too complex)
- Validates 15 event types with fuzzy matching suggestions for unknown types
- Validates hook type discriminators
- Compiles regex patterns without execution (security)
- Error codes: HK001-HK010

**MCPConfigValidator** (architecture lines 422-473):

- No auto-fix
- Command existence check via shutil.which() produces WARNING not error
- Args must be list[str] not single string
- Env must be dict[str, str]
- Error codes: MC001-MC010

**LSPConfigValidator** (architecture lines 475-528):

- No auto-fix
- Strict extension format validation (.py not py)
- Lowercase language identifier enforcement
- Transport enum validation
- Error codes: LS001-LS010

**AgentEnumValidator** (architecture lines 530-580):

- No auto-fix (would guess user intent)
- Validates enum fields against official schema
- Provides suggestions for invalid enum values
- Only runs on FileType.AGENT files
- Error codes: AG001-AG010

**DescriptionValidator Modification** (architecture lines 582-629):

Current signature: `validate(self, path: Path, content: str) -> ValidationResult`
New signature: `validate(self, path: Path, content: str, file_type: FileType) -> ValidationResult`

Behavior change:

- Skip SK005 (trigger phrase check) when `file_type == FileType.COMMAND`
- Continue SK005 for SKILL and AGENT types
- Preserve SK004 (length check) for all types

**Validator Registration** (architecture lines 637-697):

Need to create VALIDATORS_BY_TYPE dispatch table:

```python
VALIDATORS_BY_TYPE: dict[FileType, list[type[Validator]]] = {
    FileType.SKILL: [FrontmatterValidator, NameFormatValidator, DescriptionValidator, ComplexityValidator, InternalLinkValidator, ProgressiveDisclosureValidator, NamespaceReferenceValidator],
    FileType.AGENT: [FrontmatterValidator, NameFormatValidator, DescriptionValidator, AgentEnumValidator, NamespaceReferenceValidator],
    FileType.COMMAND: [FrontmatterValidator, DescriptionValidator, NamespaceReferenceValidator],  # SK005 skipped
    FileType.HOOK_CONFIG: [HookConfigValidator],
    FileType.MCP_CONFIG: [MCPConfigValidator],
    FileType.LSP_CONFIG: [LSPConfigValidator],
    FileType.PLUGIN: [PluginStructureValidator],
}
```

**Error Code Registry Expansion** (architecture lines 700-763):

Need 40 new error code constants (lines 71-109 pattern):

- HK001-HK010: Hook configuration errors (10 codes)
- MC001-MC010: MCP configuration errors (10 codes)
- LS001-LS010: LSP configuration errors (10 codes)
- AG001-AG010: Agent enum errors (10 codes)

**Report Generation Fix** (architecture lines 836-893):

Change from counting validators to counting files:

- Current: `len(results)` counts ValidationResult objects
- Required: Count unique file paths `len(set(path for path, _ in results))`
- Message change: "X validators passed" → "X files validated"
- Group issues by file path, then by error code within file

**Dead Code Removal** (architecture lines 1149-1165):

Lines 904-911 in NamespaceReferenceValidator contain unreachable nested skill reference resolution after early return line 903. Verify with coverage before removal.

**Testing Strategy** (architecture lines 900-1027):

Minimum coverage: 80% overall, 90% for new validators
Test files needed:

- test_hook_config_validator.py - parametrize 15 event types, test all HK error codes
- test_mcp_config_validator.py - mock shutil.which(), test warning vs error severity
- test_lsp_config_validator.py - parametrize extension formats, test language identifier validation
- test_agent_enum_validator.py - parametrize valid enum combinations, test suggestion quality
- test_file_type_detection.py - test all 9 FileType values, edge cases (nested paths)
- test_report_generation.py - verify file counts not validator counts
- test_description_validator.py - add file_type parameter tests

**Performance Requirements** (architecture lines 1060-1097):

- Single file: <1 second
- Plugin with 10 components: <5 seconds
- Full repository scan: <30 seconds
- Optimization: Read each file once, pass content to all validators (no redundant I/O)

**Pre-Commit Integration** (architecture lines 1129-1143):

Current .pre-commit-config.yaml pattern (line 1136):

```yaml
files: '^plugins/.*(SKILL\.md|agents/.*\.md|commands/.*\.md|plugin\.json)$'
```

Required enhancement:

```yaml
files: '^plugins/.*(SKILL\.md|agents/.*\.md|commands/.*\.md|plugin\.json|hooks\.json|\.mcp\.json|\.lsp\.json)$'
```

### Technical Reference Details

#### Component Interfaces & Signatures

**FileType Enum Extension** (plugin_validator.py lines 138-166, architecture lines 85-130):

```python
class FileType(StrEnum):
    SKILL = "skill"
    AGENT = "agent"
    COMMAND = "command"
    PLUGIN = "plugin"
    HOOK_CONFIG = "hook_config"      # NEW
    MCP_CONFIG = "mcp_config"        # NEW
    LSP_CONFIG = "lsp_config"        # NEW
    HOOK_SCRIPT = "hook_script"      # NEW
    UNKNOWN = "unknown"

    @staticmethod
    def detect_file_type(path: Path) -> FileType:
        """Detect file type from path structure and filename.

        Detection priority order:
        1. Exact filename matches (hooks.json, .mcp.json, .lsp.json)
        2. Special filenames (SKILL.md, plugin.json)
        3. Directory-based (agents/, commands/, hooks/)
        4. UNKNOWN fallback
        """
```

**Validator Protocol** (plugin_validator.py lines 249-286, unchanged):

```python
class Validator(Protocol):
    def validate(self, path: Path, content: str) -> ValidationResult: ...
    def can_fix(self, issue: ValidationIssue) -> bool: ...
    def fix(self, path: Path, content: str) -> str: ...
```

**DescriptionValidator Signature Change** (architecture lines 596-629):

```python
class DescriptionValidator:
    def validate(
        self,
        path: Path,
        content: str,
        file_type: FileType  # NEW PARAMETER
    ) -> ValidationResult:
        """Validate description field with file-type awareness.

        Checks:
        - Minimum length (SK004) - ALL file types
        - Trigger phrases (SK005) - ONLY skills and agents, skip commands

        Args:
            path: Path to file
            content: File content
            file_type: FileType enum (determines SK005 behavior)

        Returns:
            ValidationResult with SK errors (SK005 skipped for commands)
        """
```

#### Data Structures

**HookConfig Pydantic Models** (architecture lines 135-194):

```python
from pydantic import BaseModel, Field

class HookType(StrEnum):
    COMMAND = "command"
    PROMPT = "prompt"
    AGENT = "agent"

class HookEventType(StrEnum):
    SESSION_START = "SessionStart"
    USER_PROMPT_SUBMIT = "UserPromptSubmit"
    PRE_TOOL_USE = "PreToolUse"
    PERMISSION_REQUEST = "PermissionRequest"
    POST_TOOL_USE = "PostToolUse"
    POST_TOOL_USE_FAILURE = "PostToolUseFailure"
    NOTIFICATION = "Notification"
    SUBAGENT_START = "SubagentStart"
    SUBAGENT_STOP = "SubagentStop"
    STOP = "Stop"
    TEAMMATE_IDLE = "TeammateIdle"
    TASK_COMPLETED = "TaskCompleted"
    PRE_COMPACT = "PreCompact"
    SESSION_END = "SessionEnd"

class HookDefinition(BaseModel):
    type: HookType
    command: str | None = None      # Required if type=command
    prompt: str | None = None       # Required if type=prompt
    agent: str | None = None        # Required if type=agent
    timeout: int | None = None
    model: str | None = None

class EventMatcher(BaseModel):
    matcher: str | None = None      # Optional regex pattern
    hooks: list[HookDefinition]

class HookConfig(BaseModel):
    hooks: dict[str, list[EventMatcher]]  # Event name → matchers
```

**MCPConfig Pydantic Models** (architecture lines 196-222):

```python
class MCPServer(BaseModel):
    command: str
    args: list[str] = Field(default_factory=list)
    env: dict[str, str] = Field(default_factory=dict)
    cwd: str | None = None

class MCPConfig(BaseModel):
    mcpServers: dict[str, MCPServer]
```

**LSPConfig Pydantic Models** (architecture lines 224-265):

```python
class LSPTransport(StrEnum):
    STDIO = "stdio"
    SOCKET = "socket"

class LSPServer(BaseModel):
    command: str
    extensionToLanguage: dict[str, str]
    args: list[str] = Field(default_factory=list)
    transport: LSPTransport = LSPTransport.STDIO
    env: dict[str, str] = Field(default_factory=dict)
    initializationOptions: dict[str, Any] = Field(default_factory=dict)
    settings: dict[str, Any] = Field(default_factory=dict)
    workspaceFolder: str | None = None
    startupTimeout: int | None = None
    shutdownTimeout: int | None = None
    restartOnCrash: bool = False
    maxRestarts: int | None = None

class LSPConfig(BaseModel):
    lspServers: dict[str, LSPServer]
```

**AgentFrontmatter Enum Models** (architecture lines 267-312):

```python
class AgentModel(StrEnum):
    SONNET = "sonnet"
    OPUS = "opus"
    HAIKU = "haiku"
    INHERIT = "inherit"

class AgentPermissionMode(StrEnum):
    DEFAULT = "default"
    ACCEPT_EDITS = "acceptEdits"
    DELEGATE = "delegate"
    DONT_ASK = "dontAsk"
    BYPASS_PERMISSIONS = "bypassPermissions"
    PLAN = "plan"

class AgentMemory(StrEnum):
    USER = "user"
    PROJECT = "project"
    LOCAL = "local"

class AgentFrontmatter(BaseModel):
    name: str  # Required
    description: str  # Required
    model: AgentModel | None = None  # Enhanced with enum
    permissionMode: AgentPermissionMode | None = None  # Enhanced with enum
    memory: AgentMemory | None = None  # NEW with enum
    # ... other existing fields (existing validators unchanged)
```

#### Configuration Requirements

**Official Schema Sources** (architecture lines 1487-1493):

- Hooks: <https://docs.anthropic.com/en/docs/claude-code/hooks.md>
- Agents: <https://docs.anthropic.com/en/docs/claude-code/sub-agents.md>
- MCP: <https://modelcontextprotocol.io/docs/server>
- LSP: <https://docs.anthropic.com/en/docs/claude-code/plugins.md#lsp-servers>
- Plugins: <https://docs.anthropic.com/en/docs/claude-code/plugins.md>

**Token Counting** (plugin_validator.py lines 44-45):

- Library: tiktoken 0.8.0+
- Encoding: cl100k_base
- Warning threshold: 4000 tokens
- Error threshold: 10000 tokens

**Dependencies** (plugin_validator.py lines 1-11):

```python
# /// script
# requires-python = ">=3.11"
# dependencies = [
#     "typer>=0.21.0",
#     "rich>=13.0.0",
#     "tiktoken>=0.8.0",
#     "pyyaml>=6.0",
#     "pydantic>=2.0.0",
# ]
# ///
```

#### File Locations

**Implementation Target**: `plugins/plugin-creator/scripts/plugin_validator.py`

**Key Line Regions**:

- Lines 71-109: Error code constants (add 40 new constants)
- Lines 138-166: FileType enum (add 4 new variants)
- Lines 147-165: detect_file_type() method (enhance detection logic)
- Lines 1030-1236: Pydantic models (add HookConfig, MCPConfig, LSPConfig, agent enums)
- Lines 1790-1936: DescriptionValidator (add file_type parameter)
- Lines 2896-2913: Validator registration (create VALIDATORS_BY_TYPE dispatch)
- Lines 2681-2709: ConsoleReporter.summarize() (fix file counting)
- Lines 904-911: Dead code removal (verify with coverage first)

**Test Files to Create**:

- `plugins/plugin-creator/tests/test_hook_config_validator.py`
- `plugins/plugin-creator/tests/test_mcp_config_validator.py`
- `plugins/plugin-creator/tests/test_lsp_config_validator.py`
- `plugins/plugin-creator/tests/test_agent_enum_validator.py`
- `plugins/plugin-creator/tests/test_file_type_detection.py`
- `plugins/plugin-creator/tests/test_report_generation.py`

**Test Files to Modify**:

- `plugins/plugin-creator/tests/test_description_validator.py` (add file_type parameter tests)

**Documentation to Update**:

- `plugins/plugin-creator/scripts/ERROR_CODES.md` (add 40 new error code entries)

**Pre-Commit Config**:

- `.pre-commit-config.yaml` (update file pattern around line 1136)

#### References

**Primary Sources** (Read Before Implementation):

1. **Task decomposition**: `./plan/tasks-1-plugin-linter.md` - Complete task breakdown with dependencies
2. **Architecture specification**: `./plan/architect-plugin-linter.md` - WHAT to build (interfaces, contracts, schemas)
3. **Feature context**: `./plan/feature-context-plugin-linter.md` - WHY this feature exists, gaps identified
4. **Codebase analysis**: `./plan/codebase/plugin-validator-architecture.md` - HOW current system works
5. **Main implementation**: `./plugins/plugin-creator/scripts/plugin_validator.py` - Complete 3045-line validator
6. **Existing tests**: `./plugins/plugin-creator/tests/` - Test patterns to follow (11 test files)
7. **Pre-commit config**: `./.pre-commit-config.yaml` - Hook integration patterns

**Official Documentation** (Cite in Model Docstrings):

- Hooks schema: <https://docs.anthropic.com/en/docs/claude-code/hooks.md>
- Agent schema: <https://docs.anthropic.com/en/docs/claude-code/sub-agents.md>
- MCP schema: <https://modelcontextprotocol.io/docs/server>
- LSP schema: <https://docs.anthropic.com/en/docs/claude-code/plugins.md#lsp-servers>

**Testing Standards** (architecture lines 1030-1051):

- Fixture type hints required: `Generator[YieldType, None, None]`
- Test function signatures: All parameters typed, `-> None` return type
- Mocking: pytest-mock only, NEVER unittest.mock
- AAA pattern: Arrange-Act-Assert with comments
- Property-based: Use hypothesis for validation functions, minimum 500 examples

**Verification Checklist Before Starting**:

- [ ] Read complete architecture specification (architect-plugin-linter.md)
- [ ] Read complete task decomposition (tasks-1-plugin-linter.md)
- [ ] Read current plugin_validator.py implementation (all 3045 lines)
- [ ] Read all official schema documentation URLs above
- [ ] Understand FileType detection priority order
- [ ] Understand Validator protocol contract
- [ ] Understand validation pipeline flow (detect → select → validate → aggregate → report)
- [ ] Understand token-based complexity measurement (tiktoken usage)
- [ ] Understand Pydantic field validator patterns from existing models
- [ ] Understand existing test file structure (conftest.py fixtures, test class patterns)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.