1> ## Documentation Index
2> Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt
3> Use this file to discover all available pages before exploring further.
4
5# Aggiungi componenti a un plugin
6
7> Aggiungi skills, hooks, server MCP e ogni altro tipo di componente a un plugin Claude Code, con un esempio che convalida per ciascuno.
8
9export const Piece = ({id, children}) => <div className="pe-piece" data-piece={id}>{children}</div>;
10
11export const PluginExplorer = ({children}) => {
12 const PIECES = [{
13 id: 'manifest',
14 name: 'Manifest',
15 path: '.claude-plugin/plugin.json',
16 required: "Required by Anthropic's directory",
17 lines: [{
18 depth: 0,
19 kind: 'folder',
20 text: '.claude-plugin/'
21 }, {
22 depth: 1,
23 kind: 'file',
24 text: 'plugin.json'
25 }],
26 href: '/en/plugins/manifest-reference#manifest-file',
27 linkText: 'Go to the manifest reference'
28 }, {
29 id: 'skills',
30 name: 'Skills',
31 path: 'skills/review/SKILL.md',
32 lines: [{
33 depth: 0,
34 kind: 'folder',
35 text: 'skills/'
36 }, {
37 depth: 1,
38 kind: 'folder',
39 text: 'review/'
40 }, {
41 depth: 2,
42 kind: 'file',
43 text: 'SKILL.md'
44 }],
45 href: '/en/plugins/components#skills',
46 linkText: 'Go to the Skills section'
47 }, {
48 id: 'commands',
49 name: 'Commands',
50 path: 'commands/about.md',
51 lines: [{
52 depth: 0,
53 kind: 'folder',
54 text: 'commands/'
55 }, {
56 depth: 1,
57 kind: 'file',
58 text: 'about.md'
59 }],
60 href: '/en/plugins/components#commands',
61 linkText: 'Go to the Commands section'
62 }, {
63 id: 'agents',
64 name: 'Agents',
65 path: 'agents/security-reviewer.md',
66 lines: [{
67 depth: 0,
68 kind: 'folder',
69 text: 'agents/'
70 }, {
71 depth: 1,
72 kind: 'file',
73 text: 'security-reviewer.md'
74 }],
75 href: '/en/plugins/components#agents',
76 linkText: 'Go to the Agents section'
77 }, {
78 id: 'hooks',
79 name: 'Hooks',
80 path: 'hooks/hooks.json',
81 lines: [{
82 depth: 0,
83 kind: 'folder',
84 text: 'hooks/'
85 }, {
86 depth: 1,
87 kind: 'file',
88 text: 'hooks.json'
89 }],
90 href: '/en/plugins/components#hooks',
91 linkText: 'Go to the Hooks section'
92 }, {
93 id: 'monitors',
94 name: 'Monitors',
95 path: 'monitors/monitors.json',
96 lines: [{
97 depth: 0,
98 kind: 'folder',
99 text: 'monitors/'
100 }, {
101 depth: 1,
102 kind: 'file',
103 text: 'monitors.json'
104 }],
105 href: '/en/plugins/components#monitors',
106 linkText: 'Go to the Monitors section'
107 }, {
108 id: 'output-styles',
109 name: 'Output styles',
110 path: 'output-styles/terse.md',
111 lines: [{
112 depth: 0,
113 kind: 'folder',
114 text: 'output-styles/'
115 }, {
116 depth: 1,
117 kind: 'file',
118 text: 'terse.md'
119 }],
120 href: '/en/plugins/components#themes-and-output-styles',
121 linkText: 'Go to the Themes and output styles section'
122 }, {
123 id: 'themes',
124 name: 'Themes',
125 path: 'themes/dracula.json',
126 lines: [{
127 depth: 0,
128 kind: 'folder',
129 text: 'themes/'
130 }, {
131 depth: 1,
132 kind: 'file',
133 text: 'dracula.json'
134 }],
135 href: '/en/plugins/components#themes-and-output-styles',
136 linkText: 'Go to the Themes and output styles section'
137 }, {
138 id: 'workflows',
139 name: 'Workflows',
140 path: 'workflows/audit-routes.js',
141 lines: [{
142 depth: 0,
143 kind: 'folder',
144 text: 'workflows/'
145 }, {
146 depth: 1,
147 kind: 'file',
148 text: 'audit-routes.js'
149 }],
150 href: '/en/workflows#distribute-a-workflow-in-a-plugin',
151 linkText: 'Go to Distribute a workflow in a plugin'
152 }, {
153 id: 'bin',
154 name: 'Executables',
155 path: 'bin/hello-plugin',
156 lines: [{
157 depth: 0,
158 kind: 'folder',
159 text: 'bin/'
160 }, {
161 depth: 1,
162 kind: 'file',
163 text: 'hello-plugin'
164 }],
165 href: '/en/plugins/components#executables',
166 linkText: 'Go to the Executables section'
167 }, {
168 id: 'scripts',
169 name: 'Scripts',
170 path: 'scripts/format.sh',
171 lines: [{
172 depth: 0,
173 kind: 'folder',
174 text: 'scripts/'
175 }, {
176 depth: 1,
177 kind: 'file',
178 text: 'format.sh'
179 }],
180 href: '/en/plugins/components#hooks',
181 linkText: 'Go to the Hooks section'
182 }, {
183 id: 'settings',
184 name: 'Default settings',
185 path: 'settings.json',
186 lines: [{
187 depth: 0,
188 kind: 'file',
189 text: 'settings.json'
190 }],
191 href: '/en/plugins/components#default-settings',
192 linkText: 'Go to the Default settings section'
193 }, {
194 id: 'mcp',
195 name: 'MCP servers',
196 path: '.mcp.json',
197 lines: [{
198 depth: 0,
199 kind: 'file',
200 text: '.mcp.json'
201 }],
202 href: '/en/plugins/components#mcp-servers',
203 linkText: 'Go to the MCP servers section'
204 }, {
205 id: 'lsp',
206 name: 'LSP servers',
207 path: '.lsp.json',
208 lines: [{
209 depth: 0,
210 kind: 'file',
211 text: '.lsp.json'
212 }],
213 href: '/en/plugins/components#lsp-servers',
214 linkText: 'Go to the LSP servers section'
215 }];
216 const [selectedId, setSelectedId] = useState('manifest');
217 const [isFullscreen, setIsFullscreen] = useState(false);
218 const rootRef = useRef(null);
219 useEffect(() => {
220 const onFsChange = () => setIsFullscreen(!!document.fullscreenElement);
221 document.addEventListener('fullscreenchange', onFsChange);
222 return () => document.removeEventListener('fullscreenchange', onFsChange);
223 }, []);
224 const toggleFullscreen = () => {
225 if (!rootRef.current) return;
226 if (document.fullscreenElement) document.exitFullscreen(); else rootRef.current.requestFullscreen().catch(() => {});
227 };
228 const selected = PIECES.find(p => p.id === selectedId) || PIECES[0];
229 const onTreeKeyDown = e => {
230 const keys = ['ArrowDown', 'ArrowUp', 'Home', 'End'];
231 if (keys.indexOf(e.key) === -1) return;
232 const i = PIECES.findIndex(p => p.id === selectedId);
233 let next = i;
234 if (e.key === 'ArrowDown') next = Math.min(PIECES.length - 1, i + 1);
235 if (e.key === 'ArrowUp') next = Math.max(0, i - 1);
236 if (e.key === 'Home') next = 0;
237 if (e.key === 'End') next = PIECES.length - 1;
238 e.preventDefault();
239 if (next === i) return;
240 const id = PIECES[next].id;
241 setSelectedId(id);
242 const el = document.getElementById('pe-node-' + id);
243 if (el) el.focus();
244 };
245 const FolderIcon = () => <svg className="pe-icon" width="15" height="15" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.3" strokeLinejoin="round" aria-hidden="true">
246 <path d="M1.5 4.5a1 1 0 0 1 1-1h3.2l1.3 1.5h6a1 1 0 0 1 1 1V12a1 1 0 0 1-1 1h-10.5a1 1 0 0 1-1-1z" />
247 </svg>;
248 const FileIcon = () => <svg className="pe-icon" width="15" height="15" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.3" strokeLinejoin="round" aria-hidden="true">
249 <path d="M4 1.5h5.5L13 5v9.5H4z" />
250 <path d="M9.5 1.5V5H13" />
251 </svg>;
252 return <div ref={rootRef} className={isFullscreen ? 'pe-root pe-fullscreen not-prose' : 'pe-root not-prose'} data-selected={selected.id}>
253 <style>{`
254 .pe-root {
255 --pe-mono: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
256 --pe-accent: #D97757;
257 --pe-accent-text: #A8502F;
258 --pe-accent-bg: rgba(217,119,87,0.10);
259 --pe-bg: #FFFFFF;
260 --pe-surface: #FAFAF7;
261 --pe-hover: #F0EEE6;
262 --pe-border: #E8E6DC;
263 --pe-text: #141413;
264 --pe-text-2: #3D3D3A;
265 --pe-text-3: #5E5D59;
266 font-family: inherit;
267 background: var(--pe-bg);
268 color: var(--pe-text);
269 border: 1px solid var(--pe-border);
270 border-radius: 12px;
271 margin: 1.5rem 0;
272 overflow: hidden;
273 box-sizing: border-box;
274 }
275 .dark .pe-root {
276 --pe-accent-text: #EBA98F;
277 --pe-accent-bg: rgba(217,119,87,0.18);
278 --pe-bg: #1A1918;
279 --pe-surface: #232221;
280 --pe-hover: #2E2D2B;
281 --pe-border: #3A3936;
282 --pe-text: #F1EFE9;
283 --pe-text-2: #D6D4CA;
284 --pe-text-3: #B8B5AD;
285 }
286 .pe-root *, .pe-root *::before, .pe-root *::after { box-sizing: border-box; }
287 .pe-head { display: flex; align-items: flex-start; gap: 12px; padding: 18px 24px 16px; border-bottom: 1px solid var(--pe-border); }
288 .pe-head-text { flex: 1; min-width: 0; }
289 .pe-fs-btn { flex-shrink: 0; width: 32px; height: 32px; display: inline-flex; align-items: center; justify-content: center; border: 1px solid var(--pe-border); border-radius: 6px; background: var(--pe-surface); color: var(--pe-text-2); font-size: 15px; line-height: 1; cursor: pointer; }
290 .pe-fs-btn:hover { background: var(--pe-hover); }
291 .pe-fs-btn:focus-visible { outline: 2px solid var(--pe-accent); outline-offset: 2px; }
292 .pe-fullscreen { border-radius: 0; height: 100vh; display: flex; flex-direction: column; overflow: auto; }
293 .pe-fullscreen .pe-body { flex: 1; }
294 .pe-title { font-size: 19px; font-weight: 600; line-height: 1.3; color: var(--pe-text); margin: 0; }
295 .pe-sub { font-size: 15px; line-height: 1.5; color: var(--pe-text-3); margin: 4px 0 0; }
296 .pe-sub code { font-family: var(--pe-mono); font-size: 0.88em; padding: 1px 5px; border-radius: 4px; background: var(--pe-surface); border: 1px solid var(--pe-border); }
297 .pe-body { display: flex; align-items: stretch; }
298 .pe-tree-pane { width: 270px; flex-shrink: 0; background: var(--pe-surface); border-right: 1px solid var(--pe-border); padding: 16px 0 12px; }
299 .pe-panel { flex: 1; min-width: 0; padding: 16px 24px 24px; }
300 .pe-caption { font-size: 13px; font-weight: 600; color: var(--pe-text-3); margin: 0 0 10px; }
301 .pe-tree-pane .pe-caption { padding: 0 16px; }
302 .pe-rootline { display: flex; align-items: center; gap: 7px; padding: 3px 16px; font-family: var(--pe-mono); font-size: 13.5px; color: var(--pe-text-3); }
303 .pe-node {
304 display: block; width: 100%; margin: 0; padding: 3px 16px 3px 30px; text-align: left; cursor: pointer;
305 background: transparent; color: var(--pe-text-2);
306 border: none; border-left: 3px solid transparent;
307 font-family: var(--pe-mono); font-size: 13.5px; line-height: 1.4;
308 }
309 .pe-node:hover { background: var(--pe-hover); }
310 .pe-node:focus-visible { outline: 2px solid var(--pe-accent); outline-offset: -2px; }
311 .pe-node[aria-pressed="true"] { background: var(--pe-accent-bg); border-left-color: var(--pe-accent); color: var(--pe-accent-text); font-weight: 600; }
312 .pe-line { display: flex; align-items: center; gap: 7px; padding: 2px 0; }
313 .pe-line-tree { flex-wrap: wrap; }
314 .pe-line-tree .pe-req { flex-basis: 100%; margin: 2px 0 0 22px; white-space: normal; width: fit-content; max-width: calc(100% - 22px); }
315 .pe-line span { overflow-wrap: anywhere; }
316 .pe-piece { display: none; font-size: 16px; line-height: 1.6; color: var(--pe-text-2); }
317 .pe-root[data-selected="manifest"] .pe-piece[data-piece="manifest"],
318 .pe-root[data-selected="skills"] .pe-piece[data-piece="skills"],
319 .pe-root[data-selected="commands"] .pe-piece[data-piece="commands"],
320 .pe-root[data-selected="agents"] .pe-piece[data-piece="agents"],
321 .pe-root[data-selected="hooks"] .pe-piece[data-piece="hooks"],
322 .pe-root[data-selected="monitors"] .pe-piece[data-piece="monitors"],
323 .pe-root[data-selected="output-styles"] .pe-piece[data-piece="output-styles"],
324 .pe-root[data-selected="themes"] .pe-piece[data-piece="themes"],
325 .pe-root[data-selected="workflows"] .pe-piece[data-piece="workflows"],
326 .pe-root[data-selected="bin"] .pe-piece[data-piece="bin"],
327 .pe-root[data-selected="scripts"] .pe-piece[data-piece="scripts"],
328 .pe-root[data-selected="settings"] .pe-piece[data-piece="settings"],
329 .pe-root[data-selected="mcp"] .pe-piece[data-piece="mcp"],
330 .pe-root[data-selected="lsp"] .pe-piece[data-piece="lsp"] { display: block; }
331 .pe-piece p { margin: 0 0 10px; }
332 .pe-piece p:last-child { margin-bottom: 0; }
333 .pe-piece code { font-family: var(--pe-mono); font-size: 0.88em; padding: 1px 5px; border-radius: 4px; background: var(--pe-surface); border: 1px solid var(--pe-border); }
334 .pe-piece .code-block { margin: 12px 0 0; }
335 .pe-piece pre code { padding: 0; border: none; background: none; }
336 .pe-piece a { color: var(--pe-accent-text); }
337 .pe-line-compact { display: none; }
338 .pe-icon { flex-shrink: 0; }
339 .pe-req { margin-left: 8px; padding: 0 6px; border-radius: 999px; font-size: 11px; line-height: 18px; letter-spacing: .02em; color: var(--pe-accent-text); border: 1px solid var(--pe-border); background: var(--pe-surface); white-space: nowrap; font-weight: 500; vertical-align: middle; }
340 .pe-name { font-size: 22px; font-weight: 600; line-height: 1.25; letter-spacing: -0.2px; color: var(--pe-text); margin: 0; }
341 .pe-path { font-family: var(--pe-mono); font-size: 13.5px; color: var(--pe-accent-text); margin: 4px 0 0; overflow-wrap: anywhere; }
342 .pe-block { margin: 20px 0 0; }
343 .pe-link {
344 display: inline-block; margin: 24px 0 0; padding: 8px 14px; border-radius: 8px;
345 font-size: 14.5px; font-weight: 600; text-decoration: none;
346 color: var(--pe-accent-text); background: var(--pe-accent-bg); border: 1px solid var(--pe-accent);
347 }
348 .pe-link:hover { filter: brightness(0.97); }
349 .pe-link:focus-visible { outline: 2px solid var(--pe-accent); outline-offset: 2px; }
350 @media (max-width: 700px) {
351 .pe-head { padding: 16px 16px 14px; }
352 .pe-body { flex-direction: column; }
353 .pe-tree-pane { width: 100%; border-right: none; border-bottom: 1px solid var(--pe-border); }
354 .pe-line-tree { display: none; }
355 .pe-line-compact { display: flex; }
356 .pe-panel { padding: 16px 16px 20px; }
357 }
358 `}</style>
359
360 <div className="pe-head">
361 <div className="pe-head-text">
362 <div className="pe-title">What goes in a plugin</div>
363 <div className="pe-sub">This example plugin, <code>my-plugin</code>, has one of every kind of component, each in its default location. Select a file or folder to read what it’s for and see what goes in it.</div>
364 </div>
365 <button type="button" className="pe-fs-btn" onClick={toggleFullscreen} aria-label={isFullscreen ? 'Exit fullscreen' : 'Fullscreen'} title={isFullscreen ? 'Exit fullscreen' : 'Fullscreen'}>
366 {isFullscreen ? '⤡' : '⛶'}
367 </button>
368 </div>
369
370 <div className="pe-body">
371 <div className="pe-tree-pane">
372 <div className="pe-caption" id="pe-tree-caption">Plugin directory</div>
373 <div role="group" aria-labelledby="pe-tree-caption" onKeyDown={onTreeKeyDown}>
374 <div className="pe-rootline"><FolderIcon /><span>my-plugin/</span></div>
375 {PIECES.map(p => <button key={p.id} id={'pe-node-' + p.id} type="button" className="pe-node" aria-pressed={p.id === selected.id} aria-label={p.name + ', ' + p.path} onClick={() => setSelectedId(p.id)}>
376 {p.lines.map((line, i) => <span key={i} className="pe-line pe-line-tree" style={{
377 paddingLeft: line.depth * 18 + 'px'
378 }}>
379 {line.kind === 'folder' ? <FolderIcon /> : <FileIcon />}
380 <span>{line.text}</span>
381 {p.required && i === p.lines.length - 1 ? <span className="pe-req">{p.required}</span> : null}
382 </span>)}
383 <span className="pe-line pe-line-compact">
384 <FileIcon />
385 <span>{p.path}</span>
386 {p.required ? <span className="pe-req">{p.required}</span> : null}
387 </span>
388 </button>)}
389 </div>
390 </div>
391
392 <div className="pe-panel" role="region" aria-labelledby="pe-panel-caption" aria-live="polite" aria-atomic="true">
393 <div className="pe-caption" id="pe-panel-caption">Selected piece</div>
394 <div className="pe-name">{selected.name}{selected.required ? <span className="pe-req">{selected.required}</span> : null}</div>
395 <div className="pe-path">{selected.path}</div>
396
397 <div className="pe-block">{children}</div>
398
399 <a className="pe-link" href={selected.href}>{selected.linkText}</a>
400 </div>
401 </div>
402 </div>;
403};
404
405Un plugin Claude Code è costruito da componenti, come skills, agenti, hooks e server MCP. Ogni componente ha una cartella predefinita nel plugin, una chiave manifest opzionale in `.claude-plugin/plugin.json` che sostituisce o aggiunge a quella cartella, e un nome che l'utente vede. Per la tabella dei campi completa di ogni chiave, vedere il [riferimento manifest](/docs/it/plugins/manifest-reference#fields).
406
407Utilizzare questa pagina per aggiungere un componente a un plugin che già carica.
408
409Dopo aver aggiunto un componente, eseguire `/reload-plugins` in una sessione in esecuzione o avviarne una nuova in modo che Claude Code lo carichi. Per controllare il file del componente prima di caricarlo, eseguire [`claude plugin validate .`](/docs/it/plugins/cli-reference#plugin-validate) nella shell dalla directory del plugin.
410
411<Note>
412 Questi casi sono coperti su altre pagine:
413
414 * **Costruire il primo plugin**: iniziare con [Crea un plugin](/docs/it/plugins/create)
415 * **Installare il plugin di qualcun altro**: vedere [Installa plugin](/docs/it/plugins/install)
416 * **Gli utenti del plugin sono su claude.ai o in Cowork**: un set diverso di componenti carica lì. Vedere [Plugin su claude.ai e in Cowork](https://claude.com/docs/plugins/overview)
417</Note>
418
419<h2 id="explore-the-plugin-directory">
420 Esplora la directory dei plugin
421</h2>
422
423L'explorer mostra un plugin di esempio, `my-plugin`, che ha uno di ogni tipo di componente nella sua posizione predefinita:
424
425* Una skill di revisione e un comando `about`
426* Un subagent di security-review
427* Un hook che formatta i file dopo che Claude li modifica, e la cartella `scripts/` che chiama
428* Un monitor di log
429* Uno stile di output e un tema di colore
430* Un workflow route-audit
431* Un eseguibile `hello-plugin`
432* Impostazioni predefinite
433* Un server MCP locale e un language server Go
434
435Ogni file è l'esempio valido più piccolo del suo formato, presente per mostrare la struttura piuttosto che per essere utile: una skill o un agent reale contiene istruzioni complete e spesso file di supporto, e un hook o monitor reale svolge un lavoro reale. Le sezioni dopo l'explorer utilizzano gli stessi file come esempi e collegano a versioni più complete. Seleziona un file o una cartella per leggere a cosa serve, vedere cosa va dentro e trovare la sezione che la copre.
436
437<PluginExplorer>
438 <Piece id="manifest">
439 Il [manifest](/docs/it/plugins/manifest-reference) è il file `plugin.json` nella directory `.claude-plugin/` di un plugin. Contiene i metadati del plugin e i valori `userConfig` che Claude Code richiede all'utente. Solo `name` è obbligatorio. In questo, `description` è il testo che gli utenti vedono per il plugin in `/plugin`, e `version` mantiene gli utenti su quella versione finché non la modifichi:
440
441 ```json theme={null}
442 {
443 "name": "my-plugin",
444 "version": "1.0.0",
445 "description": "Review, formatting, and database tools for this team"
446 }
447 ```
448 </Piece>
449
450 <Piece id="skills">
451 Una [skill](/docs/it/skills) è un file `SKILL.md`. Salva ogni skill nella sua directory sotto `skills/`. Claude legge la `description` di ogni skill, e quando quello che l'utente chiede corrisponde, come chiedere a Claude di revisionare una pull request qui, Claude carica le istruzioni della skill e le segue. L'utente può anche eseguirla direttamente come `/my-plugin:review`:
452
453 ```markdown theme={null}
454 ---
455 description: Reviews a pull request for style and test coverage. Use when asked to review code.
456 ---
457
458 Review the changed files. Report style problems first, then missing tests.
459 ```
460 </Piece>
461
462 <Piece id="commands">
463 Un comando è un singolo file Markdown che l'utente esegue per nome. I comandi sono il formato più vecchio: una skill viene eseguita per nome allo stesso modo e può anche contenere file di supporto nella sua directory, quindi scrivi i nuovi come skill e mantieni `commands/` per i file che hai già. Questo file diventa `/my-plugin:about` e accetta lo stesso frontmatter di una skill:
464
465 ```markdown theme={null}
466 ---
467 description: Summarize the repository
468 ---
469
470 Summarize what this repository does in three sentences.
471 ```
472 </Piece>
473
474 <Piece id="agents">
475 Un [subagent](/docs/it/sub-agents) è un assistente separato, con le sue istruzioni e la sua finestra di contesto, che Claude può delegare un compito e ottenere un risultato. Ogni file Markdown sotto `agents/` ne definisce uno: il frontmatter lo nomina e dice quando usarlo, e il corpo è il suo system prompt. Questo è denominato `my-plugin:security-reviewer`, e l'utente può invocarlo con `@agent-my-plugin:security-reviewer`:
476
477 ```markdown theme={null}
478 ---
479 name: security-reviewer
480 description: Reviews code changes for security issues. Use after edits to authentication or input handling.
481 model: sonnet
482 ---
483
484 You are a security reviewer. Read the changed files and report injection, authentication, and secrets-handling risks.
485 ```
486 </Piece>
487
488 <Piece id="hooks">
489 Un [hook](/docs/it/hooks-guide) esegue qualcosa automaticamente in un punto del ciclo di vita di Claude Code, come dopo ogni modifica di file: un comando shell, una richiesta HTTP, una chiamata a uno strumento MCP, un prompt a un modello, o un subagent. Salva gli hook del plugin in `hooks/hooks.json` alla radice del plugin. Questo esegue lo script `scripts/format.sh` del plugin dopo che Claude scrive o modifica un file:
490
491 ```json theme={null}
492 {
493 "hooks": {
494 "PostToolUse": [
495 {
496 "matcher": "Write|Edit",
497 "hooks": [
498 {
499 "type": "command",
500 "command": "\"${CLAUDE_PLUGIN_ROOT}/scripts/format.sh\""
501 }
502 ]
503 }
504 ]
505 }
506 }
507 ```
508 </Piece>
509
510 <Piece id="monitors">
511 Un monitor è un comando shell che Claude Code avvia in background quando la sessione inizia e continua a eseguire fino a quando non termina, utilizzando lo [strumento Monitor](/docs/it/tools-reference#monitor-tool). Quello che stampa raggiunge Claude come notifiche. Un campo `when` può invece avviarlo la prima volta che una skill denominata viene eseguita. Questo monitora un log di errore:
512
513 ```json theme={null}
514 [
515 {
516 "name": "error-log",
517 "command": "tail -F ./logs/error.log",
518 "description": "Application error log"
519 }
520 ]
521 ```
522 </Piece>
523
524 <Piece id="output-styles">
525 Un plugin può includere [stili di output](/docs/it/output-styles), che cambiano il modo in cui Claude formatta e formula le sue risposte. Salva ogni stile di output come `output-styles/<name>.md`. Questo appare in `/output-style` come `my-plugin:terse`:
526
527 ```markdown theme={null}
528 ---
529 name: terse
530 description: Answer in as few words as possible
531 keep-coding-instructions: true
532 ---
533
534 Keep every reply short. Skip preambles and summaries.
535 ```
536 </Piece>
537
538 <Piece id="themes">
539 Un plugin può includere [temi di colore](/docs/it/terminal-config#create-a-custom-theme) per l'interfaccia di Claude Code. Salva ogni tema come `themes/<slug>.json`. Questo appare in `/theme` come `Dracula`, contrassegnato come da `my-plugin`:
540
541 ```json theme={null}
542 {
543 "name": "Dracula",
544 "base": "dark",
545 "overrides": {
546 "claude": "#bd93f9",
547 "error": "#ff5555"
548 }
549 }
550 ```
551 </Piece>
552
553 <Piece id="workflows">
554 La cartella `workflows/` contiene file [workflow](/docs/it/workflows) `.js`: un blocco `meta`, quindi un corpo di script che orchestra diversi subagent. Questo viene eseguito come `/my-plugin:audit-routes`:
555
556 ```javascript theme={null}
557 export const meta = {
558 name: 'audit-routes',
559 description: 'Audit every route handler for missing auth checks',
560 }
561
562 const found = await agent('List every .ts file under src/routes/.', {
563 schema: { type: 'object', required: ['files'], properties: { files: { type: 'array', items: { type: 'string' } } } },
564 })
565
566 const audits = await pipeline(found.files, file =>
567 agent(`Audit ${file} for missing authentication checks.`, { label: file }),
568 )
569
570 return audits.filter(Boolean)
571 ```
572 </Piece>
573
574 <Piece id="bin">
575 `bin/` è il modo in cui un plugin fornisce uno strumento da riga di comando. Mentre il plugin è abilitato, Claude Code mette questa cartella sul `PATH` della shell in cui esegue i comandi, quindi Claude, o le istruzioni di una skill, possono eseguire lo strumento per nome senza che l'utente installi nulla. Con questo [eseguibile](#executables) in posizione, `hello-plugin` è un comando che Claude può eseguire:
576
577 ```bash theme={null}
578 #!/bin/bash
579 echo "hello from my-plugin"
580 ```
581 </Piece>
582
583 <Piece id="scripts">
584 L'hook in `hooks/hooks.json` esegue uno script, e questa cartella è dove l'esempio lo mantiene. Il nome `scripts/` è una convenzione, non qualcosa che Claude Code cerca: l'hook punta al file dal suo percorso, `${CLAUDE_PLUGIN_ROOT}/scripts/format.sh`. Uno script di formattazione potrebbe assomigliare a questo:
585
586 ```bash theme={null}
587 #!/bin/bash
588 npx prettier --write .
589 ```
590 </Piece>
591
592 <Piece id="settings">
593 Un `settings.json` alla radice del plugin contiene [impostazioni](/docs/it/settings-reference) che si applicano mentre il plugin è abilitato, quindi un plugin può cambiare il comportamento della sessione e non solo aggiungere componenti. Solo due chiavi hanno effetto da un plugin, [`agent`](/docs/it/settings-reference#agent) e [`subagentStatusLine`](/docs/it/settings-reference#subagentstatusline); ogni altra chiave viene scartata. Vedi [Impostazioni predefinite](#default-settings).
594
595 Questo imposta `agent`, che esegue il thread principale della sessione come l'agent `security-reviewer` del plugin, quindi il system prompt di quell'agent, le restrizioni degli strumenti e il modello si applicano all'intera sessione:
596
597 ```json theme={null}
598 {
599 "agent": "security-reviewer"
600 }
601 ```
602 </Piece>
603
604 <Piece id="mcp">
605 Un [server MCP](/docs/it/mcp) fornisce a Claude strumenti da un sistema esterno. Dichiaralo in `.mcp.json` alla radice del plugin. Questo avvia un server locale da uno script all'interno del plugin e appare in `/mcp` come `plugin:my-plugin:db`:
606
607 ```json theme={null}
608 {
609 "mcpServers": {
610 "db": {
611 "command": "node",
612 "args": ["${CLAUDE_PLUGIN_ROOT}/server.js"]
613 }
614 }
615 }
616 ```
617 </Piece>
618
619 <Piece id="lsp">
620 Un server LSP fornisce a Claude [diagnostica e navigazione del codice](/docs/it/plugins/code-intelligence) per un linguaggio. Dichiara il server in `.lsp.json` alla radice del plugin. Questo connette il language server Go per i file `.go`:
621
622 ```json theme={null}
623 {
624 "gopls": {
625 "command": "gopls",
626 "args": ["serve"],
627 "extensionToLanguage": {
628 ".go": "go"
629 }
630 }
631 }
632 ```
633 </Piece>
634</PluginExplorer>
635
636<h2 id="add-each-kind-of-component">
637 Aggiungi ogni tipo di componente
638</h2>
639
640Ogni sezione di seguito copre un tipo di componente: dove i suoi file vanno nel plugin, un esempio che convalida, cosa vede l'utente una volta che il plugin carica, e la chiave manifest che cambia la posizione predefinita. Aggiungere quelli di cui il plugin ha bisogno; nessuno è obbligatorio.
641
642<h3 id="skills">
643 Skills
644</h3>
645
646Una [skill](/docs/it/skills) è un file `SKILL.md` che Claude può caricare quando la sua descrizione corrisponde al compito. L'utente può anche eseguirla come comando. Salvare ogni skill nella sua directory sotto `skills/`:
647
648```text theme={null}
649my-plugin/
650├── .claude-plugin/
651│ └── plugin.json
652└── skills/
653 └── review/
654 └── SKILL.md
655```
656
657Dare al `SKILL.md` una `description` in modo che Claude sappia quando usarla:
658
659```markdown skills/review/SKILL.md theme={null}
660---
661description: Reviews a pull request for style and test coverage. Use when asked to review code.
662---
663
664Review the changed files. Report style problems first, then missing tests.
665```
666
667Dopo aver caricato il plugin, `/my-plugin:review` esegue la skill. Il nome del comando e chi può invocarlo seguono queste regole:
668
669* **Nome del comando**: `/<plugin>:<directory>`, quindi `skills/review/SKILL.md` in `my-plugin` è `/my-plugin:review`. Se imposti `name` nel frontmatter, sostituisce l'ultimo segmento e il prefisso del plugin rimane. Vedere [come una skill ottiene il suo nome di comando](/docs/it/skills#how-a-skill-gets-its-command-name)
670* **Chi la invoca**: Claude, l'utente o entrambi, controllato dal frontmatter. Vedere [Controlla chi invoca una skill](/docs/it/skills#control-who-invokes-a-skill)
671
672Puoi anche posizionare le skills al di fuori della directory predefinita `skills/`:
673
674* **Directory aggiuntive**: elencale nella chiave manifest `skills`. Aggiungono alla scansione predefinita `skills/` piuttosto che sostituirla, a differenza di `commands` e `agents`
675* **Una singola skill alla radice del plugin**: senza directory `skills/` e senza chiave manifest `skills`, un `SKILL.md` alla radice del plugin carica come una skill. Imposta `name` nel suo frontmatter, perché altrimenti un'installazione del marketplace nomina la skill dopo la sua [directory cache](/docs/it/plugins/loading#find-plugins-on-disk) piuttosto che il tuo plugin
676
677Per includere istruzioni in un plugin, scrivile come una skill. Claude Code non carica un `CLAUDE.md` alla radice del plugin, e `claude plugin validate` avverte `CLAUDE.md at the plugin root is not loaded as project context`.
678
679Per i campi frontmatter e i file di supporto, vedere [Skills](/docs/it/skills).
680
681<h3 id="commands">
682 Comandi
683</h3>
684
685Un comando è un singolo file Markdown che l'utente esegue per nome, come `/my-plugin:about`.
686
687<Note>
688 I comandi sono il formato più vecchio, e le [skills](#skills) li superano per il nuovo lavoro. Una skill viene eseguita per nome allo stesso modo, e può anche portare file di supporto nella sua directory. Mantenere `commands/` per i file che stai spostando da `.claude/commands/`.
689</Note>
690
691Salvare un comando in `commands/<file>.md` e diventa `/<plugin>:<file>`. Una sottodirectory aggiunge un segmento, quindi `commands/db/migrate.md` è `/my-plugin:db:migrate`.
692
693I file di comando accettano lo stesso frontmatter delle skills.
694
695<h4 id="define-commands-in-the-manifest">
696 Definisci comandi nel manifest
697</h4>
698
699Hai bisogno di questo solo se vuoi mantenere i file di comando da qualche parte diversa da `commands/`, o per definire un comando breve all'interno di `plugin.json` senza un file Markdown separato. Imposta la chiave manifest `commands`, e Claude Code la legge invece di scansionare `commands/`. La chiave accetta un percorso, un array di percorsi, o un oggetto che mappa ogni nome di comando a un file `source` o a `content` inline.
700
701Questo manifest definisce `/my-plugin:about` inline, senza file Markdown:
702
703```json .claude-plugin/plugin.json theme={null}
704{
705 "name": "my-plugin",
706 "commands": {
707 "about": {
708 "content": "Summarize what this repository does in three sentences.",
709 "description": "Summarize the repository"
710 }
711 }
712}
713```
714
715Carica il plugin ed esegui `/my-plugin:about` nella sessione per confermare che ha caricato.
716
717Per la sintassi completa della chiave, vedere [`commands`](/docs/it/plugins/manifest-reference#commands).
718
719<h3 id="agents">
720 Agenti
721</h3>
722
723Un [subagente](/docs/it/sub-agents) è un assistente separato, con le sue istruzioni e finestra di contesto, che Claude può delegare a un compito. Ogni file Markdown sotto `agents/` ne definisce uno:
724
725```markdown agents/security-reviewer.md theme={null}
726---
727name: security-reviewer
728description: Reviews code changes for security issues. Use after edits to authentication or input handling.
729model: sonnet
730---
731
732You are a security reviewer. Read the changed files and report injection, authentication, and secrets-handling risks.
733```
734
735Questo agente è denominato `my-plugin:security-reviewer`, e l'utente può [invocarlo esplicitamente](/docs/it/sub-agents#invoke-subagents-explicitly) con `@agent-my-plugin:security-reviewer`. La forma del nome è `<plugin>:<name>`, dove `<name>` viene dal frontmatter, o dal nome del file quando non c'è.
736
737La chiave manifest `agents` sostituisce la scansione `agents/`.
738
739<h4 id="organize-agents-in-subfolders">
740 Organizza agenti in sottocartelle
741</h4>
742
743Puoi mettere i file dell'agente del plugin in sottocartelle di `agents/`. Claude Code [li carica ricorsivamente](/docs/it/sub-agents#choose-the-subagent-scope) e unisce il nome del plugin, ogni nome di sottocartella e il nome del file con due punti per formare il nome con ambito dell'agente. Ad esempio, `agents/review/security.md` in un plugin denominato `my-plugin` carica come `my-plugin:review:security`. Due impostazioni cambiano quel nome:
744
745* Frontmatter `name`: sostituisce solo il nome del file, quindi `name: audit` in `agents/review/security.md` carica come `my-plugin:review:audit`
746* Campo manifest [`agents`](/docs/it/plugins/manifest-reference#fields): un file che elenchi lì carica senza nomi di sottocartella, quindi `"agents": "./custom/review/security.md"` carica come `my-plugin:security`
747
748<h4 id="frontmatter-fields-in-plugin-agents">
749 Campi frontmatter negli agenti del plugin
750</h4>
751
752Il frontmatter di un agente del plugin segue queste regole:
753
754* **Campi supportati**: `name`, `description`, `model`, `effort`, `maxTurns`, `tools`, `disallowedTools`, `skills`, `memory`, `background`, `omitClaudeMd`, `isolation`, `color`, e la chiave `cacheTtl` di `experimental`. L'unico valore `isolation` valido è `"worktree"`. Vedere [campi frontmatter supportati](/docs/it/sub-agents#supported-frontmatter-fields) per quello che fa ciascuno
755* **Campi ignorati**: `permissionMode`, `hooks`, `mcpServers`, e `initialPrompt`. Un file agente non può aggiungere hook o server MCP da solo, quindi aggiungili come plugin [hooks](#hooks) e [server MCP](#mcp-servers) invece
756* **Frontmatter che non analizza**: l'agente carica comunque con ogni campo ignorato. È denominato dopo il file, e la sua descrizione legge `Agent from my-plugin plugin`. Esegui [`claude plugin validate`](/docs/it/plugins/cli-reference#plugin-validate) nella shell per trovare questi file
757
758Per quello che fa ogni campo e le regole di precedenza, vedere [Subagenti](/docs/it/sub-agents#supported-frontmatter-fields).
759
760<h3 id="hooks">
761 Hooks
762</h3>
763
764Un [hook](/docs/it/hooks-guide) esegue qualcosa automaticamente in un punto del ciclo di vita di Claude Code, come dopo ogni modifica di file: un comando shell, una richiesta HTTP, una chiamata a uno strumento MCP, un prompt a un modello, o un subagente. Salvare gli hook del plugin in `hooks/hooks.json` alla radice del plugin, sotto una chiave `"hooks"` di livello superiore, nella stessa forma dell'oggetto `hooks` in `settings.json`. Questo ti permette di copiare un hook di impostazioni esistente senza modifiche.
765
766Questo hook esegue uno script in bundle dopo ogni `Write` o `Edit`:
767
768```json hooks/hooks.json theme={null}
769{
770 "hooks": {
771 "PostToolUse": [
772 {
773 "matcher": "Write|Edit",
774 "hooks": [
775 {
776 "type": "command",
777 "command": "\"${CLAUDE_PLUGIN_ROOT}/scripts/format.sh\""
778 }
779 ]
780 }
781 ]
782 }
783}
784```
785
786Salvare lo script in `scripts/format.sh` e renderlo eseguibile.
787
788Carica il plugin e chiedi a Claude di modificare un file. Un hook `PostToolUse` che esce con 0 non mostra nulla nella trascrizione, quindi conferma che è stato eseguito con [debug logging](/docs/it/hooks#debug-hooks) o da quello che lo script stesso cambia.
789
790Gli hook in `hooks/hooks.json` e nella chiave manifest `hooks` caricano entrambi. Per ogni evento e il suo payload, vedere [Hook events](/docs/it/hooks#hook-events).
791
792<h4 id="when-plugin-hooks-fire">
793 Quando gli hook del plugin si attivano
794</h4>
795
796Gli hook di un plugin non aspettano che una delle skill o dei comandi del plugin venga utilizzata. Claude Code li registra quando una sessione carica il plugin, e si attivano sui loro eventi da allora in poi. Per limitare quando un hook viene eseguito, restringere il suo `matcher`.
797
798Se un hook non si attiva mai, vedere [hook che non si attivano](/docs/it/plugins/troubleshooting#failed-to-load-hooks-from-and-hooks-that-dont-fire).
799
800<h4 id="environment-quoting-and-matching-mcp-tools">
801 Ambiente, quoting e corrispondenza degli strumenti MCP
802</h4>
803
804L'ambiente dell'hook, il quoting di `${CLAUDE_PLUGIN_ROOT}`, e i matcher per gli strumenti MCP del plugin funzionano come segue:
805
806* **Ambiente**: ogni processo hook riceve `CLAUDE_PLUGIN_ROOT` e `CLAUDE_PLUGIN_DATA` nel suo ambiente, più `CLAUDE_PLUGIN_OPTION_<KEY>` per ogni valore di [configurazione utente](#user-configuration), in modo che lo script possa leggerli da lì
807* **Quoting**: quando `command` non ha `args`, viene eseguito attraverso una shell, quindi avvolgi il percorso `${CLAUDE_PLUGIN_ROOT}` tra virgolette doppie, come fa l'esempio `hooks/hooks.json` sotto [Hooks](#hooks), per mantenere il percorso espanso una parola shell. Quando passi `args` invece, ogni elemento viene passato come un argomento senza shell e non ha bisogno di quoting. Vedere [exec form e shell form](/docs/it/hooks#exec-form-and-shell-form)
808* **Corrispondenza degli strumenti MCP del plugin**: uno strumento da un [server MCP che questo plugin dichiara](#mcp-servers) è denominato `mcp__plugin_<plugin>_<server>__<tool>`, quindi scrivi quel nome completo nel matcher. Un matcher sul solo nome del server non si attiva mai. Vedere [Match MCP tools](/docs/it/hooks#match-mcp-tools)
809
810<h3 id="mcp-servers">
811 Server MCP
812</h3>
813
814Un server MCP fornisce a Claude strumenti da un sistema esterno. Dichiararlo in `.mcp.json` alla radice del plugin, nella stessa forma di un [`.mcp.json` di progetto](/docs/it/mcp#project-scope). Questo `.mcp.json` dichiara un server denominato `db`:
815
816```json .mcp.json theme={null}
817{
818 "mcpServers": {
819 "db": {
820 "command": "node",
821 "args": ["${CLAUDE_PLUGIN_ROOT}/server.js"]
822 }
823 }
824}
825```
826
827Puoi anche omettere il wrapper `mcpServers` e mettere `db` al livello superiore del file.
828
829Carica il plugin ed esegui `/mcp` per confermare che il server appare come `plugin:my-plugin:db`.
830
831`claude plugin validate` controlla `.mcp.json` e segnala una voce di server che Claude Code eliminerebbe al momento del caricamento come errore. Richiede Claude Code v2.1.281 o successivo.
832
833Per dove una voce errata appare al momento del caricamento, vedere [Server MCP che non si avviano](/docs/it/plugins/troubleshooting#invalid-mcp-server-config-for-and-mcp-servers-that-dont-start).
834
835La chiave manifest `mcpServers` accetta una mappa di server inline, un percorso a un file JSON, o un array di quelli. Quando un server manifest ha lo stesso nome di uno in `.mcp.json`, il server manifest lo sostituisce.
836
837<h4 id="reach-users-on-claude-ai-and-cowork">
838 Raggiungi gli utenti su claude.ai e Cowork
839</h4>
840
841Un server stdio locale, come il server `db` sotto [Server MCP](#mcp-servers), viene eseguito in Claude Code e in una sessione Cowork che viene eseguita sulla tua macchina nell'app Claude Desktop, ma non su claude.ai. Per raggiungerli anche lì, fai riferimento a un server remoto dal suo URL `https://`, che claude.ai e Cowork offrono all'utente come connettore.
842
843<h4 id="server-names-tool-names-and-reloads">
844 Nomi dei server, nomi degli strumenti e ricaricamenti
845</h4>
846
847I nomi del server, la sostituzione delle variabili e il comportamento di ricaricamento seguono queste regole:
848
849* **Nome del server**: `plugin:<plugin>:<server>`, quindi il server `db` in `my-plugin` è `plugin:my-plugin:db` in `/mcp`. Usa la stessa forma per nominare il server in un [hook `mcp_tool`](/docs/it/hooks#mcp-tool-hook-fields)
850* **Nomi degli strumenti**: `mcp__plugin_<plugin>_<server>__<tool>`, quindi uno strumento `query` su quel server `db` è `mcp__plugin_my-plugin_db__query`. Questo è il nome da usare in [regole di permesso](/docs/it/permissions) e [matcher di hook](#hooks)
851* **Sostituzione**: `${CLAUDE_PLUGIN_ROOT}` e le altre [variabili di percorso](#path-variables-and-persistent-data) vengono sostituite in `command`, `args`, e `env`. Non è necessario quoting in `args`, perché ogni elemento viene passato come un argomento
852* **Ricaricamento**: quando l'utente esegue `/reload-plugins` e [il ricaricamento si applica](/docs/it/plugins/cli-reference#reloads-that-change-mcp-tools), un server la cui configurazione è invariata mantiene la sua connessione. Un server la cui configurazione è cambiata si riconnette, e uno che hai rimosso si disconnette
853
854<h4 id="include-a-packaged-mcpb-server">
855 Includi un server MCPB in pacchetto
856</h4>
857
858La chiave `mcpServers` accetta anche un server in pacchetto come file [MCPB](https://github.com/modelcontextprotocol/mcpb), la cui estensione è `.mcpb` o la più vecchia `.dxt`. Punta la chiave al file, come percorso all'interno del plugin o un URL `https://`:
859
860```json .claude-plugin/plugin.json theme={null}
861{
862 "name": "my-plugin",
863 "mcpServers": "./servers/db.mcpb"
864}
865```
866
867Il server prende il suo nome da `name` nel manifest del bundle.
868
869Per trasporti e autenticazione, vedere [MCP](/docs/it/mcp#plugin-provided-mcp-servers).
870
871<h3 id="lsp-servers">
872 Server LSP
873</h3>
874
875Un server LSP fornisce a Claude diagnostica e navigazione del codice per un linguaggio. Se un [plugin ufficiale di code intelligence](/docs/it/plugins/code-intelligence) copre già il tuo linguaggio, installa quello invece di scriverne uno. Altrimenti dichiara il server in `.lsp.json` alla radice del plugin:
876
877```json .lsp.json theme={null}
878{
879 "gopls": {
880 "command": "gopls",
881 "args": ["serve"],
882 "extensionToLanguage": {
883 ".go": "go"
884 }
885 }
886}
887```
888
889Il file mappa ogni nome di server direttamente alla sua configurazione, senza oggetto wrapper attorno alla mappa. `command` è il nome del binario, con i suoi argomenti in `args`. `extensionToLanguage` ha bisogno di almeno un'estensione, ognuna che inizia con `.`.
890
891`claude plugin validate` non legge questo file. Quando una voce è non valida, l'intero file viene saltato al caricamento e `Invalid LSP server config for ".lsp.json"` appare nella scheda **Errors** di `/plugin`.
892
893Il tuo plugin configura la connessione ma non installa il binario del server, e ogni estensione di file ottiene un server:
894
895* **Binario mancante**: Claude Code avvia `command` per nome dal `PATH` dell'utente. Quando il binario non è lì, il server non si avvia e `claude --debug` registra `LSP server <name> failed to start`
896* **Conflitti di estensione**: quando due server abilitati rivendicano la stessa estensione, il primo registrato gestisce quei file e l'altro non viene utilizzato per loro, che i server provengano da un plugin o da due. La scheda **Errors** di `/plugin` mostra l'avviso `LSP server "<name>" is not used for <ext> files`
897
898La chiave manifest `lspServers` accetta la stessa mappa inline, un percorso a un file JSON, o un array di quelli, e i suoi server si aggiungono a quelli in `.lsp.json`. Quando un server manifest ha lo stesso nome di uno in `.lsp.json`, il server manifest lo sostituisce.
899
900Per `transport`, timeout, riavvii e gli altri campi, vedere [`lspServers`](/docs/it/plugins/manifest-reference#lspservers).
901
902Invia l'output del log a stderr, non a stdout. Claude Code legge stdout di un server solo come messaggi di protocollo, e accetta intestazioni di messaggi fino a 64 KiB e un corpo di messaggio fino a 32 MiB.
903
904Claude Code disconnette un server che supera uno dei due limiti o scrive output non-protocollo a stdout, e conta la disconnessione come un crash per `restartOnCrash` e `maxRestarts`. Quando esegui con `--debug`, Claude Code scrive un errore che nomina la causa al log di debug.
905
906<h3 id="executables">
907 Eseguibili
908</h3>
909
910I file in `bin/` alla radice del plugin sono su `PATH` della shell dello strumento Bash mentre il plugin è abilitato, quindi Claude può eseguirli come comandi nudi. Aggiungi uno script eseguibile:
911
912```bash bin/hello-plugin theme={null}
913#!/bin/bash
914echo "hello from my-plugin"
915```
916
917Rendilo eseguibile con `chmod +x bin/hello-plugin` e carica il plugin. Quando chiedi a Claude di eseguire `hello-plugin`, il risultato dello strumento Bash mostra l'output dello script.
918
919Le directory `bin/` del plugin vengono dopo le voci `PATH` dell'utente, quindi un plugin non può oscurare `git`, `ls`, o un altro comando di sistema.
920
921claude.ai e Cowork non installano un plugin che ha una directory `bin/` di livello superiore, incluso uno che [distribuisci attraverso le impostazioni dell'organizzazione claude.ai](/docs/it/plugins/host-marketplace#distribute-through-organization-settings).
922
923<h3 id="default-settings">
924 Impostazioni predefinite
925</h3>
926
927Per impostare i valori predefiniti che si applicano mentre il plugin è abilitato, aggiungi un `settings.json` alla radice del plugin, o metti lo stesso oggetto inline nella chiave manifest `settings`. Due chiavi hanno effetto, `agent` e `subagentStatusLine`, e ogni altra chiave viene eliminata.
928
929Imposta `agent` per eseguire uno dei propri agenti del plugin come thread principale:
930
931```json settings.json theme={null}
932{
933 "agent": "security-reviewer"
934}
935```
936
937Carica il plugin e avvia una sessione. Claude quindi risponde nella conversazione principale con il prompt di sistema e il modello dell'agente `security-reviewer`.
938
939Per tutto quello che la chiave controlla, vedere l'[impostazione `agent`](/docs/it/settings-reference#agent).
940
941Quando la stessa chiave è impostata in più di un posto, queste regole decidono quale valore si applica:
942
943* **File su manifest**: quando entrambi esistono e `settings.json` imposta almeno una chiave supportata, `settings.json` si applica e il `settings` del manifest viene ignorato
944* **Impostazioni utente su valori predefiniti del plugin**: tra le fonti di impostazioni, i valori predefiniti del plugin sono il livello più basso, quindi un `agent` proprio dell'utente in `~/.claude/settings.json` sostituisce il tuo
945* **Due plugin impostano la stessa chiave**: il valore dal plugin caricato per ultimo si applica, e `claude --debug` registra `overrides setting`
946
947Per la forma `subagentStatusLine`, vedere [linee di stato del subagente](/docs/it/statusline#subagent-status-lines).
948
949<h3 id="themes-and-output-styles">
950 Temi e stili di output
951</h3>
952
953Un plugin può includere temi di colore e stili di output. Entrambi appaiono negli stessi picker dei propri dell'utente. Per uno qualsiasi, impostare la chiave manifest sostituisce la scansione della cartella.
954
955| Componente | Salva come | Formato | Appare in | Chiave manifest |
956| :-------------- | :------------------------ | :---------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------- | :-------------------- |
957| Tema | `themes/<slug>.json` | Il formato [file tema personalizzato](/docs/it/terminal-config#create-a-custom-theme) che gli utenti scrivono in `~/.claude/themes/` | `/theme`, sotto il `name` del file | `experimental.themes` |
958| Stile di output | `output-styles/<name>.md` | Il formato [stile di output personalizzato](/docs/it/output-styles#create-a-custom-output-style), con frontmatter `name` e `description` | `/output-style`, come `<plugin>:<name>` | `outputStyles` |
959
960I temi del plugin sono di sola lettura, quindi quando un utente ne modifica uno in `/theme`, la modifica viene salvata come copia nella sua directory di temi.
961
962Questo tema ricolora il prompt di accento e il testo di errore sul preset scuro:
963
964```json themes/dracula.json theme={null}
965{
966 "name": "Dracula",
967 "base": "dark",
968 "overrides": {
969 "claude": "#bd93f9",
970 "error": "#ff5555"
971 }
972}
973```
974
975<h3 id="channels">
976 Canali
977</h3>
978
979Un [canale](/docs/it/channels) consente a un sistema esterno come un'app di chat di inviare messaggi in una sessione. In un plugin, un canale è uno dei server MCP più una voce `channels` che si lega ad esso e può richiedere la sua configurazione. Questo manifest lega un canale a un server `telegram` e chiede un token bot:
980
981```json .claude-plugin/plugin.json theme={null}
982{
983 "name": "my-plugin",
984 "mcpServers": {
985 "telegram": {
986 "command": "node",
987 "args": ["${CLAUDE_PLUGIN_ROOT}/server.js"],
988 "env": { "BOT_TOKEN": "${user_config.bot_token}" }
989 }
990 },
991 "channels": [
992 {
993 "server": "telegram",
994 "userConfig": {
995 "bot_token": {
996 "type": "string",
997 "title": "Bot token",
998 "description": "Telegram bot token",
999 "sensitive": true
1000 }
1001 }
1002 }
1003 ]
1004}
1005```
1006
1007`server` deve corrispondere a una chiave in `mcpServers`. Il `userConfig` per canale accetta la stessa forma della chiave [`userConfig`](#user-configuration) di livello superiore.
1008
1009Per quello che il server deve implementare e come gli utenti abilitano un plugin di canale, vedere [Pacchetto come plugin](/docs/it/channels-reference#package-as-a-plugin) nel riferimento dei canali. Per la tabella dei campi, vedere [`channels`](/docs/it/plugins/manifest-reference#channels).
1010
1011<h3 id="monitors">
1012 Monitor
1013</h3>
1014
1015Un monitor è un comando shell che viene eseguito in background per l'intera sessione. Quello che stampa raggiunge Claude come notifiche, quindi Claude può reagire a un log o a un cambio di stato senza essere chiesto di guardarlo. Salvare le voci in `monitors/monitors.json`:
1016
1017```json monitors/monitors.json theme={null}
1018[
1019 {
1020 "name": "error-log",
1021 "command": "tail -F ./logs/error.log",
1022 "description": "Application error log"
1023 }
1024]
1025```
1026
1027Il comando viene eseguito in una shell, nella directory di lavoro in cui la sessione è stata avviata.
1028
1029Il comando di un monitor è limitato in dove inizia e cosa può fare riferimento:
1030
1031* **Solo sessioni interattive**: i monitor del plugin si avviano in una sessione interattiva e mai in modalità non interattiva con il flag `-p`. Si avviano anche solo dove lo [strumento Monitor](/docs/it/tools-reference#monitor-tool) è disponibile
1032* **Nessuna configurazione utente**: `command` ottiene le [variabili di percorso](#path-variables-and-persistent-data) e `${ENV_VAR}` dall'ambiente, ma mai `${user_config.*}`. Un monitor che fa riferimento a uno non si avvia, e i processi monitor non ricevono nemmeno `CLAUDE_PLUGIN_OPTION_<KEY>`
1033* **Disabilitazione a metà sessione**: se disabiliti un plugin a metà sessione, Claude Code non ferma i monitor che sono già in esecuzione. Si fermano quando la sessione finisce
1034
1035La chiave manifest `experimental.monitors` accetta lo stesso array inline o un percorso a un file JSON, e viene letta invece di `monitors/monitors.json`.
1036
1037Per il trigger `when` e gli altri campi, vedere [`monitors`](/docs/it/plugins/manifest-reference#monitors).
1038
1039<h2 id="user-configuration">
1040 Chiedi all'utente i valori di configurazione
1041</h2>
1042
1043Dichiara i valori di cui il tuo plugin ha bisogno dall'utente nella chiave manifest `userConfig`, in modo che gli utenti non modifichino `settings.json` da soli. Ogni opzione appare in una finestra di dialogo con il suo `title` come etichetta e la sua `description` sotto.
1044
1045Imposta `"sensitive": true` per un token o una password. La finestra di dialogo quindi maschera l'input, e il valore viene archiviato in archiviazione sicura piuttosto che in `settings.json`.
1046
1047Questo manifest chiede un endpoint e un token:
1048
1049```json .claude-plugin/plugin.json theme={null}
1050{
1051 "name": "my-plugin",
1052 "userConfig": {
1053 "api_url": {
1054 "type": "string",
1055 "title": "API URL",
1056 "description": "Base URL of your team's API"
1057 },
1058 "api_token": {
1059 "type": "string",
1060 "title": "API token",
1061 "description": "Token for your team's API",
1062 "sensitive": true
1063 }
1064 }
1065}
1066```
1067
1068<h3 id="when-the-configuration-dialog-appears">
1069 Quando appare la finestra di dialogo di configurazione
1070</h3>
1071
1072La finestra di dialogo appare solo nell'interfaccia interattiva `/plugin`. Si apre per qualsiasi opzione che non è ancora impostata quando l'utente fa uno dei seguenti:
1073
1074* Installa il plugin in `/plugin`
1075* Esegui `/plugin install <plugin>@<marketplace>` all'interno di una sessione
1076* Abilita il plugin dalla scheda **Installed** in `/plugin`
1077
1078Per aprire la stessa finestra di dialogo in qualsiasi momento, l'utente esegue `/plugin configure <plugin>@<marketplace>`.
1079
1080Il comando shell `claude plugin install` non richiede mai i valori `userConfig`. Per impostare i valori dalla shell, passa ognuno come `--config KEY=VALUE`. Quando le opzioni rimangono non impostate, il comando stampa una riga `userConfig options not yet set` che nomina entrambi i modi per impostarli. [La finestra di dialogo `userConfig` non appare mai](/docs/it/plugins/troubleshooting#the-userconfig-dialog-never-appears) cita la riga.
1081
1082Per i campi dell'opzione, dove ogni valore viene archiviato, come un componente fa riferimento a un valore salvato, e quali campi rifiutano `${user_config.*}`, vedere [Configurazione utente](/docs/it/plugins/manifest-reference#user-configuration).
1083
1084<h2 id="path-variables-and-persistent-data">
1085 Fai riferimento ai percorsi del plugin e archivia i dati
1086</h2>
1087
1088Non sai dove il tuo plugin verrà installato, quindi fai riferimento ai suoi file e dati attraverso queste variabili piuttosto che percorsi fissi. Vengono sostituite nel contenuto di skill, comando e agente, nei comandi di hook e monitor, e nelle configurazioni di server MCP e LSP. Vengono anche esportate ai processi hook, MCP e LSP:
1089
1090* **`${CLAUDE_PLUGIN_ROOT}`**: la directory di installazione del plugin. Ogni versione ha la sua [directory cache](/docs/it/plugins/loading#find-plugins-on-disk), quindi il percorso cambia quando il plugin si aggiorna. Non scrivere stato lì
1091* **`${CLAUDE_PLUGIN_DATA}`**: una directory che sopravvive agli aggiornamenti, per `node_modules`, ambienti virtuali e cache. Si risolve in `~/.claude/plugins/data/<id>/` e viene creata quando viene referenziata per la prima volta
1092* **`${CLAUDE_PROJECT_DIR}`**: la radice del progetto, lo stesso valore che gli hook ricevono
1093
1094Nel percorso della directory dei dati, `<id>` è l'identificatore del plugin con ogni carattere diverso da lettere, cifre, `_`, e `-` sostituito da `-`, quindi `my-plugin@my-marketplace` diventa `my-plugin-my-marketplace`.
1095
1096Su Windows, i percorsi sostituiti utilizzano barre in avanti in modo che una shell non legga le barre rovesciate come escape.
1097
1098<h3 id="install-dependencies-into-the-data-directory">
1099 Installa le dipendenze nella directory dei dati
1100</h3>
1101
1102Per un plugin installato dal marketplace, Claude Code installa automaticamente le [dipendenze di pacchetti Node.js](/docs/it/plugins/loading#node-js-package-dependencies) idonee quando memorizza il plugin nella cache, quindi potresti non aver bisogno di installarle tu stesso. Quando lo fai, questo hook `SessionStart` installa `node_modules` in `${CLAUDE_PLUGIN_DATA}` alla prima esecuzione e di nuovo dopo che un aggiornamento cambia `package.json`:
1103
1104```json hooks/hooks.json theme={null}
1105{
1106 "hooks": {
1107 "SessionStart": [
1108 {
1109 "hooks": [
1110 {
1111 "type": "command",
1112 "command": "diff -q \"${CLAUDE_PLUGIN_ROOT}/package.json\" \"${CLAUDE_PLUGIN_DATA}/package.json\" >/dev/null 2>&1 || (cd \"${CLAUDE_PLUGIN_DATA}\" && cp \"${CLAUDE_PLUGIN_ROOT}/package.json\" . && npm install) || rm -f \"${CLAUDE_PLUGIN_DATA}/package.json\""
1113 }
1114 ]
1115 }
1116 ]
1117 }
1118}
1119```
1120
1121Dopo la prima sessione, `~/.claude/plugins/data/<id>/node_modules` esiste. Un server MCP può quindi impostare `NODE_PATH` a `${CLAUDE_PLUGIN_DATA}/node_modules` nel suo `env`. Per quali campi sostituiscono quale variabile, vedere [Variabili di ambiente](/docs/it/plugins/manifest-reference#environment-variables).
1122
1123<h2 id="next-steps">
1124 Passaggi successivi
1125</h2>
1126
1127* [Riferimento manifest del plugin](/docs/it/plugins/manifest-reference): campi `plugin.json`, regole di percorso e layout standard
1128* [Testa i plugin con evals](/docs/it/plugin-evals): controlla che i componenti che hai aggiunto cambino il comportamento di Claude nel modo che intendi
1129* [Pubblica e distribuisci un plugin](/docs/it/plugins/publish): versiona il plugin e mettilo in un marketplace
1130* [Risolvi i problemi dei plugin](/docs/it/plugins/troubleshooting): cosa fare quando un componente non carica o un hook non si attiva