# ADR-001: Plugin Exclusion System\n\n**Date**: 2025-12-03\n**Status**: Accepted ✅\n**Decision**: Implement a centralized, configuration-driven plugin exclusion system\n\n---\n\n## Context\n\nThe nushell-plugins repository builds and distributes multiple plugins, including some that serve as reference implementations or documentation (e.g., `nu_plugin_example`). These reference plugins are valuable for developers and maintainers but should not be included in end-user distributions.\n\n### Problem Statement\n\n**Without exclusion system**:\n\n- Reference plugins ship with every distribution (increases download size)\n- Users install plugins they don't need\n- No clear mechanism to control distribution contents\n- Adding/removing exclusions requires manual changes in multiple scripts\n\n**Key Requirements**:\n\n1. Reference plugins must still be built (for testing and reference)\n2. Reference plugins must be excluded from distributions\n3. Exclusion list must be maintainable and centralized\n4. System must work without breaking existing workflows\n\n---\n\n## Decision\n\n**Implement a Configuration-Driven Plugin Exclusion System** with:\n\n1. **Central Registry** (`etc/plugin_registry.toml`) - single source of truth\n2. **Collection Filtering** (`collect_full_binaries.nu`) - filters during binary collection\n3. **Packaging Filtering** (`create_distribution_packages.nu`) - filters during package creation\n4. **Configuration Exclusion** (`default_config.nu`) - manual config-level filtering\n5. **No Build Changes** - all plugins still built, only excluded from distribution\n\n### Architecture\n\n```plaintext\n┌─────────────────────────────────┐\n│ plugin_registry.toml │\n│ ├─ [distribution] │\n│ │ └─ excluded_plugins: [...] │\n│ └─ (source of truth) │\n└────────────┬────────────────────┘\n │\n ┌───────┴────────┐\n ▼ ▼\nCollection Packaging\n(collect_full_ (create_distribution_\n binaries.nu) packages.nu)\n │ │\n ▼ ▼\ndistribution/ bin_archives/\n(without (without\n excluded) excluded)\n```\n\n---\n\n## Implementation Details\n\n### 1. Registry-Based Configuration\n\n**File**: `etc/plugin_registry.toml`\n\n```toml\n[distribution]\nexcluded_plugins = [\n "nu_plugin_example"\n]\nreason = "Reference/documentation plugin"\n```\n\n**Rationale**:\n\n- ✅ Single file, easy to maintain\n- ✅ Documented in code\n- ✅ Supports future expansion (profiles, conditions)\n- ✅ Can be version controlled\n\n### 2. Filtering Functions\n\nAdded helper functions in both scripts:\n\n- `get_excluded_plugins()` - reads registry, returns exclusion list\n- `get_excluded_plugins_dist()` - same function (different name for clarity)\n\n**Design**:\n\n```nu\ndef get_excluded_plugins []: nothing -> list<string> {\n try {\n let registry_path = "./etc/plugin_registry.toml"\n if not ($registry_path | path exists) {\n return [] # Graceful degradation\n }\n\n let registry_content = open $registry_path\n let excluded = try {\n $registry_content.distribution.excluded_plugins\n } catch {\n [] # Handle malformed registry\n }\n\n return $excluded\n } catch {\n return [] # Never block on registry errors\n }\n}\n```\n\n**Rationale**:\n\n- ✅ Centralized logic (DRY principle)\n- ✅ Graceful error handling (non-blocking)\n- ✅ Future-proof (supports registry changes)\n\n### 3. Collection System Updates\n\nUpdated two filtering points:\n\n- `get_workspace_plugins_info()` - filters built-in workspace plugins\n- `get_custom_plugins_info()` - filters custom plugins from plugin_* directories\n\n**Pattern**:\n\n```nu\nlet excluded = get_excluded_plugins\nlet available = $all_plugins | where { |p| $p