Skip to content
Apothem
블로그

멀티 하니스 어댑터 설계의 내부

Apothem의 HarnessAdapter 프로토콜과, 하나의 프로파일을 열일곱 개의 하니스로 구체화하는 세 가지 어댑터 클래스에 대한 기술적 심층 분석.

Apothem은 하나의 공유 프로파일을 열일곱 개의 하니스 네이티브 구성으로 구체화합니다. 열일곱 개의 대상, 열일곱 가지 벤더 형식, 열일곱 개의 설치 위치 — 그리고 운영자와 CLI 둘 다가 의존하는 하나의 균일한 인터페이스. 이 글은 어댑터 계층이 그 계약을 어떻게 하나로 묶어 두는지 설명합니다.

HarnessAdapter 프로토콜

모든 하니스 어댑터는 구조적 HarnessAdapter 프로토콜을 구현합니다. 프로토콜은 CLI와 벤더 특화 세부 사항 사이의 솔기입니다. CLI가 호출하는 연산과 CLI가 읽는 메타데이터를 선언합니다.

  • name — 어댑터의 등록된 식별자.
  • output_path — 구체화된 구성이 디스크에 안착하는 위치.
  • install — 하니스 네이티브 구성을 렌더링하고 기록한다.
  • uninstall — 공유 프로파일은 건드리지 않은 채, 구체화된 구성을 제거한다.
  • is_installed — 하니스의 구성이 존재하는지 보고한다.
  • verify — 프로파일과 디스크 상의 구성 사이의 표류를 탐지한다.

계약이 typing.Protocol이므로, 어댑터는 상속이 아니라 형태로 그것을 충족합니다. CLI는 pyproject.toml[project.entry-points."apothem.harnesses"] 테이블로부터 importlib.metadata 를 통해 어댑터를 동적으로 로드합니다. 하니스를 추가한다는 것은 프로토콜을 노출하는 하위 패키지를 게시하는 것을 뜻합니다 — 코어 디스패처를 수정하지 않습니다.

어댑터당 하나의 하위 패키지

각 어댑터는 src/apothem/harnesses/<name>/ 아래 자신만의 하위 패키지 안에 살아 있습니다.

  • __init__.py — 프로토콜을 구현하고 형제 액션 모듈에 위임하는 <Name>Adapter 클래스.
  • install.py / uninstall.py / update.py / verify.py — 어댑터 클래스가 임포트하고 호출하는, 액션별 구현.
  • materializer.py — 공유 프로파일을 하니스 네이티브 구성 텍스트로 렌더링하는, 선택적 materialize_native_config(profile) -> str.

각 액션을 자신만의 모듈로 나누면 어댑터 클래스가 얇게 유지됩니다. 그것은 프로토콜 메서드를 액션 함수에 배선하는 디스패처입니다. verify.py를 여는 독자는 정확히 그 하나의 하니스에 대한 표류 탐지 로직만을 보며, 헤쳐 나가야 할 설치나 제거의 잡음이 없습니다.

세 가지 어댑터 클래스

열일곱 개의 하니스가 모두 같은 방식으로 구성을 소비하지는 않습니다. Apothem은 프로파일이 하니스에 닿기 전에 얼마나 많은 변환이 필요한지에 따라 그것들을 세 클래스로 분류합니다.

클래스 I — 원시 전파

하니스는 Apothem이 이미 작성하는 바로 그 산출물 — 평평한 .md 규칙, agents, hooks — 을 렌더링 단계 없이 소비합니다. 어댑터는 원시 템플릿을 하니스의 구성 트리로 복사합니다. 아무것도 렌더링되지 않으므로 materializer.py는 없습니다. 프로파일의 산출물이 곧 출력입니다.

클래스 II-A — 원시에 더해 벤더 템플릿

하니스는 Apothem의 원시 산출물 AND 일련의 벤더 특화 템플릿 파일(하니스가 요구하는 설정, 매니페스트 또는 스캐폴드 파일)을 소비합니다. 어댑터는 원시 산출물과 벤더 템플릿을 함께 복사합니다. 벤더 템플릿은 어댑터 옆 templates/ 디렉터리 아래에 살아 있습니다.

클래스 II-B — 프로파일에서 렌더링

하니스는 공유 프로파일의 구조화된 필드로부터 렌더링된 하나의 네이티브 구성 파일을 원합니다. 어댑터의 materializer.py는 프로파일을 읽고 하니스 네이티브 텍스트를 내보냅니다 — Hermes의 config.yaml, Open-Claw의 openclaw.json, OpenCode의 opencode.json, 또는 Qwen Code의 settings.json. 클래스 II-B는 형식 조정 작업이 집중되는 곳입니다. 규약 수렴 심층 분석 이 이를 자세히 다룹니다.

claude-code: 전체 표면 참조 어댑터

claude-code 어댑터는 가장 넓은 구성 표면 — 규칙, agents, hooks, output-styles, 설정, 그리고 규약 디렉터리 — 를 위한 참조 구현입니다. 그것은 클래스 II-A에 속합니다. Apothem의 원시 템플릿을 전파하고 규약 디렉터리를 평탄화하며, src/apothem/harnesses/claude_code/templates/ 아래에 벤더 설정 템플릿을 함께 실어 보냅니다. 그것은 materializer.py를 지니지 않습니다 — 프로파일에서 네이티브 구성 파일을 렌더링하지 않고, 산출물과 규약 디렉터리를 직접 전파합니다.

하나의 의도된 경계: claude-code 어댑터는 CLAUDE.md를 관리하지 않습니다. 그 파일은 운영자가 소유한 영토입니다. Apothem은 주변의 구성 표면 — 규칙, hooks, 설정 — 을 구체화하고, 운영자 자신의 CLAUDE.md 목소리는 손대지 않고 둡니다. 그것을 덮어쓰는 어댑터라면 매 apothem install마다 손으로 작성한 프로젝트 지시를 지워 버릴 것이므로, 어댑터는 디렉터리 경계에서 선을 긋고 멈춥니다.

균일성이 중요한 이유

이 프로토콜은 운영자에게 열일곱 개의 도구를 가로지르는 하나의 심성 모형을 줍니다. 대상이 단일 파일을 렌더링하든 디렉터리 트리를 평탄화하든, apothem install, apothem verify, apothem uninstall은 똑같은 방식으로 동작합니다. 벤더 차이는 프로토콜 뒤편, 어댑터 하위 패키지 내부 — 그것들이 있어야 할 자리 — 에 살아 있습니다.

운영자를 위한 참조는 하니스에서, 프로파일 모델은 개념에서 읽어 보세요.

On this page