콘텐츠로 이동

Plugin System

Bonie의 플러그인 시스템 구조 — marketplace, 번들링, 네임스페이싱, 로드 순서를 정의한다.

Why this structure

개별 플러그인 설치/관리는 번거롭고, 하나의 거대한 플러그인은 관심사 분리가 어렵다. Main-bundle 구조를 택하여 단일 marketplace 설치로 전체 스위트를 활성화하면서도, 각 플러그인은 독립 plugin.json으로 관심사를 분리한다.

System view

graph TD
    MP["marketplace.json"] --> Bonie["bonie (core)"]
    MP --> Todo["todo (core)"]
    MP --> TS["typescript"]
    MP --> Docker["docker"]
    MP --> K8s["kubernetes"]
    MP --> More["..."]

    subgraph Core["primitives/ (항상 활성화)"]
        Bonie
        Todo
    end

    subgraph Optional["카테고리 (개별 활성화 가능)"]
        TS
        Docker
        K8s
        More
    end

Components

marketplace.json

  • Responsibility — 전체 플러그인 카탈로그. 설치 단위.
  • Inputs — plugins[] 배열의 source 경로
  • Outputs — 각 플러그인 활성화
  • Dependencies — 없음 (최상위)
{
  "name": "bonie",
  "owner": {
    "name": "pabloism0x",
    "email": "pablo@luxtra.dev"
  },
  "metadata": {
    "description": "Bonie - Universal Claude Code agent plugin suite",
    "version": "0.1.0"
  },
  "plugins": [
    {
      "name": "bonie",
      "source": "./plugins/primitives/bonie",
      "description": "Main entry point. Scaffolds .claude/ and orchestrates Bonie plugins.",
      "category": "primitives",
      "tags": ["scaffold", "core", "init"]
    },
    {
      "name": "todo",
      "source": "./plugins/primitives/todo",
      "description": "Phase-based task planning bound to .claude/TODO.md with statusline progress.",
      "category": "primitives",
      "tags": ["task", "planning", "statusline"]
    }
  ]
}

plugins[] entry fields

Field Type Required Description
name string Y 플러그인 식별자 (kebab-case)
source string Y marketplace root 기준 상대경로
description string Y 간략 설명
category string N 분류 (primitives, lang, devops, git, design, security)
tags string[] N 검색/필터용 태그
version string N plugin.json에 없을 경우 여기서 관리

plugin.json

  • Responsibility — 개별 플러그인 메타데이터와 컴포넌트 경로
  • Inputs — 없음
  • Outputs — Claude Code에 플러그인 등록
{
  "name": "bonie",
  "version": "0.1.0",
  "description": "Main Bonie plugin. Scaffolds .claude/ and orchestrates the Bonie plugin suite.",
  "author": {
    "name": "pabloism0x",
    "email": "pablo@luxtra.dev"
  },
  "homepage": "https://github.com/luxtradev/bonie",
  "repository": "https://github.com/luxtradev/bonie",
  "keywords": ["bonie", "scaffold", "claude-code", "agent"]
}

고정 필드 — Bonie 전체 플러그인에 공통 적용:

{
  "author": { "name": "pabloism0x", "email": "pablo@luxtra.dev" },
  "homepage": "https://github.com/luxtradev/bonie",
  "repository": "https://github.com/luxtradev/bonie"
}

Interactions

네임스페이싱

플러그인 skills는 plugin-name:skill-name 형태로 네임스페이싱된다.

Plugin Skill Invocation 방식
bonie init /bonie:init 사용자 직접 호출
todo plan /todo:plan 사용자 직접 호출
typescript conventions (auto) Claude 자동 매칭
kubernetes best-practices (auto) Claude 자동 매칭

로드 순서

sequenceDiagram
    participant CC as Claude Code
    participant PJ as plugin.json
    participant HK as hooks.json
    participant AG as agents/
    participant SK as skills/
    participant ST as settings.json
    participant PM as CLAUDE.md + rules/

    CC->>PJ: 1. 파싱 → 컴포넌트 경로 확인
    CC->>HK: 2. hook 이벤트 리스너 등록
    CC->>AG: 3. subagent 정의 등록
    CC->>SK: 4. skill description 컨텍스트 주입
    CC->>ST: 5. 설정 적용 (agent 등)
    CC->>PM: 6. 프로젝트 레벨 로드

환경변수

Variable Description Use
${CLAUDE_PLUGIN_ROOT} 플러그인 설치 디렉토리 hook script, 파일 참조
${CLAUDE_PLUGIN_DATA} 플러그인 영구 데이터 디렉토리 캐시, 의존성
${CLAUDE_SKILL_DIR} 현재 skill 디렉토리 supporting file 참조
${CLAUDE_SESSION_ID} 현재 세션 ID 로깅, 세션별 파일

Trade-offs

Benefit Cost
단일 설치로 전체 활성화 사용하지 않는 플러그인도 포함
각 플러그인 독립성 유지 플러그인 간 의존성이 암묵적
네임스페이싱으로 충돌 방지 호출 시 prefix 필요 (bonie:init)

Constraints

  • marketplace 단위로만 설치/제거 가능 (개별 플러그인 단위 X)
  • 카테고리 플러그인은 primitives에만 의존 가능 (교차 의존 금지)
  • plugin.json 경로는 반드시 ./로 시작하는 상대경로

See also