-
Notifications
You must be signed in to change notification settings - Fork 5.1k
Closed
Description
Problem
When the same plugin exists in both opencode.json configuration and the .opencode/plugin/ directory, both instances are loaded and executed, causing duplicate behavior and potential conflicts.
Example Scenario
A user has:
[email protected]specified in theiropencode.jsonoh-my-opencode.jsin their local.opencode/plugin/directory (perhaps a development version)
Current behavior: Both plugins are loaded and executed, leading to:
- Duplicate side effects
- Potential version conflicts
- Confusing behavior when testing local modifications
- Resource waste from running the same plugin twice
Expected behavior: Only the highest priority plugin should be loaded, with a clear priority hierarchy.
Proposed Solution
Implement plugin deduplication by canonical name with priority-based resolution:
1. Plugin Name Extraction (getPluginName)
Extract a canonical name from various plugin specifier formats:
- file:// URLs: Extract filename without extension
file:///path/to/plugin/foo.js→foo
- npm packages: Extract package name without version
[email protected]→oh-my-opencode
- Scoped packages: Preserve scope, remove version
@scope/[email protected]→@scope/pkg
2. Priority-Based Deduplication (deduplicatePlugins)
When multiple plugins with the same canonical name are found, use this priority order (highest to lowest):
| Priority | Source | Rationale |
|---|---|---|
| 1 (Highest) | Local plugin/ directory |
Development/override takes precedence |
| 2 | Local opencode.json |
Project-specific config |
| 3 | Global plugin/ directory |
User-wide overrides |
| 4 (Lowest) | Global opencode.json |
User-wide defaults |
3. Implementation Approach
Since plugins are collected in low-to-high priority order:
- Reverse the plugin list
- Deduplicate by canonical name (keeping first occurrence = highest priority)
- Restore original order
Use Cases
Use Case 1: Local Development Override
Global opencode.json: "[email protected]"
Local plugin/: "oh-my-opencode.js" (modified version)
→ Only local plugin/oh-my-opencode.js is loaded
Use Case 2: Project-Specific Version
Global opencode.json: "@company/[email protected]"
Local opencode.json: "@company/[email protected]"
→ Only @company/[email protected] from local config is loaded
Use Case 3: No Duplicates
Local opencode.json: "plugin-a", "plugin-b"
→ Both loaded normally (no deduplication needed)
Acceptance Criteria
-
getPluginNamecorrectly extracts canonical names from:- file:// URLs (with .js and .ts extensions)
- npm packages with versions
- Scoped packages with versions
- Plain package names without versions
-
deduplicatePluginscorrectly:- Removes duplicates by canonical name
- Preserves highest priority plugin
- Maintains relative order of unique plugins
- Integration test confirms local plugin overrides global config
- No breaking changes for users without duplicate plugins
Additional Context
- This is a configuration enhancement in
packages/opencode/src/config/config.ts - The fix should be transparent to users who don't have duplicate plugins
- Users with intentional duplicates (e.g., different scoped packages with same base name but different functionality) should not be affected since the canonical name includes the scope
Metadata
Metadata
Assignees
Labels
No labels