Skip to content

Duplicate plugins loaded when same plugin exists in multiple sources #7427

@devxoul

Description

@devxoul

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 their opencode.json
  • oh-my-opencode.js in 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.jsfoo
  • npm packages: Extract package name without version
  • Scoped packages: Preserve scope, remove version

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:

  1. Reverse the plugin list
  2. Deduplicate by canonical name (keeping first occurrence = highest priority)
  3. 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

  • getPluginName correctly extracts canonical names from:
    • file:// URLs (with .js and .ts extensions)
    • npm packages with versions
    • Scoped packages with versions
    • Plain package names without versions
  • deduplicatePlugins correctly:
    • 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
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions