Agent skill

Create Plugin

by marcus in marcus/sidecar

Create new sidecar plugins implementing the plugin.Plugin interface, rendering views with Bubble Tea, handling keyboard input via keymap contexts, and integrating with the app shell (footer hints…

MITAuto-check passedBackend & APIs

Install Create Plugin

skills CLI
$ npx skills add marcus/sidecar --skill create-plugin -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install marcus/sidecar create-plugin --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/marcus/sidecar.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/create-plugin .claude/skills/create-plugin && rm -rf skills-src

Use ~/.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/

Facts

Skill name
create-plugin
GitHub stars
1.1k
Token cost
~2.3k tokens
SKILL.md length
757 words
Files
3 (incl. references)
Skills in repo
19
Repo updated
First seen
Licence
MIT

At a glance

Create new sidecar plugins implementing the plugin.Plugin interface, rendering views with Bubble Tea, handling keyboard input via keymap contexts, and integrating with the app shell (footer hints…

  • Works in 3 steps: Add Epoch to message type → Capture epoch in command creators → Check staleness in Update
  • Creating a new plugin
  • SKILL.md covers Architecture Overview, Plugin Interface, Lifecycle Order and Epoch Pattern (Stale Message…, plus 11 more sections
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md

What it does

Create Plugin is an agent skill from marcus/sidecar. Create new sidecar plugins implementing the plugin.Plugin interface, rendering views with Bubble Tea, handling keyboard input via keymap contexts, and integrating with the app shell (footer hints, event bus, adapters). Use when creating a new plugin, modifying plugin architecture, or debugging plugin rendering/lifecycle issues. See references/ for sidebar list and fixed footer layout details.

Its SKILL.md is about 2.3k tokens, which your agent loads only when the skill is triggered. The skill folder holds 3 other files, including reference files (for example `references/fixed-footer-layout-guide.md` and `references/sidebar-list-guide.md`).

It sits in Backend & APIs, covering Event-driven systems. The repository describes itself as: Use sidecar next to CLI agents for diffs, file trees, conversation history, and task management with td. The licence is MIT.

When your agent uses it

  • Creating a new plugin
  • Modifying plugin architecture
  • Debugging plugin rendering/lifecycle issues

Example prompts

  • “/create-plugin”

Workflow steps

3 steps, taken from the step headings in SKILL.md.

  1. Add Epoch to message type
  2. Capture epoch in command creators
  3. Check staleness in Update

What it can do on your machine

Read from SKILL.md and the folder at commit 3792a4e. It shows what the files ask for, not the result of running them.

  • Tool permissions

    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.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are go).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Create Plugin loads about 2.3k tokens when it runs, and up to ~3.8k if it reads all its reference files. Until then it costs about 102 tokens; SKILL.md has 757 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~102
When it runs · the whole SKILL.md, loaded when a task matches
~2.3k
With references · SKILL.md plus every file in references/, read only if the agent opens them
~3.8k

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.

Safety

Auto-check passed

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.

SKILL.md

The full file from marcus/sidecar at commit 3792a4e, republished under its MIT licence (© marcus). 757 words, ~2,333 tokens.

Download SKILL.mdSave it as .claude/skills/create-plugin/SKILL.md (or your agent's skills folder). This skill also uses 2 other files; get the full folder from GitHub.
name
create-plugin
description
Create new sidecar plugins implementing the plugin.Plugin interface, rendering views with Bubble Tea, handling keyboard input via keymap contexts, and integrating with the app shell (footer hints, event bus, adapters). Use when creating a new plugin, modifying plugin architecture, or debugging plugin rendering/lifecycle issues. See references/ for sidebar list and fixed footer layout details.

Create Plugin

This skill is the embedded class: a Go package compiled into Sidecar with its own Bubble Tea UI. If what you want is a tool's data in Sidecar — a searchable tab, rows that open into documents, panes beside a terminal — you almost certainly want a protocol plugin instead: an executable in any language answering five JSON methods, which Sidecar renders itself and which ships as a config entry rather than a Sidecar release. Read docs/guides/active/creating-plugins.md and stop here. Come back only when the screen itself is the point — a board, a queue, a layout the collection-and-document vocabulary cannot express — because everything below costs a release, a keymap pass, and a permanent place in the repository.

Architecture Overview

  • Bubble Tea model: internal/app/model.go owns the active plugin index, dispatches key events, renders plugin views.
  • Registry: internal/plugin/registry.go stores plugins, handles lifecycle with panic protection, keeps an unavailable map when Init fails (silent degradation).
  • Plugin contract: internal/plugin/plugin.go defines the interface every plugin must satisfy.
  • Context: internal/plugin/context.go provides WorkDir, ConfigDir, Adapters, EventBus, Logger, Epoch, and Keymap.
  • Keymap: internal/keymap maps keys to command IDs. Footer/help reads bindings by context using Plugin.Commands() + Plugin.FocusContext().

Plugin Interface

Every plugin must implement all of these methods:

go
ID() string              // Stable kebab-case identifier
Name() string            // Short human label for headers/help
Icon() string            // Single-character glyph for tab strip
Init(ctx *Context) error // Lightweight setup; return error to degrade gracefully
Start() tea.Cmd          // Kick off async work (non-blocking)
Update(msg tea.Msg) (Plugin, tea.Cmd) // Pure state transition
View(width, height int) string        // Render within provided dimensions
IsFocused() bool         // Check focus state
SetFocused(bool)         // App calls this on tab switch
Commands() []plugin.Command           // Footer hints per context
FocusContext() string    // Current context name for keymap
Stop()                   // Idempotent cleanup

Optional: implement Diagnostics() []plugin.Diagnostic for the diagnostics overlay.

Lifecycle Order

  1. Registration (cmd/sidecar/main.go): registry.Register(myplugin.New()). No work here.
  2. Init: Detect prerequisites (repos, adapters, env vars). Use ctx.Logger for warnings. Return error to degrade gracefully.
  3. Start: Batch initial commands with tea.Batch. Never block.
  4. Update: Pattern-match on custom Msg types and tea.KeyMsg. Keep I/O in commands, not directly in Update.
  5. View: Render only; no side-effects. Honor width/height.
  6. Focus/Blur: SetFocused called on tab switch. Pause expensive work when unfocused.
  7. Stop: Close watchers, timers, channels. Guard with sync.Once/flags.

Epoch Pattern (Stale Message Detection)

When switching projects/worktrees, async operations may deliver stale data. Use the epoch pattern:

Step 1: Add Epoch to message type
go
type MyDataLoadedMsg struct {
    Epoch uint64
    Data  string
    Err   error
}
func (m MyDataLoadedMsg) GetEpoch() uint64 { return m.Epoch }
Step 2: Capture epoch in command creators
go
func (p *Plugin) loadData() tea.Cmd {
    epoch := p.ctx.Epoch // Capture synchronously before closure
    return func() tea.Msg {
        data, err := fetchData()
        return MyDataLoadedMsg{Epoch: epoch, Data: data, Err: err}
    }
}
Step 3: Check staleness in Update
go
case MyDataLoadedMsg:
    if plugin.IsStale(p.ctx, msg) {
        return p, nil // Discard stale message
    }
    p.data = msg.Data

Apply this to any async message that fetches data from filesystem/external sources or updates project-specific state.

Keymap, Contexts, and Commands

  • Define contexts mirroring your view modes (e.g., git-status, git-diff). Return the active one from FocusContext().
  • Expose commands with matching contexts via Commands(). These power footer hints and help overlay.
  • Add default bindings in internal/keymap/bindings.go.
  • Keep command IDs stable (verbs preferred: open-file, toggle-diff-mode).
Command structure
go
plugin.Command{
    ID:       "stage-file",
    Name:     "Stage",           // Keep 1-2 words max
    Category: plugin.CategoryGit,
    Priority: 10,                // Lower = higher priority; 0 treated as 99
    Context:  "git-status",
}

Categories: CategoryNavigation, CategoryActions, CategoryView, CategorySearch, CategoryEdit, CategoryGit, CategorySystem

Context naming convention
  • plugin-name for main view
  • plugin-name-detail for detail/preview
  • plugin-name-modal for modals
  • plugin-name-search for search modes
Dynamic binding registration
go
func (p *Plugin) Init(ctx *plugin.Context) error {
    if ctx.Keymap != nil {
        ctx.Keymap.RegisterPluginBinding("g g", "go-to-top", "my-context")
    }
    return nil
}

Event Bus (Cross-Plugin Communication)

  • Subscribe: ch := ctx.EventBus.Subscribe("topic") in Start(), forward messages into Update.
  • Publish: ctx.EventBus.Publish("topic", event.NewEvent(event.TypeRefreshNeeded, "topic", payload)).
  • Best-effort, buffered (size 16), drops when full. Design listeners to be resilient.
Show full SKILL.md (310 more words)Show less

Inter-Plugin Messages

App-level messages (internal/app/commands.go):

  • FocusPluginByIDMsg{PluginID} / app.FocusPlugin(id)

File browser messages (internal/plugins/filebrowser/plugin.go):

  • NavigateToFileMsg{Path} - navigate to and preview a file

Pattern for cross-plugin navigation:

go
func (p *Plugin) openInFileBrowser(path string) tea.Cmd {
    return tea.Batch(
        app.FocusPlugin("file-browser"),
        func() tea.Msg { return filebrowser.NavigateToFileMsg{Path: path} },
    )
}

Plugin Focus Events

PluginFocusedMsg (from internal/app): sent when your plugin becomes active tab. Use to refresh data only needed when visible:

go
case app.PluginFocusedMsg:
    if p.pendingRefresh {
        p.pendingRefresh = false
        return p, p.refresh()
    }

External Editor Integration

go
func (p *Plugin) openFile(path string, lineNo int) tea.Cmd {
    editor := p.ctx.Config.EditorCommand
    return func() tea.Msg {
        return plugin.OpenFileMsg{Editor: editor, Path: path, LineNo: lineNo}
    }
}

Rendering Rules

CRITICAL: Always constrain plugin output height. The app header/footer are always visible. Plugins must not exceed allocated height.

go
lipgloss.NewStyle().Width(width).Height(height).MaxHeight(height).Render(content)

Do NOT render footers in plugin View(). The app renders footer using Commands() and keymap bindings.

Additional rendering rules:

  • Keep View deterministic; drive dynamic data through state in Update.
  • Cache width/height in plugin state.
  • Expand \t to spaces before width checks.
  • Use ANSI-aware helpers (ansi.Truncate, lipgloss.Width) for content with escape codes.
  • Use small helper render functions per view mode.

See references/sidebar-list-guide.md for scrollable list implementation patterns. See references/fixed-footer-layout-guide.md for footer and layout math details.

Persisting User Preferences

Use internal/state to persist layout preferences across restarts:

  1. Add field to state.State struct with getter/setter.
  2. Load in Init(): if saved := state.GetMyPaneWidth(); saved > 0 { p.paneWidth = saved }
  3. Save on user action: _ = state.SetMyPaneWidth(p.paneWidth)

Adapters

  • ctx.Adapters holds integrations. Check capability in Init before using.
  • Watcher data from adapters should feed messages through Update.

Error Handling

  • Return lightweight errors from Init; registry records them without crashing.
  • Use ctx.Logger with structured fields.
  • Surface recoverable issues as status/toast messages, not panics.

New Plugin Checklist

  1. Create internal/plugins/<id>/ with plugin.go plus supporting files.
  2. Implement the plugin.Plugin interface; consider DiagnosticProvider.
  3. Register in cmd/sidecar/main.go.
  4. Add default key bindings in internal/keymap/bindings.go.
  5. Ensure Commands() covers every binding so hints/help work.
  6. Wire external needs (adapters, env detection) in Init; degrade gracefully.
  7. Provide cleanup in Stop; keep Start/Update non-blocking.

Testing

  • Keep business logic in testable helpers; wire Bubble Tea plumbing around it.
  • Use small typed messages (type RefreshMsg struct{}) to keep Update readable.
  • Enable --debug for verbose logs from registry and plugins.

© marcus, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 2 other files (references) in .claude/skills/create-plugin of marcus/sidecar.

  • SKILL.md
  • references/fixed-footer-layout-guide.md
  • references/sidebar-list-guide.md

Open the folder on GitHubat commit 3792a4e

Compare with similar skills

Create Plugin 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.

Create Plugin compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Create Plugin this skillmarcus/sidecar1.1k—~2.3kAutomated safety check: PassMIT
Windmill Trigger Type Checklistwindmill-labs/windmill18k—~4.7kAutomated safety check: PassCustom licence
Dynamic Consistency BoundariesAxonIQ/AxonFramework3.6k—~1.9kAutomated safety check: PassApache-2.0
Opensource Guide Coachcalf-ai/calfkit-sdk1491 repos~2.1kAutomated safety check: PassApache-2.0
NestJS Modular Monolith Architecttech-leads-club/agent-skills7k—~3.9kAutomated safety check: PassCC-BY-4.0
Adobe App Builder Action Scaffolderadobe/skills195—~3.1kAutomated safety check: PassApache-2.0

Similar skills

  • Windmill Trigger Type Checklist

    windmill-labs/windmill

    Checklist of every backend, frontend, CLI and capture change needed to add a new TriggerCrud-based trigger type, such as Azure, GCP or Kafka, to Windmill.

    18k GitHub stars~4.7k tokensUpdated today
    Backend & APIsAuto-check passed
  • Dynamic Consistency Boundaries

    AxonIQ/AxonFramework

    Explain and reason about Dynamic Consistency Boundaries (DCB) and how Axon Framework 5 and Axon Server implement them.

    3.6k GitHub stars~1.9k tokensUpdated today
    Backend & APIsAuto-check passed
  • Opensource Guide Coach

    calf-ai/calfkit-sdk

    A skill your agent uses when a user wants guidance on starting, contributing to, growing, governing, funding, securing, or sustaining an open source project, or asks about contributor onboarding…

    149 GitHub starsUsed in 1 repo~2.1k tokens
    Backend & APIsAuto-check passed
  • NestJS Modular Monolith Architect

    tech-leads-club/agent-skills

    Designs scalable NestJS modular monoliths with domain-driven design, Clean Architecture layers and optional CQRS, defining bounded contexts and strict module boundaries.

    7k GitHub stars~3.9k tokensUpdated 17 days ago
    Backend & APIsAuto-check passed
  • Scaffolds, implements, deploys and debugs Adobe Runtime actions in App Builder projects, with templates for webhooks, events, database CRUD, sequences and Asset Compute workers.

    195 GitHub stars~3.1k tokensUpdated yesterday
    Backend & APIsAuto-check passed
  • Mediator Reference

    fullstackhero/dotnet-starter-kit

    CQRS interface reference for FSH. An agent skill from fullstackhero/dotnet-starter-kit.

    6.8k GitHub stars~709 tokensUpdated 7 days ago
    Backend & APIsAuto-check passed

More from marcus/sidecar

All 19 skills in this repo
  • Create Adapter

    marcus/sidecar

    Create conversation adapters for importing AI chat history from different tools (Claude Code, Cursor, Warp, Codex, etc.).

    1.1k GitHub stars~4.8k tokensUpdated 2 days ago
    Auto-check passed
  • Create Modal

    marcus/sidecar

    Create declarative modals using the modal library API. An agent skill from marcus/sidecar.

    1.1k GitHub stars~2.6k tokensUpdated 2 days ago
    Auto-check passed
  • Project Switching

    marcus/sidecar

    Project switching implementation in sidecar: project discovery, state management, UI flow, modal rendering, filtering, theme preview, and plugin reinitialization.

    1.1k GitHub stars~1.8k tokensUpdated 2 days ago
    Auto-check passed
  • Shell Integration

    marcus/sidecar

    Interactive shell/TTY integration with tmux session management, shell command execution, control-mode output capture with polling fallback, native cursor rendering, lazy scrollback, selection, paste…

    1.1k GitHub stars~3.6k tokensUpdated 2 days ago
    Auto-check passed
  • Sidecar Website

    marcus/sidecar

    Writing and maintaining the Sidecar Docusaurus documentation site, including page structure, doc authoring, blog posts, styling, images, and deployment workflow.

    1.1k GitHub stars~1.7k tokensUpdated 2 days ago
    Auto-check passed
  • UI Features

    marcus/sidecar

    Implementing UI/UX features in sidecar including modals (internal/modal library), keyboard shortcuts, mouse support, scrolling, pill/tab rendering, and pane resizing.

    1.1k GitHub stars~4.6k tokensUpdated 2 days ago
    Auto-check passed

Questions about Create Plugin

What does Create Plugin do?

Create new sidecar plugins implementing the plugin.Plugin interface, rendering views with Bubble Tea, handling keyboard input via keymap contexts, and integrating with the app shell (footer hints…. Create Plugin is an agent skill from marcus/sidecar.Plugin interface, rendering views with Bubble Tea, handling keyboard input via keymap contexts, and integrating with the app shell (footer hints, event bus, adapters).

When should I use Create Plugin?

Create Plugin fits situations like: creating a new plugin; modifying plugin architecture; debugging plugin rendering/lifecycle issues.

How do I install Create Plugin in Claude Code?

Run `npx skills add marcus/sidecar --skill create-plugin -a claude-code`. Or copy the skill folder (.claude/skills/create-plugin in marcus/sidecar) into .claude/skills/create-plugin in your project. Claude Code loads it when a task matches its description.

How do I install Create Plugin in Codex?

Run `npx skills add marcus/sidecar --skill create-plugin -a codex`. Or copy the skill folder (.claude/skills/create-plugin in marcus/sidecar) into .agents/skills/create-plugin in your project. Codex loads it when a task matches its description.

Can I use Create Plugin in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add marcus/sidecar --skill create-plugin -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/create-plugin, .gemini/skills/create-plugin, .github/skills/create-plugin and .opencode/skills/create-plugin in your project.

What does Create Plugin need to run?

SKILL.md names no scripts, command-line tools or credentials: Create Plugin is instructions for the agent only.

Does Create Plugin access the network?

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.

Is Create Plugin safe to install?

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.

What licence does Create Plugin use?

Create Plugin is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Create Plugin use?

About 2.3k tokens (SKILL.md is roughly 9.3k 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 1.5k tokens, read only when the agent opens those files.

What are the alternatives to Create Plugin?

Skills that share tags, products or a category with Create Plugin: Windmill Trigger Type Checklist (windmill-labs/windmill, 18k stars), Dynamic Consistency Boundaries (AxonIQ/AxonFramework, 3.6k stars), Opensource Guide Coach (calf-ai/calfkit-sdk, 149 stars) and NestJS Modular Monolith Architect (tech-leads-club/agent-skills, 7k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Create Plugin?

marcus (a GitHub user) maintains it in marcus/sidecar, which has 1,085 GitHub stars. The repository holds 19 skills in this directory. The repository was last updated on October 5, 2026.

Source: marcus/sidecar on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.