Skip to content

feat: auto-discover skills/commands from Claude Code, Codex, and Gemini configs#405

Open
kulvirgit wants to merge 1 commit intomainfrom
feat/auto-skill-discovery
Open

feat: auto-discover skills/commands from Claude Code, Codex, and Gemini configs#405
kulvirgit wants to merge 1 commit intomainfrom
feat/auto-skill-discovery

Conversation

@kulvirgit
Copy link
Collaborator

@kulvirgit kulvirgit commented Mar 23, 2026

Summary

  • Adds auto-discovery of skills and commands from external AI tool configs (Claude Code .claude/commands/*.md, Codex .codex/skills/**/SKILL.md, Gemini .gemini/skills/**/SKILL.md and .gemini/commands/*.toml)
  • Discovered skills are additive — existing skills always take precedence
  • Controlled by experimental.auto_skill_discovery config toggle (default: true)
  • Fixes skill-backed commands to expose $ARGUMENTS hints via hints(skill.content)

Test plan

  • bun turbo typecheck passes
  • 14 new tests in test/skill/discover-external.test.ts pass
  • Existing test/skill/skill.test.ts (13 tests) — no regressions
  • Existing test/tool/skill.test.ts (5 tests) — no regressions
  • Manual: create ~/.claude/commands/test-cmd.md → verify /test-cmd appears
  • Manual: create ~/.gemini/commands/deploy.toml → verify /deploy discovered
  • Manual: set experimental.auto_skill_discovery: false → verify no discovery

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Auto-discover skills from external AI tools (Claude Code, Codex, Gemini) at startup.
    • New experimental configuration option auto_skill_discovery to control this feature (enabled by default).
  • Bug Fixes

    • Skill-based commands now properly display hints derived from their prompt templates.
  • Tests

    • Added comprehensive test coverage for external skill discovery functionality.

…ni configs

Extends the MCP auto-discovery pattern to skills and commands. Discovers:
- Claude Code commands (.claude/commands/*.md)
- Codex CLI skills (.codex/skills/**/SKILL.md)
- Gemini CLI skills (.gemini/skills/**/SKILL.md)
- Gemini CLI commands (.gemini/commands/*.toml)

Discovered skills are additive — existing skills always take precedence.
Controlled by experimental.auto_skill_discovery config (default: true).
Also fixes skill-backed commands to expose $ARGUMENTS hints.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link

@claude claude bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review to trigger a review.

Tip: disable this comment in your organization's Code Review settings.

@coderabbitai
Copy link

coderabbitai bot commented Mar 23, 2026

📝 Walkthrough

Walkthrough

This change introduces auto-discovery of external AI tool skills from Claude Code, Codex, and Gemini configurations by adding discovery logic, configuration flags, and comprehensive test coverage. The feature scans well-known directories, parses multiple file formats (markdown with frontmatter, TOML), deduplicates by skill name, and conditionally integrates discovered skills into the loading pipeline.

Changes

Cohort / File(s) Summary
Configuration & Metadata
packages/opencode/src/config/config.ts, packages/opencode/src/command/index.ts
Added experimental.auto_skill_discovery boolean config field (defaulting true) and updated command metadata to derive hints from skill content instead of empty array.
External Skill Discovery
packages/opencode/src/skill/discover-external.ts
New module implementing auto-discovery of skills from Claude Code, Codex, and Gemini by scanning home/project directories, parsing markdown with frontmatter, TOML files, and applying deduplication logic. Exports discovery function and helpers to track results.
Skill Loading Integration
packages/opencode/src/skill/skill.ts
Integrated conditional auto-discovery into skill loading pipeline; when enabled and flag not set, calls external discovery, merges new skills into existing map, records added skill names and sources.
Test Coverage
packages/opencode/test/skill/discover-external.test.ts, packages/opencode/test/tool/skill.test.ts
Added comprehensive test suite validating discovery across multiple formats, deduplication, edge cases (malformed YAML, missing frontmatter), and placeholder conversion. Updated existing skill tests with experimental config flag.

Sequence Diagram

sequenceDiagram
    participant Instance
    participant Config
    participant SkillLoader as Skill Loader
    participant Discover as discover-external
    participant FileSystem as File System
    participant ParsedSkills as Skills Map

    SkillLoader->>Config: Check auto_skill_discovery enabled<br/>& flag not set
    Config-->>SkillLoader: true/false
    alt Discovery Enabled
        SkillLoader->>Discover: discoverExternalSkills(worktree)
        Discover->>FileSystem: Walk home & project dirs<br/>to find .claude, .codex, .gemini
        FileSystem-->>Discover: Directory listing
        Discover->>FileSystem: Glob-match files<br/>(*.md, *.toml patterns)
        FileSystem-->>Discover: File list
        Discover->>Discover: Parse markdown frontmatter<br/>or TOML format
        Discover->>Discover: Extract skill metadata<br/>(name, description, prompt)
        Discover->>Discover: Deduplicate by skill.name<br/>(first discovered wins)
        Discover-->>SkillLoader: { skills, sources }
        SkillLoader->>ParsedSkills: Merge new skills<br/>(skip if name exists)
        ParsedSkills-->>SkillLoader: Updated skills map
        SkillLoader->>Discover: setSkillDiscoveryResult(added, sources)
    else Discovery Disabled
        SkillLoader->>ParsedSkills: Load only builtin skills
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

contributor

Poem

🐰 Whiskers twitching with delight,
Skills discovered left and right!
From Claude to Codex, Gemini too,
Auto-loading all that's new!
Markdown, TOML, what a feast—
The clever rabbit's code, at least!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed Title accurately and clearly summarizes the main change—auto-discovering skills from external AI tool configs—without being vague or misleading.
Description check ✅ Passed Description covers Summary, Test Plan, and Checklist sections; mostly complete with automated test results confirmed and manual tests marked TODO but listed.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/auto-skill-discovery

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/opencode/src/config/config.ts (1)

1546-1547: ⚠️ Potential issue | 🟡 Minor

Remove orphaned statements at end of file.

These two standalone Filesystem.write expressions appear to be leftover artifacts from a refactoring or merge. They have no effect and should be removed.

🐛 Proposed fix
-Filesystem.write
-Filesystem.write
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/opencode/src/config/config.ts` around lines 1546 - 1547, Remove the
two orphaned standalone expressions "Filesystem.write" found at the end of the
file; these are no-op remnants and should be deleted so only real function
definitions/exports remain (search for the symbol "Filesystem.write" near the
file tail and remove those two lines).
🧹 Nitpick comments (1)
packages/opencode/test/skill/discover-external.test.ts (1)

8-16: Consider using the tmpdir fixture for consistency.

The test uses manual mkdtemp/rm with beforeEach/afterEach instead of the project's tmpdir fixture. While functional, using tmpdir from fixture/fixture.ts with await using syntax would align with project conventions and provide automatic cleanup. As per coding guidelines, use the tmpdir function from fixture/fixture.ts to create temporary directories for tests with automatic cleanup.

♻️ Example pattern using tmpdir
import { tmpdir } from "../fixture/fixture"

describe("discoverExternalSkills", () => {
  test("discovers Claude Code command with frontmatter", async () => {
    await using tmp = await tmpdir({
      init: async (dir) => {
        await mkdir(path.join(dir, ".claude", "commands"), { recursive: true })
        await writeFile(
          path.join(dir, ".claude", "commands", "review.md"),
          `---\nname: review\ndescription: Review the code changes\n---\n\nPlease review the following code changes: $ARGUMENTS\n`,
        )
      },
    })
    
    const { skills } = await Instance.provide({
      directory: tmp.path,
      fn: () => discoverExternalSkills(tmp.path),
    })
    // assertions...
  })
})
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/opencode/test/skill/discover-external.test.ts` around lines 8 - 16,
Replace the manual mkdtemp/rm setup in the test with the project's tmpdir
fixture: import tmpdir from fixture/fixture.ts, remove beforeEach/afterEach and
tempDir variable, and use "await using tmp = await tmpdir({ init: async (dir) =>
{ ... } })" inside the test to create the directory and seed files; then call
discoverExternalSkills(tmp.path) (or pass tmp.path into Instance.provide) so the
fixture handles cleanup automatically.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@packages/opencode/src/config/config.ts`:
- Around line 1546-1547: Remove the two orphaned standalone expressions
"Filesystem.write" found at the end of the file; these are no-op remnants and
should be deleted so only real function definitions/exports remain (search for
the symbol "Filesystem.write" near the file tail and remove those two lines).

---

Nitpick comments:
In `@packages/opencode/test/skill/discover-external.test.ts`:
- Around line 8-16: Replace the manual mkdtemp/rm setup in the test with the
project's tmpdir fixture: import tmpdir from fixture/fixture.ts, remove
beforeEach/afterEach and tempDir variable, and use "await using tmp = await
tmpdir({ init: async (dir) => { ... } })" inside the test to create the
directory and seed files; then call discoverExternalSkills(tmp.path) (or pass
tmp.path into Instance.provide) so the fixture handles cleanup automatically.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 1cc2ba19-9156-47a9-8323-9d6249fff3dd

📥 Commits

Reviewing files that changed from the base of the PR and between 6b7070d and bb1ae28.

📒 Files selected for processing (6)
  • packages/opencode/src/command/index.ts
  • packages/opencode/src/config/config.ts
  • packages/opencode/src/skill/discover-external.ts
  • packages/opencode/src/skill/skill.ts
  • packages/opencode/test/skill/discover-external.test.ts
  • packages/opencode/test/tool/skill.test.ts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant