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=补全只提供五个内置样式,因此这里的样式不会出现在其中。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保留,因此第二次重命名能让两个工作阶段在历史记录中保持区分。/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)。超过零后,下一条消息会以 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。
导出会直接读取 SQLite,而不是调用 claude-mem 的读取 API;后者最多只能处理接近 200 行,并会改写工作阶段 id,使自身输出在重新导入时无法通过外键检查。导入通过 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
跳过这一步后,第一次导出会发布机器持有的每一行——这是正确的,但第一次同步会不必要地变大,而每个对等端随后都会重新导入并跳过这些内容。
完整设计和理由见 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.

