From 29d04d186a8b6c167434f01b5b17a3422510f7bb Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 29 Jun 2026 14:48:29 +0000 Subject: [PATCH] feat(skills): add curated skill repo links to Skills settings page Add a "Browse skills online" section to the Skills settings panel with clickable links to places users can find and download SKILL.md skills (Anthropic Skills, the agentskills.io open standard, the Claude Code Marketplace, and SkillsMP). Each link opens in the browser and is paired with a short description; a hint directs users to drop a downloaded skill folder into a scanned directory and hit Reload. This is a lightweight first step toward skill discovery, ahead of a full marketplace-style installer. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01WGXHB8jKct1peZjM8E1J5W --- .../skill/SkillsSettingsComponent.java | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/src/main/java/com/devoxx/genie/ui/settings/skill/SkillsSettingsComponent.java b/src/main/java/com/devoxx/genie/ui/settings/skill/SkillsSettingsComponent.java index 160490b92..023006a50 100644 --- a/src/main/java/com/devoxx/genie/ui/settings/skill/SkillsSettingsComponent.java +++ b/src/main/java/com/devoxx/genie/ui/settings/skill/SkillsSettingsComponent.java @@ -5,6 +5,7 @@ import com.devoxx.genie.ui.settings.DevoxxGenieStateService; import com.intellij.ide.BrowserUtil; import com.intellij.openapi.project.Project; +import com.intellij.ui.HyperlinkLabel; import com.intellij.ui.JBColor; import com.intellij.ui.components.JBLabel; import com.intellij.ui.components.JBScrollPane; @@ -35,6 +36,29 @@ public class SkillsSettingsComponent extends AbstractSettingsComponent { private static final String DOCS_URL = "https://genie.devoxx.com/docs/features/skills"; + /** A curated external source where users can discover and download skills. */ + private record SkillLink(String title, String url, String description) {} + + /** + * Curated links shown in the "Browse skills online" section. Skills follow the open + * {@code SKILL.md} standard, so a skill folder downloaded from any of these sources can be + * dropped into one of the scanned skill directories and picked up by the {@link SkillRegistry}. + */ + private static final SkillLink[] SKILL_LINKS = { + new SkillLink("Anthropic Skills", + "https://github.com/anthropics/skills", + "Official Agent Skills published by Anthropic"), + new SkillLink("Agent Skills standard", + "https://agentskills.io", + "The open SKILL.md specification, portable across AI coding tools"), + new SkillLink("Claude Code Marketplace", + "https://github.com/netresearch/claude-code-marketplace", + "40+ community skills for AI-assisted development"), + new SkillLink("SkillsMP", + "https://skillsmp.com", + "Searchable directory of community SKILL.md files"), + }; + private final Project project; private final SkillRegistry registry; private final SkillsTableModel tableModel = new SkillsTableModel(); @@ -100,6 +124,17 @@ public JPanel createPanel() { gbc.gridy++; panel.add(description, gbc); + // Curated links to places where users can find skills to download into the folders above. + addSection(panel, gbc, "Browse skills online"); + + JBLabel linksHint = new JBLabel( + "Download a skill's folder from one of these sources into a directory above, then click Reload."); + gbc.gridy++; + panel.add(linksHint, gbc); + + gbc.gridy++; + panel.add(buildLinksPanel(), gbc); + // Toolbar: a single "Open Skills Folder" button + dropdown that selects which of the // six skill directories to open, followed by the Reload button on the same row. The // previous layout (six side-by-side buttons in a FlowLayout) overflowed and clipped @@ -172,6 +207,36 @@ public JPanel createPanel() { return panel; } + /** + * Builds a panel listing the curated {@link #SKILL_LINKS}, one per row: a clickable + * {@link HyperlinkLabel} opening the source in the browser, followed by a short description. + */ + private JPanel buildLinksPanel() { + JPanel linksPanel = new JPanel(new GridBagLayout()); + GridBagConstraints lgbc = new GridBagConstraints(); + lgbc.gridy = 0; + lgbc.anchor = GridBagConstraints.WEST; + lgbc.insets = JBUI.insets(2, 0, 2, 12); + + for (SkillLink link : SKILL_LINKS) { + HyperlinkLabel label = new HyperlinkLabel(link.title()); + label.setHyperlinkTarget(link.url()); + label.setToolTipText(link.url()); + lgbc.gridx = 0; + lgbc.weightx = 0; + linksPanel.add(label, lgbc); + + JBLabel desc = new JBLabel(link.description()); + desc.setForeground(JBColor.GRAY); + lgbc.gridx = 1; + lgbc.weightx = 1.0; + linksPanel.add(desc, lgbc); + + lgbc.gridy++; + } + return linksPanel; + } + public boolean isModified() { Set persisted = DevoxxGenieStateService.getInstance().getDisabledSkillNames(); if (persisted == null) {