מדריך קלוד קוד בעברית

תיעוד 143

תוספים ב-SDK

טען תוספים מותאמים אישית כדי להרחיב את Claude Code עם skills, agents, hooks ושרתי MCP באמצעות ה-Agent SDK.

תוספים מאפשרים לך להרחיב את Claude Code עם פונקציונליות מותאמת אישית שניתן לשתף בין פרויקטים. באמצעות ה-Agent SDK, באפשרותך לטעון תוספים באופן תכנותי מתוך ספריות מקומיות כדי להוסיף יכולות להפעלות הסוכן שלך. תוסף יכול לכלול:

  • Skills: יכולות ש-Claude מפעיל באופן עצמאי כאשר הן רלוונטיות. ניתן גם להפעיל skill של תוסף ישירות באמצעות ‎/plugin-name:skill-name‎.
  • Agents: תת-סוכנים ייעודיים למשימות ספציפיות.
  • Hooks: מטפלי אירועים המגיבים לשימוש בכלים ולאירועים אחרים.
  • שרתי MCP: שילובי כלים חיצוניים באמצעות Model Context Protocol.

למידע מלא על מבנה תוספים וכיצד ליצור תוספים, ראה תוספים.

#טעינת תוספים

טען תוספים על ידי ציון נתיבי מערכת הקבצים המקומית שלהם בהגדרת ה-options שלך. השדה type חייב להיות "local", הערך היחיד שה-SDK מקבל. ה-SDK תומך בטעינת מספר תוספים ממיקומים שונים.

כדי להשתמש בתוסף המופץ דרך חנות תוספים או מאגר מרוחק, הורד אותו תחילה וספק את נתיב הספרייה המקומית. למבנה הספריות שתוסף צריך, ראה את הפניה למבנה תוסף להלן.

TypeScript:

import { query } from "@anthropic-ai/claude-agent-sdk";

for await (const message of query({
  prompt: "Hello",
  options: {
    plugins: [
      { type: "local", path: "./my-plugin" },
      { type: "local", path: "/absolute/path/to/another-plugin" }
    ]
  }
})) {
  // Plugin commands, agents, and other features are now available
}

Python:

import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions


async def main():
    async for message in query(
        prompt="Hello",
        options=ClaudeAgentOptions(
            plugins=[
                {"type": "local", "path": "./my-plugin"},
                {"type": "local", "path": "/absolute/path/to/another-plugin"},
            ]
        ),
    ):
        
# Plugin commands, agents, and other features are now available
        pass


asyncio.run(main())

#מפרטי נתיב

נתיבי תוספים יכולים להיות:

  • נתיבים יחסיים: נפתרים ביחס לספריית העבודה הנוכחית שלך (לדוגמה, "./plugins/my-plugin").
  • נתיבים מוחלטים: נתיבי מערכת קבצים מלאים (לדוגמה, "/home/user/plugins/my-plugin").

הערה: הנתיב צריך להצביע על ספריית השורש של התוסף: ספריית האב של skills/, agents/, hooks/, commands/, או .claude-plugin/.

#אימות התקנת תוסף

כאשר תוספים נטענים בהצלחה, הם מופיעים בהודעת אתחול המערכת. באפשרותך לוודא שהתוספים שלך זמינים:

TypeScript:

import { query } from "@anthropic-ai/claude-agent-sdk";

for await (const message of query({
  prompt: "Hello",
  options: {
    plugins: [{ type: "local", path: "./my-plugin" }]
  }
})) {
  if (message.type === "system" && message.subtype === "init") {
    // Check loaded plugins
    console.log("Plugins:", message.plugins);
    // Example: [{ name: "my-plugin", path: "/absolute/path/to/my-plugin" }]

    // Plugin skills appear with the plugin name as a prefix
    console.log("Skills:", message.skills);
    // Example: ["my-plugin:greet"]

    // Plugin commands use the same prefix, and skills appear here too
    console.log("Commands:", message.slash_commands);
    // Example: ["compact", "context", "my-plugin:custom-command", "my-plugin:greet"]
  }
}

Python:

import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, SystemMessage


async def main():
    async for message in query(
        prompt="Hello",
        options=ClaudeAgentOptions(
            plugins=[{"type": "local", "path": "./my-plugin"}]
        ),
    ):
        if isinstance(message, SystemMessage) and message.subtype == "init":
            
# Check loaded plugins
            print("Plugins:", message.data.get("plugins"))
            
# Example: [{"name": "my-plugin", "path": "/absolute/path/to/my-plugin"}]

            
# Plugin skills appear with the plugin name as a prefix
            print("Skills:", message.data.get("skills"))
            
# Example: ["my-plugin:greet"]

            
# Plugin commands use the same prefix, and skills appear here too
            print("Commands:", message.data.get("slash_commands"))
            
# Example: ["compact", "context", "my-plugin:custom-command", "my-plugin:greet"]


asyncio.run(main())

#שימוש בכישורי תוספים

כישורים (skills) מתוספים מקבלים באופן אוטומטי מרחב שמות (namespace) עם שם התוסף כדי למנוע התנגשויות. כדי להפעיל אחד ישירות, שלח את ‎/plugin-name:skill-name‎ כהנחיה (prompt).

TypeScript:

import { query } from "@anthropic-ai/claude-agent-sdk";

// Load a plugin with a custom /greet skill
for await (const message of query({
  prompt: "/my-plugin:greet", // Use plugin skill with namespace
  options: {
    plugins: [{ type: "local", path: "./my-plugin" }]
  }
})) {
  // Claude executes the custom greeting skill from the plugin
  if (message.type === "assistant") {
    console.log(message.message.content);
  }
}

Python:

import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, AssistantMessage, TextBlock


async def main():
    
# Load a plugin with a custom /greet skill
    async for message in query(
        prompt="/my-plugin:greet",  
# Use plugin skill with namespace
        options=ClaudeAgentOptions(
            plugins=[{"type": "local", "path": "./my-plugin"}]
        ),
    ):
        
# Claude executes the custom greeting skill from the plugin
        if isinstance(message, AssistantMessage):
            for block in message.content:
                if isinstance(block, TextBlock):
                    print(f"Claude: {block.text}")


asyncio.run(main())

הערה: אם התקנת תוסף דרך ה-CLI (לדוגמה, ‎/plugin install my-plugin@marketplace‎), אתה עדיין יכול להשתמש בו ב-SDK על ידי ציון נתיב ההתקנה שלו. בדוק את ~/.claude/plugins/ עבור תוספים שהותקנו דרך ה-CLI.

#דוגמה מלאה

הנה דוגמה מלאה המדגימה טעינה ושימוש בתוספים:

TypeScript:

import { query } from "@anthropic-ai/claude-agent-sdk";
import { fileURLToPath } from "node:url";

async function runWithPlugin() {
  const pluginPath = fileURLToPath(new URL("./plugins/my-plugin", import.meta.url));

  console.log("Loading plugin from:", pluginPath);

  for await (const message of query({
    prompt: "What custom commands do you have available?",
    options: {
      plugins: [{ type: "local", path: pluginPath }],
      maxTurns: 3
    }
  })) {
    if (message.type === "system" && message.subtype === "init") {
      console.log("Loaded plugins:", message.plugins);
      console.log("Available skills:", message.skills);
      console.log("Available commands:", message.slash_commands);
    }

    if (message.type === "assistant") {
      console.log("Assistant:", message.message.content);
    }
  }
}

runWithPlugin().catch(console.error);

Python:

#!/usr/bin/env python3
"""Example demonstrating how to use plugins with the Agent SDK."""

import asyncio
from pathlib import Path

from claude_agent_sdk import (
    AssistantMessage,
    ClaudeAgentOptions,
    SystemMessage,
    TextBlock,
    query,
)


async def run_with_plugin():
    """Example using a custom plugin."""
    plugin_path = Path(__file__).parent / "plugins" / "my-plugin"

    print(f"Loading plugin from: {plugin_path}")

    options = ClaudeAgentOptions(
        plugins=[{"type": "local", "path": str(plugin_path)}],
        max_turns=3,
    )

    async for message in query(
        prompt="What custom commands do you have available?", options=options
    ):
        if isinstance(message, SystemMessage) and message.subtype == "init":
            print(f"Loaded plugins: {message.data.get('plugins')}")
            print(f"Available skills: {message.data.get('skills')}")
            print(f"Available commands: {message.data.get('slash_commands')}")

        if isinstance(message, AssistantMessage):
            for block in message.content:
                if isinstance(block, TextBlock):
                    print(f"Assistant: {block.text}")


if __name__ == "__main__":
    asyncio.run(run_with_plugin())

#הפניה למבנה תוסף

ספריית תוסף מכילה בדרך כלל קובץ מניפסט מסוג .claude-plugin/plugin.json. קובץ המניפסט הוא אופציונלי. כאשר הוא מושמט, Claude Code מזהה רכיבים באופן אוטומטי מתוך פריסת הספרייה. הספרייה יכולה לכלול:

my-plugin/
├── .claude-plugin/
│   └── plugin.json          
# Plugin manifest (optional, components auto-discovered without it)
├── skills/                   
# Agent Skills (invoked autonomously or via /plugin-name:skill-name)
│   └── my-skill/
│       └── SKILL.md
├── commands/                 
# Skills as flat .md files
│   └── custom-cmd.md
├── agents/                   
# Custom agents
│   └── specialist.md
├── hooks/                    
# Event handlers
│   └── hooks.json
└── .mcp.json                
# MCP server definitions

הערה: ספריית commands/ מכילה כישורים כקובצי Markdown שטוחים. השתמש ב-skills/ עבור תוספים חדשים. Claude Code תומך בשני המיקומים.

#מספר מקורות תוספים

שלב תוספים ממיקומים שונים:

import * as os from "node:os";
import * as path from "node:path";

plugins: [
  { type: "local", path: "./local-plugin" },
  {
    type: "local",
    path: path.join(os.homedir(), ".claude", "custom-plugins", "shared-plugin")
  }
];

הערה: ה-SDK אינו מרחיב נתיבי טילדה כמו ~/plugins. אם נתיב של תוסף אינו קיים, ה-SDK מדלג על תוסף זה וההפעלה ממשיכה, לכן בדוק את רשימת plugins בהודעת ה-init כדי לוודא שכל תוסף אכן נטען.

#פתרון בעיות

#תוסף אינו נטען

אם התוסף שלך אינו מופיע בהודעת ה-init:

  1. בדוק את הנתיב: ודא שהנתיב מצביע על ספריית השורש של התוסף: ספריית האב של skills/, agents/, hooks/, commands/, או .claude-plugin/.
  2. אמת את plugin.json: אם התוסף שלך כולל מניפסט, ודא שיש לו תחביר JSON תקין.
  3. בדוק הרשאות קבצים: ודא שספריית התוסף ניתנת לקריאה.
  4. אשר שהספרייה קיימת: ה-SDK מדלג על נתיב שאינו קיים, והתוסף אינו מופיע ברשימת ה-plugins של הודעת ה-init.

#כישורים אינם מופיעים

אם כישורי התוסף אינם עובדים:

  1. השתמש במרחב השמות: הפעל כישורי תוסף בתבנית ‎/plugin-name:skill-name‎.
  2. בדוק את הודעת ה-init: ודא שהכישור מופיע ברשימת ה-skills עם מרחב השמות הנכון.
  3. אמת את קובצי הכישור: ודא שלכל כישור יש קובץ SKILL.md בספריית משנה משלו תחת skills/, לדוגמה skills/my-skill/SKILL.md.

#ראו גם