Skip to content

Commit e450099

Browse files
arsenyinfoclaude
andauthored
aitools: add skills command for coding agents (#4125)
## Changes Add `databricks experimental aitools skills` subcommand to install Agent Skills for coding agents: - `skills list` - list available skills from the databricks-agent-skills repo - `skills install [skill-name]` - install skills to detected coding agents ### Multi-agent support Automatically detects and installs skills for: - Claude Code (`~/.claude/skills/`) - Cursor (`~/.cursor/skills/`) - Codex CLI (`~/.codex/skills/`) - OpenCode (`~/.config/opencode/skills/`) - GitHub Copilot (`~/.copilot/skills/`) - Antigravity (`~/.gemini/antigravity/global_skills/`) When multiple agents are detected, skills are installed to a canonical location (`~/.databricks/agent-skills/`) and symlinked to each agent to avoid duplication. ### Refactored agent registry Unified agent detection logic in `lib/agents/agents.go` - shared between skills installation and MCP installation commands. ## Why Skills are simpler than MCP for providing domain-specific guidance to AI agents. While MCP requires a running server, skills are static documentation that agents load on demand. This gives users a lightweight way to get Databricks-specific guidance across all major coding agents. ## Tests Manual testing: ```bash databricks experimental aitools skills list databricks experimental aitools skills install databricks experimental aitools skills install databricks-apps ``` --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent da95cea commit e450099

File tree

6 files changed

+625
-82
lines changed

6 files changed

+625
-82
lines changed

experimental/aitools/cmd/aitools.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ Provides commands to:
2828

2929
cmd.AddCommand(newMcpCmd())
3030
cmd.AddCommand(newInstallCmd())
31+
cmd.AddCommand(newSkillsCmd())
3132
cmd.AddCommand(newToolsCmd())
3233

3334
return cmd

experimental/aitools/cmd/install.go

Lines changed: 32 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -30,25 +30,24 @@ func runInstall(ctx context.Context) error {
3030
// Check for non-interactive mode with agent detection
3131
// If running in an AI agent, install automatically without prompts
3232
if !cmdio.IsPromptSupported(ctx) {
33+
var targetAgent *agents.Agent
3334
switch agent.Product(ctx) {
3435
case agent.ClaudeCode:
35-
if err := agents.InstallClaude(); err != nil {
36-
return err
37-
}
38-
cmdio.LogString(ctx, color.GreenString("✓ Installed Databricks MCP server for Claude Code"))
39-
cmdio.LogString(ctx, color.YellowString("⚠️ Please restart Claude Code for changes to take effect"))
40-
return nil
36+
targetAgent = agents.GetByName("claude-code")
4137
case agent.Cursor:
42-
if err := agents.InstallCursor(); err != nil {
38+
targetAgent = agents.GetByName("cursor")
39+
}
40+
41+
if targetAgent != nil && targetAgent.InstallMCP != nil {
42+
if err := targetAgent.InstallMCP(); err != nil {
4343
return err
4444
}
45-
cmdio.LogString(ctx, color.GreenString("✓ Installed Databricks MCP server for Cursor"))
46-
cmdio.LogString(ctx, color.YellowString("⚠️ Please restart Cursor for changes to take effect"))
45+
cmdio.LogString(ctx, color.GreenString("✓ Installed Databricks MCP server for %s", targetAgent.DisplayName))
46+
cmdio.LogString(ctx, color.YellowString("⚠️ Please restart %s for changes to take effect", targetAgent.DisplayName))
4747
return nil
48-
default:
49-
// Unknown agent in non-interactive mode - show manual instructions
50-
return agents.ShowCustomInstructions(ctx)
5148
}
49+
// Unknown agent in non-interactive mode - show manual instructions
50+
return agents.ShowCustomInstructions(ctx)
5251
}
5352

5453
cmdio.LogString(ctx, "")
@@ -69,39 +68,32 @@ func runInstall(ctx context.Context) error {
6968

7069
anySuccess := false
7170

72-
ans, err := cmdio.AskSelect(ctx, "Install for Claude Code?", []string{"yes", "no"})
73-
if err != nil {
74-
return err
75-
}
76-
if ans == "yes" {
77-
fmt.Fprint(os.Stderr, "Installing MCP server for Claude Code...")
78-
if err := agents.InstallClaude(); err != nil {
79-
fmt.Fprint(os.Stderr, "\r"+color.YellowString("⊘ Skipped Claude Code: "+err.Error())+"\n")
80-
} else {
81-
fmt.Fprint(os.Stderr, "\r"+color.GreenString("✓ Installed for Claude Code")+" \n")
82-
anySuccess = true
71+
// Install for agents that have MCP support
72+
for i := range agents.Registry {
73+
a := &agents.Registry[i]
74+
if a.InstallMCP == nil {
75+
continue
8376
}
84-
cmdio.LogString(ctx, "")
85-
}
8677

87-
ans, err = cmdio.AskSelect(ctx, "Install for Cursor?", []string{"yes", "no"})
88-
if err != nil {
89-
return err
90-
}
91-
if ans == "yes" {
92-
fmt.Fprint(os.Stderr, "Installing MCP server for Cursor...")
93-
if err := agents.InstallCursor(); err != nil {
94-
fmt.Fprint(os.Stderr, "\r"+color.YellowString("⊘ Skipped Cursor: "+err.Error())+"\n")
95-
} else {
96-
// Brief delay so users see the "Installing..." message before it's replaced
97-
time.Sleep(1 * time.Second)
98-
fmt.Fprint(os.Stderr, "\r"+color.GreenString("✓ Installed for Cursor")+" \n")
99-
anySuccess = true
78+
ans, err := cmdio.AskSelect(ctx, fmt.Sprintf("Install for %s?", a.DisplayName), []string{"yes", "no"})
79+
if err != nil {
80+
return err
81+
}
82+
if ans == "yes" {
83+
fmt.Fprintf(os.Stderr, "Installing MCP server for %s...", a.DisplayName)
84+
if err := a.InstallMCP(); err != nil {
85+
fmt.Fprint(os.Stderr, "\r"+color.YellowString("⊘ Skipped %s: %s", a.DisplayName, err.Error())+"\n")
86+
} else {
87+
// Brief delay so users see the "Installing..." message before it's replaced
88+
time.Sleep(500 * time.Millisecond)
89+
fmt.Fprint(os.Stderr, "\r"+color.GreenString("✓ Installed for %s", a.DisplayName)+" \n")
90+
anySuccess = true
91+
}
92+
cmdio.LogString(ctx, "")
10093
}
101-
cmdio.LogString(ctx, "")
10294
}
10395

104-
ans, err = cmdio.AskSelect(ctx, "Show manual installation instructions for other agents?", []string{"yes", "no"})
96+
ans, err := cmdio.AskSelect(ctx, "Show manual installation instructions for other agents?", []string{"yes", "no"})
10597
if err != nil {
10698
return err
10799
}

0 commit comments

Comments
 (0)