Hook Development for Claude Code Plugins
anthropics/claude-plugins-official
Explains how to write Claude Code plugin hooks, both prompt-based checks and bash commands, for events such as PreToolUse, Stop and SessionStart.
Guide for creating Kit extensions. An agent skill from mark3labs/kit.
$ npx skills add mark3labs/kit --skill kit-extensions -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install mark3labs/kit kit-extensions --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/mark3labs/kit.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/kit-extensions .claude/skills/kit-extensions && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "kit-extensions" agent skill from https://github.com/mark3labs/kit/tree/master/skills/kit-extensions into .claude/skills/kit-extensions/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "kit-extensions", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/mark3labs/kit/tree/master/skills/kit-extensionsType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add mark3labs/kit --skill kit-extensions -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install mark3labs/kit kit-extensions --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/mark3labs/kit.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/kit-extensions .agents/skills/kit-extensions && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "kit-extensions" agent skill from https://github.com/mark3labs/kit/tree/master/skills/kit-extensions into .agents/skills/kit-extensions/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "kit-extensions", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add mark3labs/kit --skill kit-extensions -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install mark3labs/kit kit-extensions --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/mark3labs/kit.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/kit-extensions .cursor/skills/kit-extensions && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "kit-extensions" agent skill from https://github.com/mark3labs/kit/tree/master/skills/kit-extensions into .cursor/skills/kit-extensions/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "kit-extensions", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/mark3labs/kit.git --path skills/kit-extensions--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add mark3labs/kit --skill kit-extensions -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install mark3labs/kit kit-extensions --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/mark3labs/kit.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/kit-extensions .gemini/skills/kit-extensions && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "kit-extensions" agent skill from https://github.com/mark3labs/kit/tree/master/skills/kit-extensions into .gemini/skills/kit-extensions/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "kit-extensions", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install mark3labs/kit kit-extensionsInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add mark3labs/kit --skill kit-extensions -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/mark3labs/kit.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/kit-extensions .github/skills/kit-extensions && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "kit-extensions" agent skill from https://github.com/mark3labs/kit/tree/master/skills/kit-extensions into .github/skills/kit-extensions/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "kit-extensions", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add mark3labs/kit --skill kit-extensions -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install mark3labs/kit kit-extensions --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/mark3labs/kit.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/kit-extensions .opencode/skills/kit-extensions && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "kit-extensions" agent skill from https://github.com/mark3labs/kit/tree/master/skills/kit-extensions into .opencode/skills/kit-extensions/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "kit-extensions", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
kit-extensionsGuide for creating Kit extensions. An agent skill from mark3labs/kit.
Kit Extensions is an agent skill from mark3labs/kit. Guide for creating Kit extensions. Use when the user asks to build, create, or modify a Kit extension, add a custom tool, slash command, widget, keyboard shortcut, editor interceptor, tool renderer, or hook into any Kit lifecycle event.
Its SKILL.md is about 2.5k tokens, which your agent loads only when the skill is triggered. The skill folder holds 10 other files, including reference files (for example `references/bridged-sdk-apis.md`, `references/common-patterns.md` and `references/context-api.md`).
It sits in Agent Workflows, covering Hooks and plugins. The repository describes itself as: KIT (Knowledge Inference Tool) — A lightweight AI agent for coding. The licence is MIT.
4 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit 1eb0cb9. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
goFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Kit Extensions loads about 2.5k tokens when it runs, and up to ~16k if it reads all its reference files. Until then it costs about 63 tokens; SKILL.md has 851 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from mark3labs/kit at commit 1eb0cb9, republished under its MIT licence (© mark3labs). 851 words, ~2,471 tokens.
.claude/skills/kit-extensions/SKILL.md (or your agent's skills folder). This skill also uses 9 other files; get the full folder from GitHub.Kit extensions are single-file Go programs interpreted at runtime by Yaegi. They hook into Kit's lifecycle, register custom tools and slash commands, display widgets, intercept editor input, render tool output, register and switch color themes, and more.
Extensions can be distributed via git repositories using kit install. Repos can contain single extensions or collections of multiple extensions.
This file is the entry point. It gives the structure, a minimal example, and the constraints you must never miss. Detailed material lives in the references/ directory (see Reference files below). Read only the reference files that apply to your task.
Every extension must export a package main with an Init(api ext.API) function:
//go:build ignore
package main
import "kit/ext"
func Init(api ext.API) {
// Register event handlers, tools, commands, etc.
}The //go:build ignore tag prevents go build from compiling the file directly.
Extensions are auto-loaded from these directories:
/usr/share/kit/extensions/*.go (system-wide, single files)/usr/share/kit/extensions/*/main.go (system-wide, subdirectories)~/.config/kit/extensions/*.go (user, single files)~/.config/kit/extensions/*/main.go (user, subdirectories).kit/extensions/*.go (project-local, single files).kit/extensions/*/main.go (project-local, subdirectories)Or loaded explicitly:
kit -e path/to/extension.go
kit --extension path/to/extension.goExtensions import the Kit API as "kit/ext". The full standard library is available plus os/exec for subprocess spawning.
The Init function receives an ext.API object for registering handlers, and event handlers receive an ext.Context with runtime capabilities.
api.On* — subscribe to one of 30 lifecycle events (OnSessionStart, OnToolCall, OnAgentEnd, ...). See references/lifecycle-events.md.api.RegisterTool / RegisterCommand / RegisterShortcut / RegisterOption — add LLM tools, /slash commands, key bindings, and config options. See references/tools-commands-shortcuts.md.ctx.* — runtime capabilities: print output, inject messages, widgets, header/footer, prompts, overlays, editor interceptor, session data/state, model and tool management, LLM completions, themes. See references/context-api.md.api.RegisterToolRenderer / api.RegisterMessageRenderer — custom rendering of tool calls and messages. See references/renderers.md.A tool, a slash command, and an event handler in one file:
//go:build ignore
package main
import (
"time"
"kit/ext"
)
var toolCalls int // package-level vars hold state across callbacks
func Init(api ext.API) {
api.RegisterTool(ext.ToolDef{
Name: "current_time",
Description: "Get the current date and time",
Parameters: `{"type":"object","properties":{}}`,
Execute: func(input string) (string, error) {
return time.Now().Format(time.RFC3339), nil
},
})
api.RegisterCommand(ext.CommandDef{
Name: "echo",
Description: "Echo back the provided text",
Execute: func(args string, ctx ext.Context) (string, error) {
ctx.PrintInfo("You said: " + args)
return "", nil
},
})
api.OnToolCall(func(e ext.ToolCallEvent, ctx ext.Context) *ext.ToolCallResult {
toolCalls++
return nil // nil = allow; return &ext.ToolCallResult{Block: true, Reason: "..."} to block
})
}Run it with kit -e my-ext.go. Validate syntax with kit extensions validate.
Yaegi silently miscompiles some valid Go. Failures do not show an error; the code just does nothing. The full version with complete examples is in references/yaegi-constraints.md.
A named function assigned to a struct field (or passed directly as an argument) returns zero values across the interpreter boundary. Always use anonymous closure literals:
// WRONG - will silently return zero values:
func myHandler(key, text string) ext.EditorKeyAction { ... }
ctx.SetEditor(ext.EditorConfig{HandleKey: myHandler})
// CORRECT - use anonymous closure:
ctx.SetEditor(ext.EditorConfig{
HandleKey: func(key, text string) ext.EditorKeyAction { return myHandler(key, text) },
})This applies to ALL struct fields that take function values: ToolDef.Execute, CommandDef.Execute, EditorConfig.HandleKey, EditorConfig.Render, ToolRenderConfig.RenderHeader, ToolRenderConfig.RenderBody, etc.
In switch { case a, b, c: } Yaegi evaluates only the first expression. Join the conditions with || into one case expression, or use an if/else chain. A switch WITH a tag (switch n { case 1, 2, 3: }) is fine.
// WRONG - only the first condition is ever checked:
case r >= 'a' && r <= 'z', r >= 'A' && r <= 'Z', r >= '0' && r <= '9':
// CORRECT:
case (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') || (r >= '0' && r <= '9'):All extension-facing API types are concrete structs, never interfaces. Yaegi crashes on interface wrapper generation.
Yaegi supports package-level variables captured in closures. This is the standard way to maintain state across event callbacks (var callCount int at file scope, then mutate inside handlers).
nil to pass through. Every On* handler that returns a *Result pointer treats nil as "no change". Return a non-nil pointer only to modify or block.ctx.PromptSelect, I/O, or exec.Command safely.ctrl+c as a shortcut (rejected at load). Prefer modifier combinations over bare keys.e.StopReason == "error" is the error check in OnAgentEnd. Do NOT compare against "completed" for success.Parameters is a JSON Schema string. The input argument to Execute is the JSON-encoded parameters from the LLM.len([]rune(s))) not byte length when aligning widget text that contains box-drawing or multi-byte characters.Read the file that matches the task. Paths are relative to this skill's root directory.
| File | Read it when you need... |
|---|---|
references/lifecycle-events.md | The full list of all 30 events (session, agent turn, tool, tool-call streaming, input, streaming, model, UI, context filtering, session control, custom events), their fields, and return types. |
references/tools-commands-shortcuts.md | Registering tools (including ExecuteWithContext with cancellation/progress), slash commands with tab-completion, keyboard shortcuts (key-name normalization and reserved keys), and options. |
references/context-api.md | The complete ext.Context API: output, message injection, widgets, header/footer, status bar, prompts, overlays, editor interceptor, terminal size, thinking level, UI visibility, session data/state, model and tool management, LLM completions, TUI suspension, themes, application control, context fields. |
references/renderers.md | Custom tool renderers (RenderHeader / RenderBody) and message renderers. |
references/yaegi-constraints.md | The full Yaegi constraints section with complete code examples for each pitfall. |
references/common-patterns.md | Recipes: tool call blocking, system prompt injection, background processing with SendMessage, ephemeral context injection, live widget updates, custom theme with slash command, spawning Kit as a sub-agent. |
references/testing-and-distribution.md | The pkg/extensions/test harness and assertions, CLI testing commands, and distributing extensions via git repositories (kit install, repo structure, README template, storage locations). |
references/plan-mode-example.md | A complete, end-to-end extension (Plan Mode) that combines shortcuts, widgets, tool blocking, and state. |
references/bridged-sdk-apis.md | Bridged SDK capabilities: conversation tree navigation, skill loading, template parsing, model resolution, model pricing. |
internal/extensions/api.go — Complete API type definitionsinternal/extensions/runner.go — Event dispatch and state managementinternal/extensions/loader.go — Yaegi interpreter setupinternal/extensions/symbols.go — All types exported to extensionspkg/extensions/test/ — Testing package with harness, mocks, and assertionsexamples/extensions/tool-logger_test.go — Complete test exampleexamples/extensions/ — 25+ working example extensions© mark3labs, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 9 other files (references) in skills/kit-extensions of mark3labs/kit.
Open the folder on GitHubat commit 1eb0cb9
Kit Extensions next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Kit Extensions this skillmark3labs/kit | 140 | — | ~2.5k | Automated safety check: Pass | MIT | |
| Hook Development for Claude Code Pluginsanthropics/claude-plugins-official | 37k | 11 repos | ~4.1k | Automated safety check: Notes | Apache-2.0 | |
| Claude Code Agent Developmentanthropics/claude-plugins-official | 37k | 8 repos | ~2.8k | Automated safety check: Pass | Apache-2.0 | |
| Claude Code Skill Developer Guidediet103/claude-code-infrastructure-showcase | 10k | 10 repos | ~3.5k | Automated safety check: Pass | MIT | |
| Plugin Settings Patternanthropics/claude-plugins-official | 37k | 7 repos | ~3k | Automated safety check: Pass | Apache-2.0 | |
| MCP Integration for Pluginsanthropics/claude-plugins-official | 37k | 11 repos | ~3.1k | Automated safety check: Pass | Apache-2.0 |
anthropics/claude-plugins-official
Explains how to write Claude Code plugin hooks, both prompt-based checks and bash commands, for events such as PreToolUse, Stop and SessionStart.
anthropics/claude-plugins-official
Explains how to write agents for Claude Code plugins: the markdown file with YAML frontmatter, trigger descriptions, model and color settings, and system prompt design.
diet103/claude-code-infrastructure-showcase
A guide to creating and managing Claude Code skills with auto-activation: skill-rules.json triggers, hooks, enforcement levels, YAML frontmatter and progressive disclosure.
anthropics/claude-plugins-official
Shows how Claude Code plugins keep per-project settings and state in .claude/plugin-name.local.md files with YAML frontmatter and a markdown body.
anthropics/claude-plugins-official
Explains how to bundle Model Context Protocol servers in a Claude Code plugin, covering config files, stdio, SSE, HTTP and WebSocket server types, and authentication.
anthropics/claude-plugins-official
Explains how to write Claude Code slash commands: Markdown files with YAML frontmatter, arguments, file references, bash context and interactive prompts.
mark3labs/kit
Guide for building Go applications with the Kit SDK. An agent skill from mark3labs/kit.
Categories
Guide for creating Kit extensions. An agent skill from mark3labs/kit. Kit Extensions is an agent skill from mark3labs/kit. Guide for creating Kit extensions.
Kit Extensions fits situations like: the user asks to build; modify a Kit extension; add a custom tool; keyboard shortcut.
Run `npx skills add mark3labs/kit --skill kit-extensions -a claude-code`. Or copy the skill folder (skills/kit-extensions in mark3labs/kit) into .claude/skills/kit-extensions in your project. Claude Code loads it when a task matches its description.
Run `npx skills add mark3labs/kit --skill kit-extensions -a codex`. Or copy the skill folder (skills/kit-extensions in mark3labs/kit) into .agents/skills/kit-extensions in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add mark3labs/kit --skill kit-extensions -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/kit-extensions, .gemini/skills/kit-extensions, .github/skills/kit-extensions and .opencode/skills/kit-extensions in your project.
Going by SKILL.md and its folder, Kit Extensions needs the command-line tools its instructions call (go).
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Kit Extensions is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 2.5k tokens (SKILL.md is roughly 9.9k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 13k tokens, read only when the agent opens those files.
Skills that share tags, products or a category with Kit Extensions: Hook Development for Claude Code Plugins (anthropics/claude-plugins-official, 37k stars), Claude Code Agent Development (anthropics/claude-plugins-official, 37k stars), Claude Code Skill Developer Guide (diet103/claude-code-infrastructure-showcase, 10k stars) and Plugin Settings Pattern (anthropics/claude-plugins-official, 37k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
mark3labs (a GitHub organization) maintains it in mark3labs/kit, which has 140 GitHub stars. The repository holds 2 skills in this directory. The repository was last updated on October 6, 2026.
Source: mark3labs/kit on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.