Handling Plugin Conflicts When Multiple Skills Are Installed in i-have-adhd
To prevent plugin conflicts in i-have-adhd, ensure unique skill names in SKILL.md front-matter, isolate hooks to distinct config files, preserve the disable-model-invocation: true flag, and sync agent-specific copies using the provided CI workflows.
The i-have-adhd repository implements a skill-based plugin architecture designed for LLM agents including Claude Code, Codex, Gemini, Cursor, and OpenCode. Understanding how this system handles plugin conflicts when multiple skills are installed helps you maintain clean, predictable behavior across your development environment.
How the Plugin Architecture Works
The repository uses three layered components to deliver functionality:
| Component | Role | Key File |
|---|---|---|
| Plugin descriptor | Declares the plugin to the agent harness, making it discoverable with a unique name | plugin.json |
| Skill definition | Markdown file with front-matter describing the skill name, description, and invocation behavior | skills/i-have-adhd/SKILL.md |
| Hooks | Optional shell scripts that run automatically when the skill loads | hooks/always-on.sh |
The SKILL.md file contains a critical flag: disable-model-invocation: true. This prevents automatic activation, ensuring the skill remains dormant until you explicitly invoke it with /i-have-adhd.
Common Conflict Scenarios
1. Duplicate Skill Names
When two plugins define skills with identical name values in their front-matter, the agent harness may silently load only the first discovered skill or raise a validation error. This produces unpredictable behavior where expected functionality simply disappears.
2. Overlapping Hooks
The always-on.sh hook writes to ~/.claude/.i-have-adhd-always to enable persistent skill injection. If another plugin writes to this same file, the conflict creates a race condition where the "baseline" condition contains the wrong rule set—a scenario documented in evals/README.md.
3. Unwanted Model Invocation
A skill that removes disable-model-invocation: true from its front-matter activates automatically. Combined with another similarly configured skill, this causes both to run simultaneously, producing mixed and confusing output styles.
4. Version Drift in Copied Directories
Cursor and OpenCode copy skills into hidden directories (.cursor/skills/…). When these copies diverge from the canonical source in skills/…, agents exhibit inconsistent behavior based on which copy they load.
Conflict Resolution Strategy
Follow these steps to eliminate and prevent plugin conflicts when multiple skills are installed:
Ensure Unique Skill Names
Edit the name: field in any SKILL.md front-matter to guarantee uniqueness:
---
name: my-custom-skill
description: 'Personal productivity assistant'
disable-model-invocation: true
---
The agent harness uses this name as a unique identifier; deterministic loading requires no collisions.
Isolate Hooks to Separate Config Files
When adding hooks, use distinct script names and avoid targeting files already touched by other plugins. The always-on.sh in this repository specifically handles ~/.claude/.i-have-adhd-always—do not overlap with this mechanism.
Preserve the disable-model-invocation Flag
Keep disable-model-invocation: true in every skill you maintain. This guarantees explicit user control over which skill activates, preventing automatic style collisions:
---
name: i-have-adhd
description: 'ADHD-friendly development patterns'
disable-model-invocation: true # Critical: prevents auto-activation
---
Sync Agent-Specific Copies Manually
After modifying the canonical skill, propagate changes to Cursor's copy:
# Copy updated skill definition
cp skills/i-have-adhd/SKILL.md .cursor/skills/i-have-adhd/
# Verify synchronization
cmp skills/i-have-adhd/SKILL.md .cursor/skills/i-have-adhd/SKILL.md || {
echo "Sync error – files differ"
exit 1
}
Automate Verification with CI
The repository provides two workflows that catch conflicts automatically:
.github/workflows/plugin-load-check.yml validates clean plugin loading:
- name: Install the plugin from this checkout
run: |
# ... installation steps ...
grep -q "✔ enabled" plugin-list.txt || {
echo "::error::plugin failed to load; duplicate hook detected"
exit 1
}
.github/workflows/cursor-skill-sync.yml ensures copies stay aligned:
- name: Verify Cursor skill sync
run: |
cmp skills/i-have-adhd/SKILL.md .cursor/skills/i-have-adhd/SKILL.md
Push changes and monitor these jobs—they fail fast on duplicate hooks or version drift.
Installing Skills Safely
To add the i-have-adhd skill without triggering conflicts:
# Register the plugin with the agent
claude plugin marketplace add https://github.com/ayghri/i-have-adhd.git
claude plugin install i-have-adhd@i-have-adhd
# Skill remains inactive until explicit invocation due to
# disable-model-invocation: true in SKILL.md
/i-have-adhd # Manual activation only
Key Files for Conflict Prevention
| File | Purpose |
|---|---|
plugin.json |
Registers plugin with unique identifier |
skills/i-have-adhd/SKILL.md |
Defines skill behavior and invocation flags |
hooks/always-on.sh |
Auto-injection hook requiring careful management |
.github/workflows/plugin-load-check.yml |
CI validation for clean plugin loading |
.github/workflows/cursor-skill-sync.yml |
Automated sync verification |
evals/README.md |
Documents hook leakage scenarios |
Summary
- Unique naming in
SKILL.mdfront-matter prevents identifier collisions - Hook isolation eliminates race conditions on shared config files
disable-model-invocation: trueguarantees explicit skill activation only- Copy synchronization via CI workflows maintains consistency across agents
- Automated validation catches conflicts before they reach production environments
Frequently Asked Questions
What happens if two skills have the same name?
The agent harness loads the first discovered skill and may silently ignore the duplicate, or fail validation entirely. Either outcome causes unpredictable behavior where expected functionality does not execute. Always verify unique name values across your installed skills.
Can I disable the always-on hook to prevent conflicts?
Yes. The always-on.sh hook is optional—removing it eliminates automatic injection into ~/.claude/.i-have-adhd-always. Without this hook, the skill only activates through explicit /i-have-adhd commands, completely avoiding hook-related conflicts.
Why does Cursor need a separate copy of the skill?
Cursor's architecture requires skill definitions within .cursor/skills/… for its internal plugin loader. The cursor-skill-sync.yml workflow ensures this copy matches the canonical source, preventing version drift where Cursor behaves differently than other agents.
How do I detect conflicts before they affect my workflow?
Push changes to trigger the CI workflows. plugin-load-check.yml fails on duplicate hook declarations or loading errors, while cursor-skill-sync.yml errors when copies diverge. These automated checks catch conflicts during development, before deployment.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →