How It Works: Store, Scopes, Links, Ledgers
A scope is one skills directory (user-global ~/.claude/skills/ or a
project's .claude/skills/). The project directory is the environment —
cd is activation. IpMan's job is organization: one stored original per
skill, symlinks wherever it's used, ledgers that can rebuild everything.
The data flow
ip.yaml ──resolve──> central store clone ──pin──> @<commit> worktree
│
ip.lock <──record── commit + tree hash └──symlink── .claude/skills/<name>
The two-layer store
~/.ipman/store/<source-id>/repo/ # live git clone
~/.ipman/store/<source-id>/@<hash12>/ # immutable worktree per pinned commit
repo/is an ordinary, editable git clone. This is where--livelinks point, whereipman updatefetches, and where your bug fixes become commits you can PR upstream. With--adopt,repo/is a symlink to a clone you already had (e.g.~/GitHub/...) — ipman never copies or deletes it.@<hash12>/directories are detached git worktrees, created on demand and locked againstgit worktree prune. They are treated as immutable: two projects can pin the same skill at different commits and coexist, because each pin gets its own worktree.
<source-id> is the normalized URL (github.com/owner/repo) for remote
sources, or a short hash of the absolute path for local ones. Override the
store location with IPMAN_STORE_ROOT.
Links (topology)
One symlink per skill, directly inside each agent's skills directory:
.claude/skills/<name> -> ~/.ipman/store/<id>/@<commit>/<skill-dir> # pinned
.claude/skills/<name> -> ~/.ipman/store/<id>/repo/<skill-dir> # live
- Managed links coexist with your own real skill directories — ipman never
overwrites a real directory, and
ipman doctorreports them as unmanaged. - Managed links are git-ignored via a marked block in
.gitignore;ip.yamlandip.lockare what you commit.
pinned vs live
| pinned (default) | live (--live) |
|
|---|---|---|
| Link target | immutable @<commit> worktree |
editable repo/ working copy |
| Reproducible | exactly, from ip.lock |
best-effort (fresh machines check out the locked commit) |
| Updates | explicit, per-project (ipman update) |
immediate, in every live-linked project |
| Use for | consuming skills | developing / contributing to skills |
Custody (接管目录)
takeover moves a scope's whole skills directory into
~/.ipman/scopes/<id>/content/ and replaces the path with a directory-level
symlink — created once, never repointed. The agent notices nothing (verified
by chain canaries: registration and invocation work through dir-link →
skill-link → read-only snapshot). Value: the scope becomes survivable —
custody link destroyed? ipman sync rebuilds it; store originals are
read-only snapshots a stray rm -rf cannot gut. release reverses it.
Retired: ipman env and the prompt tag
The old virtualenv-style surface (env create/activate + [ip:name] shell
prompt tag) is gone: activation needed source-based shell integration and
couldn't express multi-scope state. Packs replace exclusive environments
(additive, overlapping, per-scope), and status display moved to the agent's
status bar (ipman statusline).