agarzon/claude-plugins/tree/master/plugins/agarzon
이 mod 소개
claude-plugins
Alexander Garzon의 개인 Claude Code 플러그인 marketplace입니다. 공개 GitHub 저장소이면서 CC marketplace이기도 하며, Claude Code의 기본 autoUpdate를 통해 사용자 지정 스킬, 훅, 테마, 출력 스타일(이후 명령/에이전트/MCP)을 모든 머신에 배포합니다.
설치
claude plugin marketplace add agarzon/claude-plugins
claude plugin install agarzon@agarzon-plugins
~/.claude/plugins/known_marketplaces.json의 agarzon-plugins 항목에 autoUpdate: true를 설정하면 다음 세션에 머신이 새 스킬을 가져옵니다.
스킬, 훅, mod, 테마 또는 출력 스타일 추가
plugins/agarzon/skills/<name>/SKILL.md를 넣습니다(또는output-styles/<name>.md를 넣거나,hooks/hooks.json을 편집하거나,hooks/register.tsx의 mod를 편집합니다).claude plugin validate plugins/agarzon과claude plugin test plugins/agarzon으로 mod를 확인합니다.plugins/agarzon/.claude-plugin/plugin.json의version을 올립니다.- 커밋하고 푸시합니다.
autoUpdate가 있는 머신은 다음 세션에 가져옵니다.
2단계는 선택 사항이 아닙니다. 버전을 올리지 않으면 아무것도 전파되지 않습니다.
구성
handoff/wrap(스킬) — 보류 중인 작업을HANDOFF.md에 저장하고 새 세션에서 계속하거나 하루를 마칩니다. 아래를 참조하세요.- 세션 mod(
hooks/register.tsx) — 프롬프트 캐시 카운트다운과 경고, 출력 스타일 전환기, 컨텍스트 채움 알림, 인계 자동화, 로드된 스킬 목록을 제공합니다. 아래를 참조하세요. - claude-mem 동기화(훅 + 스크립트) — claude-mem 메모리를 머신 간에 맞춥니다. 아래를 참조하세요.
ELI5(출력 스타일) — 지친 머리를 위해 쉬운 단어와 짧은 답을 사용합니다. **agarzon:ELI5**로 선택할 수 있습니다. 플러그인 스타일은plugin:style네임스페이스를 사용하므로 맨ELI5는 아무것에도 연결되지 않습니다./config패널에서 고르거나settings.json에"outputStyle": "agarzon:ELI5"를 설정합니다. 인라인/config outputStyle=자동 완성은 기본 제공 스타일 5개만 제안하므로 이 스타일은 거기에 나타나지 않습니다.output-styles/의 파일은 관례로 선택되며plugin.json키가 필요하지 않습니다.
handoff와 wrap
저장소 루트에 있고 .git/info/exclude로 git에서 제외되는 HANDOFF.md는 세션 사이에서 작업을 전달하는 할 일 목록입니다. 보류 중인 작업만 담고, 항목이 끝나면 제거하며, 비면 파일을 삭제합니다.
/handoff는 파일을 쓰거나 병합한 뒤 mod의handoff_ready도구를 호출합니다. 턴이 끝나면 mod가/rename <name>,/clear,/rename <name>-2를 실행하고 다음 세션에 “Read HANDOFF.md and continue”를 보냅니다. Claude Code는/clear를 넘어 세션 이름을 유지하므로 두 번째 rename으로 기록에서 두 세션을 구분할 수 있습니다./wrap은 같은 파일을 처리하고 하루 마감 작업(커밋, 삭제할 산출물, 메모리 및 vault 업데이트를 한 번에 승인)을 수행한 뒤 세션 이름을 바꾸고 멈춥니다.- 새 세션이
HANDOFF.md를 발견하면 프롬프트 위에 Load / Dismiss를 제공합니다.
세션 mod
mod는 플러그인 훅 모듈입니다. hooks/hooks.json의 modules 아래, 기존 명령 훅 옆에 등록됩니다. 프롬프트 위에 다음 줄을 그립니다.
⧗ cache 42m │ [ Concise ] │ ctx 62% → /handoff
loaded: ponytail·hook 1.3k superpowers·hook 3.3k plugin-authoring 4.9k ×2
- 캐시 카운트다운. 프롬프트 캐시는 1 h 동안 유지됩니다(트랜스크립트에는
ephemeral_1h쓰기만 표시). API 호출을 만든 메인 루프 턴이 끝나면 시계가 다시 시작되고, 서브에이전트 턴과 로컬 명령은 세지 않습니다. 10 min 남으면 토스트와 소리(WSL은powershell.exe, macOS는afplay)가 나옵니다. 0을 지나면 다음 메시지가 입력 가격 2x로 전체 컨텍스트를 다시 캐시합니다. - 출력 스타일. 버튼은
/config의outputStyle행을 순환합니다. 기본 스타일만 제공하므로agarzon:ELI5는 순환 목록에 없습니다. - 컨텍스트 알림. 채움이 60 %에 도달하면 토스트와
ctx표시가/handoff를 제안합니다. - 로드된 목록. 현재 컨텍스트의 모든 스킬 본문과 훅이 주입한 블록을 트랜스크립트에서 읽어 표시하므로
--resume뒤에도 남습니다. 스킬은 시안, 훅은 마젠타, 본문이 두 번 이상 컨텍스트에 있으면 빨간 ×N입니다. 재시작이나--resume에서 발생합니다. Claude Code의 “이미 로드됨” 중복 제거는 프로세스 메모리에 있으므로 다시 호출하면 전체 본문이 주입되고, 입력한/skill도 매번 다시 주입합니다. 복사본을 없애는 것은/compact나 새 세션뿐입니다.
mod API는 아직 얼리 액세스 단계라 릴리스마다 바뀝니다. claude plugin validate는 현재 빌드가 거부할 내용을 보고합니다.
스킬 frontmatter의 allowed-tools는 명령 전용 키입니다. SKILL.md에 넣으면 Execute skill: <name>과 함께 스킬 로드가 실패합니다.
claude-mem 동기화
claude-mem은 머신별 로컬 SQLite 데이터베이스에 메모리를 저장하므로 각 머신이 자기 기록을 쌓고 서로의 기록을 볼 수 없습니다. 이 훅들은 서버 없이 그 틈을 메웁니다.
| 파일 | 역할 |
|---|---|
| hooks/hooks.json | SessionStart → 피어 가져오기 · Stop → 자기 새 행 게시 |
| scripts/mem-sync.sh | 훅 진입점: export | import |
| scripts/mem-export.sh | DB → /api/import 페이로드. 증분은 --since <epoch> |
| scripts/mem-import.sh | 청크 단위, 순서 보장, 재개 가능한 가져오기. --dry-run은 보내지 않고 FK를 확인 |
재개한 세션은 content_session_id를 유지하지만 새로운 memory_session_id를 얻습니다. 한편 sdk_sessions는 content_session_id에 유일 제약이 있으므로, 이미 보유한 세션의 피어 버전은 중복으로 버려지고 그 요약은 외래 키에 실패해 피어의 가져오기를 영구적으로 막습니다. mem-import.sh는 게시하기 전에 들어온 세션 id를 로컬 id로 다시 씁니다. 양쪽이 들어오는 길에 다시 연결하므로 두 머신이 라벨에 동의하지 않아도 괜찮습니다. --dry-run은 이를 잡지 못합니다. FK 검사가 페이로드 내부에서만 이뤄지기 때문입니다.
데이터는 JSON으로 Syncthing을 통해 ~/General/claude-mem-sync/<device>.json에 오갑니다. git은 절대 쓰지 마세요. 이 저장소는 공개되어 있습니다. CLAUDE_MEM_SYNC_DIR로 다른 위치를 지정할 수 있습니다.
파일마다 작성자가 하나인 것이 안전성을 보장합니다. 머신은 자기 <device>.json만 쓰므로 두 머신이 같은 파일을 건드리지 않고 .sync-conflict-*도 생기지 않습니다. 장치 이름은 CLAUDE_MEM_CLOUD_SYNC_DEVICE_NAME, 없으면 claude-mem 설정, 그것도 없으면 hostname -s에서 가져옵니다.
Export는 claude-mem의 읽기 API 대신 SQLite를 직접 읽습니다. 읽기 API는 약 200행에서 막히고 세션 id를 다시 써서 자신의 출력이 재가져오기 때 외래 키에 실패하기 때문입니다. Import는 worker의 POST /api/import를 거치므로 중복 제거, 트랜잭션, FTS 트리거는 공급업체가 처리합니다.
동기화는 세션을 막지 않습니다. 모든 경로는 0으로 끝나고 문제는 ~/.claude-mem/logs/mem-sync.log로 갑니다.
허용되는 한계. 추가만 가능하며 삭제와 제목/프로젝트 편집은 전파되지 않습니다. 두 머신에서 같은 작업을 해도 두 번 남습니다. 중복 키가 세션 id이고 머신마다 다르기 때문입니다. 가져온 뒤 세션 하나당 요약은 하나만 남습니다. 임베딩은 동기화하지 않으며 Chroma는 머신별 로컬입니다.
한 번만 수행하는 통합
서로 달라진 머신에 초기 상태를 심으려면 훅을 우회하고 스냅샷을 직접 병합합니다.
mem-export.sh --db <snapshot>.db --out peer.json
mem-import.sh peer.json --dry-run # expect 0 orphans
mem-import.sh peer.json
sqlite3 <db> ".backup <out>"로 스냅샷을 만듭니다. 데이터베이스는 WAL 모드이고 쓰기 작업이 진행 중이므로 cp는 찢어진 상태를 가져올 수 있습니다.
그 다음 각 머신에 워터마크를 시드해 첫 Stop 훅이 이미 공유된 이력을 다시 보내지 않고 새 작업만 게시하도록 합니다.
date +%s000 > ~/.claude-mem/mem-sync.watermark
이를 건너뛰면 첫 export가 머신이 가진 모든 행을 게시합니다. 맞는 동작이지만 첫 동기화가 불필요하게 커지고, 각 피어가 다시 가져온 뒤 건너뜁니다.
전체 설계와 이유는 docs/design.md를 참조하세요.
설치
먼저 작성자의 README에서 marketplace와 플러그인 이름을 확인하세요. 저장소 구조에 따라 명령어가 달라질 수 있습니다.
claude plugin marketplace add agarzon/claude-plugins claude plugin install agarzon
원문 / README
claude-plugins
Alexander Garzon's personal Claude Code
plugin marketplace. A public GitHub repo that doubles as a CC marketplace,
distributing custom skills, hooks, themes and output styles (and later
commands/agents/MCP)
across all machines via Claude Code's native autoUpdate.
Install
claude plugin marketplace add agarzon/claude-plugins
claude plugin install agarzon@agarzon-plugins
Set autoUpdate: true for the agarzon-plugins entry in
~/.claude/plugins/known_marketplaces.json so machines pull new skills on the
next session.
Add a skill, hook, mod, theme, or output style
- Drop
plugins/agarzon/skills/<name>/SKILL.md(oroutput-styles/<name>.md, or edithooks/hooks.json, or the mod inhooks/register.tsx; check a mod withclaude plugin validate plugins/agarzonandclaude plugin test plugins/agarzon). - Bump
versioninplugins/agarzon/.claude-plugin/plugin.json. - Commit and push. Machines with
autoUpdatepull it on the next session.
Step 2 is not optional — without a version bump nothing propagates.
Contents
handoff/wrap(skills) — save pending work toHANDOFF.mdand continue in a fresh session, or close the day. See below.- Session mod (
hooks/register.tsx) — prompt-cache countdown and warning, output-style switcher, context-fill nudge, handoff automation, and the list of loaded skills. See below. - claude-mem sync (hooks + scripts) — keeps claude-mem memory in step across machines. See below.
ELI5(output style) — small words, short answers, for a fried brain. Selectable asagarzon:ELI5— plugin styles are namespacedplugin:style, and bareELI5resolves to nothing. Pick it in the/configpanel, or set"outputStyle": "agarzon:ELI5"insettings.json. Note that the inline/config outputStyle=completion only offers the five built-ins, so this style never appears there. Files inoutput-styles/are picked up by convention; noplugin.jsonkey needed.
handoff and wrap
HANDOFF.md, at the repo root and kept out of git through .git/info/exclude, is the
to-do list that carries work between sessions. It holds only pending work: each item is
removed when done and the file is deleted when empty.
/handoffwrites or merges the file, then calls the mod'shandoff_readytool. When the turn ends the mod runs/rename <name>,/clear,/rename <name>-2, and sends the next session "Read HANDOFF.md and continue". Claude Code carries a session's name across/clear, so the second rename keeps the two sessions apart in history./wrapdoes the same file plus the end-of-day chores (commits, artifacts to delete, memory and vault updates, approved in one batch), renames the session and stops.- A new session that finds a
HANDOFF.mdoffers Load / Dismiss above the prompt.
Session mod
A mod is a plugin hooks module: hooks/hooks.json lists it under modules, next to the
classic command hooks. The row it draws above the prompt:
⧗ cache 42m │ [ Concise ] │ ctx 62% → /handoff
loaded: ponytail·hook 1.3k superpowers·hook 3.3k plugin-authoring 4.9k ×2
- Cache countdown. The prompt cache lives 1 h (transcripts show only
ephemeral_1hwrites). The clock restarts when a main-loop turn that made an API call completes; subagent turns and local commands do not count. At 10 min left: a toast and a sound (powershell.exeon WSL,afplayon macOS). Past zero the next message re-caches the whole context at 2x input price. - Output style. The button cycles the
/configoutputStylerow. It offers only the built-in styles, soagarzon:ELI5is not in the rotation. - Context nudge. At 60 % fill, a toast and the
ctxmarker suggest/handoff. - Loaded list. Every skill body and every hook-injected block in context now, read
from the transcript so it survives
--resume. Skills cyan, hooks magenta, red ×N when a body is in context more than once. That happens across a restart or--resume: Claude Code's "already loaded" dedupe lives in process memory, so a re-invocation injects the whole body again, and a typed/skillre-injects every time. Only/compactor a fresh session removes the copies.
The mod API is early access and changes between releases; claude plugin validate
reports anything the running build would refuse.
allowed-tools in a skill's frontmatter is a command-only key; adding it to a
SKILL.md makes the skill fail to load with Execute skill: <name>.
claude-mem sync
claude-mem stores its memory in a local SQLite database per machine, so each machine accumulates its own history and none of them ever see each other's. These hooks close that gap without a server.
| File | Role |
|---|---|
| hooks/hooks.json | SessionStart → import peers · Stop → publish own new rows |
| scripts/mem-sync.sh | the hook entry point: export | import |
| scripts/mem-export.sh | DB → /api/import payload. --since <epoch> for incremental |
| scripts/mem-import.sh | chunked, ordered, resumable import. --dry-run does an FK check without sending |
A resumed session keeps its content_session_id but gets a new
memory_session_id, while sdk_sessions is unique on content_session_id — so a
peer's version of a session you already hold is dropped as a duplicate and its
summaries then fail the foreign key, jamming that peer's import permanently.
mem-import.sh rewrites incoming session ids to the local ones before posting.
Each side relinks on the way in, so the two machines disagreeing about the label
is harmless. --dry-run cannot catch this: its FK check is payload-internal.
Data travels as JSON in ~/General/claude-mem-sync/<device>.json over
Syncthing — never git, this repo is public. Set
CLAUDE_MEM_SYNC_DIR to point elsewhere.
One writer per file is what makes this safe: a machine only ever writes its
own <device>.json, so no two machines touch the same file and
.sync-conflict-* cannot happen. Device name comes from
CLAUDE_MEM_CLOUD_SYNC_DEVICE_NAME, else claude-mem's settings, else hostname -s.
Export reads SQLite directly rather than claude-mem's read API, which caps out
near 200 rows and rewrites session ids such that its own output fails the
foreign key on re-import. Import goes through the worker's POST /api/import
so dedupe, transactions and FTS triggers stay the vendor's problem.
Sync never blocks a session: every path exits 0 and problems go to
~/.claude-mem/logs/mem-sync.log.
Accepted ceilings. Append-only — deletions and title/project edits do not propagate. Identical work done on two machines survives twice, because dedupe keys on session id and those differ per machine. Only one summary per session survives an import. Embeddings never sync; Chroma is local per machine.
One-time consolidation
To seed machines that have been drifting apart, bypass the hooks and merge snapshots by hand:
mem-export.sh --db <snapshot>.db --out peer.json
mem-import.sh peer.json --dry-run # expect 0 orphans
mem-import.sh peer.json
Take snapshots with sqlite3 <db> ".backup <out>" — the database is WAL-mode
with a live writer, so cp can capture a torn state.
Then seed the watermark on each machine so the first Stop hook publishes
only new work instead of re-shipping the history the machines already share:
date +%s000 > ~/.claude-mem/mem-sync.watermark
Skip this and the first export publishes every row the machine holds — correct, but a needlessly large first sync that every peer then re-imports and skips.
See docs/design.md for the full design and rationale.

