AI agents are transforming how engineers build software. At Zenity, we wanted to go beyond using AI as an assistant and make it a core part of how we plan, develop, and deliver code. That vision led us to design our own Claude Code plugin ecosystem, fully integrated into our engineering environment.

This is the technical story of how we built it, and the key architectural decision that made it work across multiple languages and codebases.

What Are Claude Code Plugins?

With the recent debut of Claude Code plugins launched alongside the Claude Sonnet 4.5 model of Anthropic, we’re entering a new chapter in autonomous developer tooling. They allow teams to customize and extend Claude Code with commands, purpose-built agents, Model Context Protocol (MCP) servers, and workflow hooks. They make it possible to package and share specialized capabilities so engineers can install exactly what they need for their project.

Think of it as a package manager for AI workflows, similar to how npm works for JavaScript packages or pip for Python, but for AI-powered development tools.

The Foundation: Devcontainer-First Architecture

Every engineer at Zenity works inside a development container. This gave us a consistent, reproducible foundation that became the backbone of our plugin distribution strategy. From the start, our goal was to maximize the "plug-and-play" functionality, both at initial setup and through seamless ongoing updates.

Our dev-container's Dockerfile installs Claude Code globally and connects it to our marketplace with a global configuration, so that when an engineer launches their workspace, Claude Code is preinstalled, connected to our up-to-date internal marketplace, ready to use with zero manual setup, persistent across container rebuilds and keeps user's custom settings.

Plugins Marketplace Repository Structure

To manage our custom Claude Code marketplace, we chose to host it in a Git repository. This gives us a clean, version-controlled environment where updates, plugin additions, and releases can be tracked, managed seamlessly and easily distributed.

In Claude Code, a marketplace serves as a container for one or more plugins. Each plugin can either live directly within the marketplace repository or be imported from external sources. This design follows Claude Code’s core structural requirement: the marketplace layer handles organization and discovery, while the plugin layer focuses on specific functionality and implementation.

Level 1: Marketplace (.claude-plugin/marketplace.json)

{
  "name": "zenity-claude-marketplace",
  "metadata": {
    "description": "The Zenity Claude Plugins Marketplace",
    "version": "1.0.0"
  },
  "plugins": [
    {
      "name": "backend-development",
      "source": "./backend-development",
      "description": "Language-agnostic backend development plugin"
    }
  ]
}

Level 2: Plugin (backend-development/.claude-plugin/plugin.json)

{
  "name": "backend-development",
  "description": "Backend Development plugin with planning and spec templates",
  "version": "1.0.0",
  "author": {
    "name": "Or Shauloff"
  }
}

Plugin Directory Structure:

backend-development/
├── .claude-plugin/
│   └── plugin.json              # Plugin metadata
├── agents/
│   ├── planner.md               # Creates comprehensive specs
│   └── utils-agent.md           # Handles Git, JIRA, GitHub operations
├── commands/
│   └── plan.md                  # /plan command definition
├── templates/
│   └── spec-TEMPLATE.md          # Language-agnostic spec template
└── README.md

Each component is a markdown file defining its behavior. For example, agents are defined as:

---
name: planner
description: Creates comprehensive specs by analyzing codebase conventions
model: sonnet
---
# Planner Agent - Backend Development
You are the Planner Agent for backend development...
[Detailed agent instructions follow]

The Key Insight: Separating Generic Instructions from Project-Specific Conventions

Here's where we made a critical architectural decision that solved the language-agnostic challenge:

The Problem: How do you build a single plugin that works across Python, Typescript and other types of projects without hardcoding language-specific logic?

The Solution: Split the context into two layers:

  1. Generic Layer (Plugin): Language-agnostic agent instructions

  2. Project-Specific Layer (CLAUDE.md): Language conventions, coding standards, patterns

The Architecture

Why This Matters for Context Management:

Instead of bloating the plugin with language-specific instructions (which would pollute Claude's context window with irrelevant information), we:

  1. Keep the plugin lean: Only generic planning logic lives in the plugin

  2. Load conventions dynamically: The Planner agent's first action is to read CLAUDE.md from the repository root

  3. Context-efficient: Claude only loads the conventions relevant to the current project

The Benefits:
  • Single plugin, unlimited languages: One plugin works everywhere

  • Better context management: Claude only loads relevant conventions

  • Easy to maintain: Update conventions in one place ( CLAUDE.md )

  • Self-documenting: Each project's conventions are explicit and version-controlled

What We Built: The Backend-Development Plugin

The plugin consists of:

  1. Commands:

    • /plan [ticket-or-description] - Create comprehensive spec from Jira ticket or feature description

  2. Agents:

    • Planner Agent: Creates specs by reading CLAUDE.md and analyzing codebase patterns

    • Utils Agent: Handles external operations such as Git, JIRA, GitHub and tooling (ruff, mypy), to make other agents context-efficient while saving context for operational processes

  3. Templates:

    • spec-TEMPLATE.md : Comprehensive structure including requirements, implementation decisions (populated from CLAUDE.md ), TDD workflow and general guidelines based on the research and instructions of the planner.

Continuous Evolution

Our system is designed to evolve. We can add, update and fine-tune agents, commands, and templates at any time by simply editing markdown files with no code changes, no deployments.

Planned Enhancements

  • Complete the workflow with additional commands:

    • /implement - Orchestrate code generation from specs

    • /review - Automated code review workflows

  • Additional domain plugins (i.e. frontend-development)

  • MCP server integrations for external tool connections

Each iteration enhances reasoning, precision, and adaptability. This is not a static tool but a living layer of intelligence that grows with our engineering culture, powered by the new Plugins system for Claude.

Lessons Learned

  1. Convention over Configuration Reading project conventions dynamically ( CLAUDE.md ) made our plugin universal instead of language-specific. This was the breakthrough that made everything else possible.

  2. Context Management is Critical Separating generic instructions (plugin) from project-specific conventions (CLAUDE.md ) keeps Claude's context window clean and focused. This dramatically improves agent performance.

  3. Dev-container Integration Embedding the marketplace in dev-containers eliminated installation friction entirely. Zero-config setup for all developers.

This is just the beginning. We're excited to see how plugin ecosystems evolve as more teams adopt Claude Code and build their own specialized workflows.

Keep Reading

No posts found