Skip to content

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 --live links point, where ipman update fetches, 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 against git 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.

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 doctor reports them as unmanaged.
  • Managed links are git-ignored via a marked block in .gitignore; ip.yaml and ip.lock are 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).