Changelog
Each release below lists the changes you can see or act on. Releases that need action from you end with migration notes. If you skip a release when you upgrade, read its migration notes too.
0.9.0 - 2026-09-27
Highlights
- Catalogs choose where usage metrics go. A catalog that names an address in
metrics_urlin itscatalog.yamlreceives anonymous usage counts from everyone who has it. Usage metrics are on until you turn them off, and SkillCatalog has no address of its own. - Delivery skips only what it cannot deliver. When a profile or skill cannot be delivered, SkillCatalog still delivers the rest, lists what it skipped, and exits 25 with
delivery-failed. - A desktop save publishes only what you saved. On a direct catalog, a save commits and pushes the files of the item you saved. Other changes in the clone wait for Sync.
- Review-branch syncs keep your work. Sync sends commits left on the primary branch as a proposal, merges a later edit into a waiting proposal, and puts your edits back when the Git host refuses a push.
- Skills for a second folder.
skc install --target-dir <folder>delivers a checkout's skills into another folder. - Matching files are taken over only when you ask. Delivery no longer takes over a file it did not write, even one that matches.
skc deliver --adopt-matchingdoes it on request.
Several exit codes changed. If your scripts check them, read the migration notes at the end of this release before you upgrade.
Added
skc install --target-dir <folder>delivers a checkout's skills into another existing folder, and laterskc install,skc deliver, andskc updateruns keep delivering there.skc profile showprints aDelivers to:line for such a profile, and the desktop Delete profile dialog names the folder. The JSON output ofskc profile list,show,create,add,remove, andreorderaddsdelivery_directory. See Use the skills in a second checkout.- A catalog can collect anonymous usage counts. When its
catalog.yamlnames an address inmetrics_url, everyone who has the catalog sends counts there while usage metrics are on. SkillCatalog asks nothing first. The address receives counts about its own catalog and that catalog's skills, stacks, and bundles, named by catalog id and slug, and how often eachskcand desktop command ran, with its outcome and duration. It never receives counts about another catalog. See Usage metrics. skc catalog add <url> --metrics-url <address>, or the Metrics address field of the desktop Add Catalog dialog, writes the address into thecatalog.yamlthat the add creates for an empty repository. For a repository that already has a catalog, the add succeeds without it and warns how to set it by hand. When you add a catalog that names an address while usage metrics are on,skc catalog add,skc install,skc update, and the desktop app show the address. JSON output addsmetrics_urleither way.skc validate --pathwarns whenmetrics_urlis not a valid address. SkillCatalog ignores such a value, so no counts are sent for that catalog.skc settings telemetryand the desktop Settings page list the catalogs that have a metrics address.skc settings telemetry --disable, or turning off Send usage metrics in Settings, stops sending from both the desktop app andskc, and--enableturns it back on. SkillCatalog ignores everyOTEL_EXPORTER_OTLP_environment variable.- A
validation:map incatalog.yamlturns each of the four advisory content checks on or off for the whole catalog. Theskillcatalog/validationmetadata key in a skill'sSKILL.mdoverrides the catalog's choice for that skill. See Check a skill before you share it. - In a
SKILL.md,\@skill-dirand\@skill:<slug>stay plain text: delivery removes the backslash and replaces nothing, andskc validatedoes not check them. See Refer to other skills. skc validatereports leftover Git conflict markers in aSKILL.md, outside fenced code blocks, asvalidation.conflict-markers, and a symbolic link in a skill folder ascatalog-integrity-error. Both are errors, so they also stop commits to the catalog. See A commit stops on leftover conflict markers.skc validate,skc status, andskc deliver --dry-runreport two entries in one profile that deliver the same skill. Theskc validatefinding isprofile-slug-conflict.skc syncwarns about each catalog that has recovery files from syncs that did not finish.skc profile addandskc installwarn when nothing was delivered because no AI tool is turned on. Both warnings go to standard error. See Recover unpublished changes.skc catalog list --jsonaddslast_synced_at, the timeskc synclast synced each catalog.
Changed
- Interactive
skc syncshows each catalog's changed files and asks for that catalog's own commit message. If the files change before it commits, it shows them again. Without a terminal and without--message, sync refuses and lists each changed catalog and its files, inerror.details.dirty_catalogsin JSON output. - When some profiles or skills cannot be delivered, delivery delivers the others, lists the rest, and exits 25 with
delivery-failed. This covers an entry whose item is gone, a missing checkout or--target-dirfolder, a symbolic link in a skill folder, and a catalog whose proposal state is unknown. A skipped skill keeps the copies delivered earlier.skc deliverexits 43, 44, or 45 only when no profile with entries can be delivered. This applies toskc deliver,skc sync,skc install,skc update, and the desktop app. 0.8.1 delivered nothing in these cases. skc syncalso exits 25 when its delivery reports conflicts or failed items, andskc deliver --dry-runexits 25 when the delivery would skip a profile or skill, or two entries would deliver the same skill. Both exited 0 in 0.8.1.- Delivery no longer takes over a file it did not write when the file is exactly what it would write. It reports the file as
unmanaged_target_existsand namesskc deliver --adopt-matching, which takes over such files and never overwrites a file with different content.skc deliver <profile-id> --adopt-matchingworks on one profile. The desktop Replace and deliver card says it takes these files over, and it also appears when other items failed. See A skill folder already exists. - Delivery refuses a tool's skills folder that is a symbolic link, such as
~/.claude/skillslinked to~/.agents/skills, also with--adopt-matching. Each file of that tool is reported asunsafe_parent_path. 0.8.1 took over matching files through the link. - Delivery skips
.DS_Store, files ending in.pyc,.pyo,.pyd,.swp, or~, anything under__pycache__,.git, ornode_modules, and files that Git ignores in the catalog. It stops with an error when a selected skill'sSKILL.mdis Git-ignored. See Skill folders. - A desktop save on a direct catalog commits and pushes only the files of the item you saved, and says how many other changed files wait for Sync. The save stops when an unsynced change touches the item's own files, or when the item uses a skill, stack, category, owner, or tag that is not synced yet. 0.8.1 committed every change in the clone. See What a desktop save does.
- On a review-branch catalog,
skc syncsends the commits on the primary branch that the Git host lacks as one proposal, then moves the primary branch back to the host's version. When those commits are all it sends, it reportspush pushed. When they conflict with the host, sync stops and prints agit reset --softcommand that turns them into a proposal. 0.8.1 neither pushed nor reported them. - After you remove a catalog in the desktop app, the profile entries that use it stay, marked Unavailable. Until you remove them, their profiles are not delivered and
skc deliverandskc syncfail. Other profiles are still delivered. 0.8.1 deleted those entries the next time the app started. skc updateand a repeatedskc installadd any catalog that the team manifest names and this machine lacks, as a first install does, andskc update --checkreports it withmissing-registered-catalog-id. Both commands printRegistered catalog '<id>' ...for each catalog they add, also on a first install and when the run fails later. The JSON output of a successfulskc installalways hasdata.registered_catalogs. See Update a checkout.skc profile addrefuses an item that its catalog does not have, withskill-not-found,stack-not-found, orbundle-not-found, and says when the slug exists as another kind. 0.8.1 saved the entry, which then stopped the delivery of every profile.skc skill listlists the skills it can read, exits 0, and warns on standard error about each skill it cannot read, which its JSON output lists ininvalid_items. The desktop Skills page shows an error row for each. 0.8.1 failed when one skill could not be read.- The date and version check,
validation.time-sensitive.outside-old-patterns, reportsinfofindings, which never failskc validateor makeskc statusreport inconsistent state. It ignores bare numbers such as2048and text inside code. - The check before each commit to a catalog no longer checks delivered copies, so an edited delivered file does not stop commits. Catalogs added from the desktop app run the check too, from their next sync or save. When the check fails, its advice matches the failure.
- A missing
stacks/orbundles/folder counts as empty everywhere, including inskc validate --path. A catalog still needsskills/. skc skill improvepreviews a diff ofSKILL.md, with three unchanged lines around each change, in place of the whole old and new file.skc skill score-history <slug> --repairkeeps the originalSCORE.jsonin~/.skillcatalog/score-history-backups/<catalog-id>/<slug>/. 0.8.1 wrote it into the skill's folder, where delivery and sync picked it up. The error for an oversizedSCORE.jsonnames--repair.- Log files show skill and catalog names as short codes, such as
rev~a1deb48cb5, that differ between installations. Catalog ids, file paths, and Git's error output still appear in full, so read a log before you share it. See Find and share logs. - The Essentials catalog's skills describe 0.9.0. They tell AI agents to sync, publish, remove a catalog, apply an improvement, or delete content only when you ask. SkillCatalog updates your copy of the catalog automatically.
- Several commands report different exit codes and outcomes, such as
skc update --check,skc deliver --check, andskc profile add. The table in the migration notes lists every case.skc installno longer reportscatalog-removed(exit 22), and no command reportsprofile-catalog-binding-missing,profile-child-catalog-binding-forbidden, orprofile-catalog-conflict, which nothing raised. skc profile reorder <profile-id> --entrytakeskind:catalog-id:slug, the same form asskc initandskc profile create. Thecatalog-id:kind:slugform of 0.8.1 still works.
Fixed
- The desktop editors say whether a save was published or saved as a proposal waiting for review. When delivery fails after a save, the message says the change was saved and gives the hint "Run Sync to retry delivery." When the push fails after the commit, the message says the change is saved on this computer and that Sync publishes it. 0.8.1 said every save stayed local until you synced, and that a failed push would be retried, which nothing did.
- On review-branch catalogs, the desktop editors open a skill, stack, or bundle that exists only in a pending proposal, and saving updates that proposal. The stack and bundle editors offer only merged skills and stacks as new members, plus the ones the draft already contains. A save from a clone on another branch names both branches and tells you to switch back, and the Catalogs page shows the primary and review branches, which 0.8.1 showed as
undefined. - In the desktop editors, switching catalogs with unsaved changes asks before discarding them, and clearing a skill's category or an item's owner saves the change. The History tab of a stack or bundle lists the changes to its
.yamlfile. The drift confirmation says that Deliver recreates deleted files and keeps edited ones, where 0.8.1 said your edits would be lost. - While a proposal waits,
skc syncmerges a later edit of the same file into the proposal's version. When both change the same lines, sync stops and puts your edit back in the clone. 0.8.1 replaced the proposal's copy of the file, so the proposal lost its earlier changes. See What a save does. - When the Git host refuses a proposal's push,
skc syncputs your edits back in the clone, uncommitted, so a later sync publishes them. 0.8.1 left them on a local branch that no later sync pushed. On review-branch catalogs, sync also stops while the clone has an unfinished merge, rebase, or cherry-pick. - A push that the Git host refuses shows the host's reason, in the text of
skc sync, inpush.messageof its JSON output, and in the desktop Sync Center under Show exact catalog and delivery records. 0.8.1 showedup_to_dateor a generic error. - A review-branch sync that sends your edits as a proposal reports
push proposaland the branch, and the desktop Sync Center says each change went out as a proposal on its own branch.skc proposal listandskc proposal showprint each proposal's status, such aspending review,closed, orstatus unknown, andskc proposal showfinds a proposal after its catalog switched back to direct. 0.8.1 printedpush nothing to push, and(pending review)for every proposal. - On review-branch catalogs, applying an improvement (
skc skill improve --applyor--apply-proposal, or the desktop app) pushes it as a proposal, and delivery uses the catalog's currentSKILL.mduntil the proposal is merged. 0.8.1 wrote the improvement into your clone before review. Applying an improvement also rejects an improvedSKILL.mdwhose metadata SkillCatalog cannot read, before writing anything. - When a sync cannot commit, for example because a pre-commit hook rejects the commit, it restores exactly what was staged in your clone. 0.8.1 left partly staged files fully staged.
skc catalog remove <catalog-id> --forceremoves a registration that SkillCatalog cannot read, such as one without a source URL, and keeps the catalog's local files and the profile entries that use it. In 0.8.1 this command failed with the same error that told you to run it.skc catalog removealso counts the entries in a checkout's local manifest, and its hint lists oneskc profile removecommand for each entry.- Deleting a skill, stack, or bundle in the desktop app removes only that item's entries from your Home and personal profiles, after a delete on a direct catalog or after you discard a proposal that created the item. 0.8.1 also removed unrelated entries, such as Unavailable and misspelled ones. An entry that stays, for example after a delete on a review-branch catalog, stops its profile's delivery once the item is gone, so remove it yourself.
- When delivery removes a skill, it also removes the skill's empty folder from each tool's skills folder.
- After
skc uninstallkept a file you edited, a laterskc installin the same checkout keeps the edit and lists it as preserved. 0.8.1 failed withunmanaged_target_exists. - Error messages name what went wrong. A pull conflict names each file that Git could not merge,
another-sync-runningnames the busy catalog, andskc catalog addexplains a repository that has commits but nocatalog.yaml.skc proposal verify-cleannames each problem, and fails when the clone is not on the primary branch, has a detached HEAD, or has a primary branch ahead of or behindorigin. Messages no longer show internal names, andskc update --help,skc sync --help, andskc deliver --helpshow the full help. - Sharing a skill in the desktop app ignores its
SCORE.json, so an unsynced score no longer stops the link. - The desktop log preview and log package replace paths under
/private/tmp,/private/var/folders, and/Volumeswith markers, and in most cases hide the rest of a path after a space in a folder name. 0.8.1 showed those paths in full.
Security
- HTTPS connections from the desktop app and
skc, such as the desktop update check and usage metrics, use rustls 0.23.45, which fixesRUSTSEC-2026-0285. skc syncand desktop saves refuse a catalog clone whose own Git data is damaged, and change nothing. When such a clone was inside another repository, such as a dotfiles repository in your home folder, 0.8.1 committed the change there and pushed it to that repository's remote.- When SkillCatalog syncs, saves, or publishes, its Git commands ignore
GIT_DIR,GIT_WORK_TREE, and other environment variables that point Git at another repository, so a shell or hook that sets them cannot redirect sync, saves, or proposals.
Migration from 0.8
- Usage metrics. A catalog whose
catalog.yamlnames a metrics address receives anonymous usage counts from everyone who has the catalog, without asking.skc settings telemetryand the desktop Settings page list these catalogs. To stop sending, runskc settings telemetry --disable, or turn off Send usage metrics in Settings. - Validation results. Date and version findings are
infoinstead of warnings, soskc validateandskc statuspass when these are the only findings. Scripts that readseverityfromskc validate --jsonmust acceptinfo. With--quiet, a report that has onlyinfofindings prints nothing. - Delivered files. The first delivery after you upgrade removes the files that 0.9.0 skips from your tools' skills folders, unless you edited them. If a skill needs a file that Git ignores in the catalog, stop ignoring it.
- Sync prompts. Interactive
skc syncasks for one commit message per changed catalog. To use one message for all of them, pass--message. - Removed catalogs. After you remove a catalog in the desktop app, remove the profile entries marked Unavailable, or add the catalog again. Until you do, the profiles with those entries are not delivered, and
skc deliverandskc syncfail. - Files that match but were not delivered. Delivery does not take over a file it did not write, even one that matches the catalog's version. After a lost delivery record, or with a skill folder copied by hand, delivery reports those files as
unmanaged_target_exists. Runskc deliver --adopt-matchingto take them over. - Linked skills folders. When a tool's skills folder is a symbolic link, as when
~/.claude/skillspoints to~/.agents/skills, delivery fails for that tool, also with--adopt-matching. Remove the link, then runskc deliver, which delivers a separate copy into each tool's folder. - Old repair backups. In 0.8.1,
skc skill score-history <slug> --repairleft aSCORE.json.repair-backup-<number>.jsonfile in the skill's folder. Delivery cannot read such a large file and stops for every profile. Move each one out of the catalog, then sync. See SCORE.json is too large to read. - Checks before each commit. A
SKILL.mdwith leftover conflict markers, or a skill folder with a symbolic link, failsskc validateand stops every commit to its catalog. In a catalog added from the desktop app, the check starts at its next sync or save. After you upgrade, runskc validateand fix what it reports before you sync. - Going back to 0.8.1. SkillCatalog 0.8.1 cannot read a project profile installed with
--target-dir, and then fails to deliver any profile on that machine. Before you downgrade, runskc uninstallwith 0.9.0 in that checkout. - Teammates on 0.8.1. SkillCatalog 0.8.1 cannot read a skill whose
SKILL.mdsetsskillcatalog/validation, so its deliveries that include the skill fail. It ignoresvalidation:andmetrics_url:incatalog.yaml, and its desktop app drops both keys when it saves a category, owner, or tag change. Upgrade everyone who uses a catalog before you add these keys to it. - Scripts. Scripts that check exit codes or outcomes must handle the changes below. See Exit codes.
| Command and case | 0.8.1 | 0.9.0 |
|---|---|---|
skc deliver: some profiles or skills cannot be delivered | 43 or 45, nothing delivered | 25 delivery-failed, the rest delivered |
skc sync: its delivery reports conflicts or failed items | 0 | 25 delivery-failed |
skc deliver --dry-run: the delivery would skip a profile or skill, or two entries would deliver the same skill | 0 | 25 delivery-failed |
skc deliver, skc install, skc update: a file matches the catalog's version, but SkillCatalog did not write it | 0, file taken over | 25 delivery-failed |
skc update --check: delivery would skip skills | 0 | 25 delivery-failed |
skc update --check: a file matches the catalog's version, but SkillCatalog did not write it | 0 | 24 delivery-blocked |
skc update, or a repeated skc install: the team manifest names a catalog this machine has not added | 17 or 22 | 0, catalog added |
skc deliver --check: a checkout is missing | 19 | 26 delivery-check-drift |
skc deliver: a Home profile stores a team manifest path | 19 manifest-missing | 24 home-profile-parent-metadata |
skc profile add: the catalog lacks the item | 0 | 10 skill-not-found, stack-not-found, or bundle-not-found |
skc profile add, remove, or reorder: an argument mistake on a project profile | 24 manifest-malformed | 10 user-input-invalid |
skc profile delete: the profile does not exist | 24 profile-write-failed | 10 profile-not-found |
skc init: no terminal, and required flags are missing | waits for input | 10 user-input-invalid |
skc skill list: a skill cannot be read | 23 catalog-read-failed | 0, the skill listed in invalid_items |
skc sync: a busy lock stops a review-branch commit | 44 | 34 another-sync-running |
skc help-json: the reader stops early | 70 internal-error | 0 |
0.8.1 - 2026-07-26
Changed
- A repeated
skc installpulls the catalogs that the checkout's team and local manifests declare before it delivers. A first install does the same when it did not need to clone any of them. If a pull fails, install stops withcatalog-refresh-failedbefore it saves the profile or delivers. A pull also fails when a review-branch catalog's clone is not on its primary branch. skc install,skc update, andskc deliverreportmanifest-changedwhen the team manifest changes while they run and they have written nothing, so you can run them again. When one of them, orskc profile add,remove, orreorder, has already written something, it reports an outcome that starts withchanged-after-. The rest of the name says what it wrote. See Exit codes.- The Essentials catalog's skills are corrected where they did not match SkillCatalog, and SkillCatalog updates your copy of the catalog automatically.
Fixed
skc validateignores SkillCatalog's own~/.skillcatalog/profiles/.committed-profile-locksfolder. 0.8.0 reported it as a broken profile.
0.8.0 - 2026-07-14
Added
- A local manifest,
.skillcatalog/skillcatalog.local.yml, holds your own changes to a checkout's project profile: extra entries, and underexcludes:, team entries you do not want. See Make personal changes. skc profile add,skc profile remove, andskc profile reorderon an installed project profile write to the local manifest and never change the team manifest. Removing a team entry adds it toexcludes:.- SkillCatalog adds
.skillcatalog/skillcatalog.local.ymland.skillcatalog/.skc-recovery/to the checkout's.gitignorewhen it writes the local manifest. skc profile show <profile-id> --effectivelists the local manifest entries, the team manifest entries marked as shadowed or excluded, and the entries that SkillCatalog delivers.skc validatewarns withlocal-exclude-no-matchabout an exclusion that matches no team entry.- In the desktop app, a project profile shows the team manifest's entries as Inherited, and you can exclude them.
Changed
skc initwrites the team manifest to.skillcatalog/skillcatalog.yml. A root-levelskillcatalog.ymlkeeps working while the new file does not exist. If both exist, commands stop with an error.skc profile show <profile-id> --effectivereplaces itsInherited parent entrieslist withLocal manifest entriesandTeam manifest entries. In its JSON output, team entries haveorigin: "team"instead of"inherited".- The JSON output of
skc profile show <profile-id> --effectiveaddslocal_profile,team_profile, andexcluded_by_local, and keepsinherited_profileas an alias ofteam_profile.
Migration from 0.7
- Scripts. Scripts that read
originfromskc profile show <profile-id> --effective --jsonmust accept"team". - Personal entries. Entries you added to an installed project profile move into
.skillcatalog/skillcatalog.local.ymlthe next time SkillCatalog installs, updates, delivers, or changes that profile. - Team manifest location. A root-level
skillcatalog.ymlkeeps working. To move it, move the file to.skillcatalog/skillcatalog.ymland commit the move. Installed profiles follow it.
Earlier releases
Releases before 0.8.0 are on the SkillCatalog releases page.