~/.agents/skills, and records what it installed in a lock file. agentx adopt reads that file and takes those skills over: each one keeps its directory exactly as it is and gains an upstream, so agentx can tell your edits from the version you installed.
agentx only ever reads the lock file. It is never written, not on a successful run and not on a failed one.
See what can be adopted
Adopt them
--skill, once for each:
agentx source add would, and pins it to the branch or tag the lock file recorded. Then it records the version each skill was installed at and points that skill’s import branch at it. A source you removed comes back this way too, and the skills you installed from it no longer show source removed.
A source holds one pin, so when its skills were installed from different refs agentx takes the first in name order and warns you:
What is recorded as the base
The base is the upstream version you installed, not the files on your disk. That distinction is the whole point: with it, an edit of yours stays an edit, and a later update or revert knows what came from upstream and what came from you. agentx establishes the version in one of these ways, and never guesses. Each is tried in turn, and a skill is left unmanaged only when none of them reaches a version:- The folder hash in the lock file. It is the id of a directory in the source, so agentx looks that directory up in the source itself, at the version you fetched and back through the history of that skill. Finding it proves the content, because a git id names one set of bytes and nothing else. This works even when the skill has since been deleted from the source: its version is in the history, which is exactly where agentx looks. Some installs record a hash of their own instead, which names nothing in the source; agentx then moves on to the next way.
- Your directory already is the current version. If the files match the source exactly, they are an upstream version rather than an edit of one, and agentx records that version.
- You name it yourself, with
--base.
--base. It is the commit an install of that version records too, so two machines that adopt the same install, or one that adopts it and one that installs it, write the same import commit, whenever each of them last fetched the source.
Your directory is never changed, whichever way the version was found. If it differs from the base, agentx says so and agentx skill list shows the skill as modified. See what differs with agentx skill diff <name>, and discard it with agentx skill revert <name>.
When the version cannot be established
--base, the one way to adopt it anyway, or leave it unmanaged.
Choose the base yourself
If you know which version you installed, name it:--base takes a commit id, a branch or a tag of the source, and it takes one --skill. A branch or a tag is resolved against the source itself, so name the version the way the repository publishes it; git ls-remote <url> lists what it has. The version it records is still read from the source; what it changes is which version you call your starting point. Your directory is left as it is, and the difference from that base becomes your local modification.
A version that is not in the history the source follows is refused: a version of another repository is not a version of this one, and neither is a branch or a tag of this one that your pin does not reach. Add the source at the ref you want first:
Leave it unmanaged
If you do not know the version, leave the skill as it is. It stays in your library and keeps its placements, so every client that saw it still does, andagentx skill list shows it as unmanaged. agentx keeps it in the inventory but never updates or reverts it.
To adopt it later, name its base:
What is refused, and why
One bad entry never costs the others: the rest of the run is adopted, and the failures are named at the end.
Where the lock file is read
agentx reads both places that tool uses:$XDG_STATE_HOME/skills/.skill-lock.json, or~/.local/state/skills/.skill-lock.jsonwhen that variable is unset~/.agents/.skill-lock.json
skills object, stops the command rather than being treated as empty: you asked to adopt what it holds, so agentx will not tell you it holds nothing. Fix it or move it aside; agentx will not write it for you.
Inside the file, one bad entry never costs the others. An entry is skipped only when it is not an object or names no source; a single field written as the wrong kind of value is dropped with a warning naming it, and the entry is read without it.