Add multi-provider-plugins skill for cross-provider architecture#10
Add multi-provider-plugins skill for cross-provider architecture#10
Conversation
* New skill: skills/multi-provider-plugins/SKILL.md * Reference docs for architecture, adapters, tool mapping, bootstrap, shared library * Patterns based on obra/superpowers implementation * Supports Claude Code, OpenAI Codex, and OpenCode * Version bump to 0.4.0 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
📝 WalkthroughWalkthroughAdds a new multi-provider-plugins skill and extensive reference docs (architecture, adapters, tool mapping, bootstrap patterns, shared skills library); bumps plugin version to 0.4.0 and updates plugin metadata (description, keywords, marketplace entries). Changes
Sequence Diagram(s)mermaid Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In `@skills/multi-provider-plugins/references/provider-adapters.md`:
- Around line 174-220: The dynamic top-level import that loads findSkillsInDir
and extractFrontmatter from the module (the await import(join(PLUGIN_ROOT,
'lib', 'skills-core.js')) call) can throw and is unhandled; wrap that import in
a try/catch, log the caught error via console.error with context (e.g., "Failed
to load skills-core module:" plus error), and exit with a non-zero status
(process.exit(1)) so the CLI doesn't leave an unhandled rejection; ensure the
rest of the script only runs after a successful import and keep references to
findSkillsInDir and extractFrontmatter intact.
- Around line 39-56: The script reads SKILL_FILE and sets CONTENT using jq but
doesn’t check for jq; modify session-start.sh to detect jq (e.g., test command
-v jq) before using it, and if jq is absent either print a clear error and exit
non-zero or fall back to an alternative JSON-escaping method (e.g., use
python3/json) to produce CONTENT; ensure the check happens before CONTENT is
assigned and that any exit or fallback preserves the existing usage of CONTENT
when emitting the final JSON message.
In `@skills/multi-provider-plugins/references/shared-skills-library.md`:
- Around line 344-356: The checkForUpdates function uses CommonJS
require('child_process') inside an ES module file which causes a runtime
ReferenceError; replace the inline require by adding an ES module import for
execSync from 'child_process' alongside the other imports at the top of the file
and update checkForUpdates to call execSync directly (keep the existing
try/catch behavior and repoDir usage).
🧹 Nitpick comments (4)
skills/multi-provider-plugins/references/architecture-overview.md (1)
39-80: Consider adding language specifiers to fenced code blocks.The directory structure diagrams lack language specifiers, triggering markdown lint warnings. While these are tree diagrams rather than executable code, adding
textorplaintextwould improve consistency and satisfy linters.📝 Suggested fix
-``` +```text your-multi-provider-plugin/ ├── .claude-plugin/ # Claude Code native integrationApply similar changes to other unlabeled code blocks at lines 15 and 137.
skills/multi-provider-plugins/references/provider-adapters.md (1)
91-96: Add language specifiers to directory tree blocks.Directory structure blocks at lines 91 and 236 lack language specifiers. Consider adding
textfor consistency with markdown lint rules.Also applies to: 236-241
skills/multi-provider-plugins/references/bootstrap-patterns.md (1)
219-219: Unlabeled code block in Codex bootstrap example.Line 219 has an unlabeled code fence that appears to close a nested example. Consider adding a language specifier or restructuring to avoid lint warnings.
skills/multi-provider-plugins/SKILL.md (1)
34-57: Consider adding language specifiers to code blocks.The directory structure diagram lacks a language specifier. Adding
textwould satisfy markdown lint rules and improve consistency.
| ```bash | ||
| #!/bin/bash | ||
|
|
||
| # Read the meta-skill that teaches about the skills system | ||
| SKILL_FILE="${CLAUDE_PLUGIN_ROOT}/skills/using-your-plugin/SKILL.md" | ||
|
|
||
| if [ -f "$SKILL_FILE" ]; then | ||
| # Escape content for JSON | ||
| CONTENT=$(cat "$SKILL_FILE" | jq -Rs .) | ||
|
|
||
| # Output hook response | ||
| cat << EOF | ||
| { | ||
| "message": $CONTENT | ||
| } | ||
| EOF | ||
| fi | ||
| ``` |
There was a problem hiding this comment.
Shell script lacks error handling for missing jq.
The session-start.sh script uses jq for JSON escaping but doesn't check if jq is installed. This could cause silent failures on systems without jq.
🛡️ Suggested improvement
#!/bin/bash
+# Check for required dependencies
+if ! command -v jq &> /dev/null; then
+ echo '{"message": "Error: jq is required but not installed."}' >&2
+ exit 1
+fi
+
# Read the meta-skill that teaches about the skills system
SKILL_FILE="${CLAUDE_PLUGIN_ROOT}/skills/using-your-plugin/SKILL.md"📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ```bash | |
| #!/bin/bash | |
| # Read the meta-skill that teaches about the skills system | |
| SKILL_FILE="${CLAUDE_PLUGIN_ROOT}/skills/using-your-plugin/SKILL.md" | |
| if [ -f "$SKILL_FILE" ]; then | |
| # Escape content for JSON | |
| CONTENT=$(cat "$SKILL_FILE" | jq -Rs .) | |
| # Output hook response | |
| cat << EOF | |
| { | |
| "message": $CONTENT | |
| } | |
| EOF | |
| fi | |
| ``` | |
| #!/bin/bash | |
| # Check for required dependencies | |
| if ! command -v jq &> /dev/null; then | |
| echo '{"message": "Error: jq is required but not installed."}' >&2 | |
| exit 1 | |
| fi | |
| # Read the meta-skill that teaches about the skills system | |
| SKILL_FILE="${CLAUDE_PLUGIN_ROOT}/skills/using-your-plugin/SKILL.md" | |
| if [ -f "$SKILL_FILE" ]; then | |
| # Escape content for JSON | |
| CONTENT=$(cat "$SKILL_FILE" | jq -Rs .) | |
| # Output hook response | |
| cat << EOF | |
| { | |
| "message": $CONTENT | |
| } | |
| EOF | |
| fi |
🤖 Prompt for AI Agents
In `@skills/multi-provider-plugins/references/provider-adapters.md` around lines
39 - 56, The script reads SKILL_FILE and sets CONTENT using jq but doesn’t check
for jq; modify session-start.sh to detect jq (e.g., test command -v jq) before
using it, and if jq is absent either print a clear error and exit non-zero or
fall back to an alternative JSON-escaping method (e.g., use python3/json) to
produce CONTENT; ensure the check happens before CONTENT is assigned and that
any exit or fallback preserves the existing usage of CONTENT when emitting the
final JSON message.
There was a problem hiding this comment.
AI Assistant:
This is reference documentation showing an example pattern, not production code that will be executed. Adding dependency checks to example code increases noise and obscures the core pattern being demonstrated.
Real implementations should certainly include such checks, but the documentation's purpose is to show the essential structure clearly. Readers adapting this for production use would add appropriate error handling for their context.
There was a problem hiding this comment.
@gwpl, you're absolutely right. For reference documentation demonstrating architectural patterns, keeping examples clean and focused on the essential structure is more valuable than including defensive checks that would be implementation-specific.
I'll keep this in mind when reviewing example code in documentation files—the goal is clarity of the pattern, not production-readiness of every snippet.
✏️ Learnings added
Learnt from: gwpl
Repo: obra/superpowers-developing-for-claude-code PR: 10
File: skills/multi-provider-plugins/references/provider-adapters.md:39-56
Timestamp: 2026-02-05T13:52:47.848Z
Learning: When reviewing example code in reference documentation or architectural pattern guides, focus on clarity of the pattern being demonstrated rather than suggesting production-level error handling, dependency checks, or defensive programming. Example code should illustrate essential structure without noise that obscures the core concept.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
| ```javascript | ||
| #!/usr/bin/env node | ||
|
|
||
| import { readFileSync, existsSync } from 'fs'; | ||
| import { join, dirname } from 'path'; | ||
| import { fileURLToPath } from 'url'; | ||
|
|
||
| const __dirname = dirname(fileURLToPath(import.meta.url)); | ||
| const PLUGIN_ROOT = join(__dirname, '..'); | ||
|
|
||
| // Import shared skill discovery | ||
| const { findSkillsInDir, extractFrontmatter } = await import( | ||
| join(PLUGIN_ROOT, 'lib', 'skills-core.js') | ||
| ); | ||
|
|
||
| const command = process.argv[2]; | ||
| const arg = process.argv[3]; | ||
|
|
||
| switch (command) { | ||
| case 'find-skills': | ||
| const skills = findSkillsInDir(join(PLUGIN_ROOT, 'skills')); | ||
| console.log('Available skills:'); | ||
| skills.forEach(s => console.log(` - ${s.name}: ${s.description}`)); | ||
| break; | ||
|
|
||
| case 'use-skill': | ||
| if (!arg) { | ||
| console.error('Usage: your-plugin-codex use-skill <skill-name>'); | ||
| process.exit(1); | ||
| } | ||
| const skillPath = join(PLUGIN_ROOT, 'skills', arg, 'SKILL.md'); | ||
| if (!existsSync(skillPath)) { | ||
| console.error(`Skill not found: ${arg}`); | ||
| process.exit(1); | ||
| } | ||
| console.log(readFileSync(skillPath, 'utf8')); | ||
| break; | ||
|
|
||
| case 'bootstrap': | ||
| const bootstrapPath = join(__dirname, 'bootstrap.md'); | ||
| console.log(readFileSync(bootstrapPath, 'utf8')); | ||
| break; | ||
|
|
||
| default: | ||
| console.log('Commands: find-skills, use-skill <name>, bootstrap'); | ||
| } | ||
| ``` |
There was a problem hiding this comment.
CLI tool lacks error handling for import failure.
The dynamic import on lines 185-187 could fail if skills-core.js doesn't exist or has syntax errors, causing an unhandled rejection.
🛡️ Suggested improvement
-// Import shared skill discovery
-const { findSkillsInDir, extractFrontmatter } = await import(
- join(PLUGIN_ROOT, 'lib', 'skills-core.js')
-);
+// Import shared skill discovery
+let findSkillsInDir, extractFrontmatter;
+try {
+ ({ findSkillsInDir, extractFrontmatter } = await import(
+ join(PLUGIN_ROOT, 'lib', 'skills-core.js')
+ ));
+} catch (err) {
+ console.error('Failed to load skills-core.js:', err.message);
+ process.exit(1);
+}🧰 Tools
🪛 markdownlint-cli2 (0.20.0)
[warning] 197-197: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
[warning] 212-212: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 Prompt for AI Agents
In `@skills/multi-provider-plugins/references/provider-adapters.md` around lines
174 - 220, The dynamic top-level import that loads findSkillsInDir and
extractFrontmatter from the module (the await import(join(PLUGIN_ROOT, 'lib',
'skills-core.js')) call) can throw and is unhandled; wrap that import in a
try/catch, log the caught error via console.error with context (e.g., "Failed to
load skills-core module:" plus error), and exit with a non-zero status
(process.exit(1)) so the CLI doesn't leave an unhandled rejection; ensure the
rest of the script only runs after a successful import and keep references to
findSkillsInDir and extractFrontmatter intact.
There was a problem hiding this comment.
AI Assistant:
Same reasoning as the shell script comment - this is reference documentation showing how to structure a CLI tool, not production code. The purpose is to demonstrate the pattern clearly without boilerplate that would obscure the core concept.
Readers implementing this in production would naturally add appropriate error handling for their specific needs.
There was a problem hiding this comment.
@gwpl, understood! You're absolutely right that for reference documentation focused on demonstrating architecture patterns, keeping the examples concise and focused on the core concept is more valuable than showing every production concern. The essential pattern—how to structure the CLI, use dynamic imports, and implement the command dispatcher—comes through clearly without the error-handling boilerplate.
Readers can add appropriate error handling, logging, and other production-readiness features when they adapt these patterns to their specific needs. Thank you for the clarification!
Replace require('child_process') with ES module import to match
the rest of the file's import style.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
AI Assistant: Regarding the nitpick comments about adding These are ASCII art directory trees, not executable code. Adding language specifiers would be purely cosmetic to satisfy markdown linters. The blocks render correctly and serve their purpose without them. The effort to change multiple files for linter compliance doesn't seem justified when:
If the repository maintainer prefers linter compliance, happy to add them in a follow-up. |
Human: Basically I collaborated with Agent to take best practices from https://github.com/obra/superpowers into skills into this repo:
AI Assistant:
Summary
Adds new
multi-provider-pluginsskill documenting how to make Claude Code plugins compatible with other AI coding assistants.Changes
skills/multi-provider-plugins/SKILL.mdreferences/architecture-overview.md- Adapter pattern designreferences/provider-adapters.md- Claude Code, Codex, OpenCode adaptersreferences/tool-mapping.md- Tool equivalents across providersreferences/bootstrap-patterns.md- Session-start injectionreferences/shared-skills-library.md- Portable skill structurePatterns Documented
Based on obra/superpowers implementation:
/skills/used by all providers.codex/,.opencode/directoriesTest plan
/skill multi-provider-plugins(for Github WebUI issue linking: Closes #9 )
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Documentation