Docs

How skills management works

The mental model behind pncli skills — where skills come from, where they go, how they stay current, and how private marketplaces authenticate.

This page is generated from skills/pncli/skills-guide.md — the same text pncli skills guide prints in your terminal, and that agents get inside the installed pncli skill.

pncli puts skills — folders of instructions an AI coding agent loads on demand — where your agents will find them, and keeps them current. Read this once; after that, pncli skills --help and pncli doctor cover the day-to-day.

Print any section on its own with pncli skills guide <section> (for example pncli skills guide auth). pncli skills guide --sections lists them all.

The big picture

Skills reach your machine from two sources, and both end up in the same place:

How skills reach your agents The bundled pncli skill (installed with pncli skills install) and org marketplace plugins (installed with marketplace add and sync) both land in the agent skills directories, where Codex, GitHub Copilot and Claude Code read them. Marketplaces can also ship AGENTS.md and CLAUDE.md, merged into user-level instruction files. pncli (npm package) bundled “pncli” skill · versioned with pncli Your org’s marketplace repo plugins → skills · AGENTS.md / CLAUDE.md pncli skills install marketplace add · sync private? git-auth + keychain Agent skills directories .agents/skills .github/skills .claude/skills project scope in the repo · user scope in ~ · each skill stamped with provenance Instructions AGENTS.md / CLAUDE.md marked block read Codex GitHub Copilot Claude Code every host
Two sources, one destination. pncli skills status traces any skill back to where it came from.
  • The bundled skill is pncli's own command reference. It ships inside the npm package, so it changes when pncli does.
  • Marketplace plugins are your org's skills, published in a git repository. pncli clones the repo once and pulls it whenever you sync.
  • Every skill pncli installs is stamped with provenance — where it came from and which pncli version put it there. That is how status, sync, and doctor can tell your org's skills, pncli's own, and anything you dropped in by hand apart.

Agent hosts and where skills live

Each agent host reads its own directories. --agent picks one; --all-agents covers every host in one run.

--agentProject scopeUser scopeRead by
codex (default).agents/skills~/.agents/skillsCodex and GitHub Copilot
github-copilot.github/skills~/.copilot/skillsGitHub Copilot
claude-code (--claude).claude/skills~/.claude/skillsClaude Code

Project scope lives in the repository — commit it and everyone who clones the repo gets the skills. User scope lives in your home directory and applies to every repository on the machine.

  • The bundled skill installs at project scope by default. Add --scope user to have it everywhere.
  • Marketplace plugins always install at user scope. They are org-wide, not repo-specific.

pncli skills locations prints every one of these paths with a count of what's in it.

The bundled pncli skill

pncli skills install --all-agents                # this repo, every agent host
pncli skills install --all-agents --scope user   # every repo on this machine

The bundled skill is versioned with pncli. After npm update -g @kolatts/pncli, the copies on disk are one version behind; pncli doctor flags them as stale, and re-running pncli skills install refreshes them.

Marketplaces

A marketplace is a git repository your org publishes plugins from. The lifecycle is:

  1. Add — register, clone, and install every plugin: pncli skills marketplace add https://ghe.imagile.dev/ai/skills.git --all-agents
  2. Sync — pull the latest and refresh what you already have. With no arguments this is non-interactive, which makes it safe for a login script or a scheduled task: pncli skills marketplace sync --all-agents
  3. Browse — see what's there without installing anything: pncli skills marketplace plugins internal-ai
  4. Pick up something new — plain sync only refreshes plugins you already have. Run sync --force for the interactive picker, or name the plugin: pncli skills marketplace sync new-plugin --all-agents

You can register as many marketplaces as you like. Clones live in ~/.agents/marketplaces/, and marketplace remove unregisters one without deleting its clone.

What a marketplace repo looks like: .claude-plugin/marketplace.json (or a plugins/ directory), with each plugin holding a skills/ folder of skill directories. That's the same layout Claude Code's own plugin marketplaces use, so one repo serves both.

Turning plugins on and off

pncli skills marketplace disable some-plugin
pncli skills marketplace enable some-plugin
pncli skills marketplace manage          # interactive: checkbox list of every plugin

disable moves a plugin's skills into a hidden .pncli-disabled/ folder next to them, so agents stop loading them. Nothing is deleted and nothing needs re-downloading. A disabled plugin stays disabled across syncs, but it still gets refreshed while it sits there.

To remove a plugin for good, use marketplace purge-plugin. skills purge-user clears an agent's whole user-level skills folder.

Shipped instructions (AGENTS.md / CLAUDE.md)

A marketplace can also ship org-wide agent instructions in instructions/AGENTS.md and instructions/CLAUDE.md. add and sync merge them into each agent's user-level instructions file (~/.codex/AGENTS.md, ~/.copilot/copilot-instructions.md, ~/.claude/CLAUDE.md).

They go in as a marked block. Your own content in that file is never touched, the block is replaced in place on every sync, and marketplace instructions remove strips it cleanly. Don't edit inside the markers, because the next sync overwrites them.

Where did this skill come from?

pncli skills status                          # every skill → plugin → marketplace → clone URL
pncli skills status --source untracked       # skills pncli did not install
pncli skills locations                       # every path, with counts

The counts in locations always add up: marketplaceSkills + bundledSkills + untrackedSkills = totalSkills.

Private repos and auth

A private marketplace needs a credential in two places, and they're easy to confuse:

  1. pncli's own clone and pull. Pass --token to marketplace add, or let pncli fall back to the token it already has for the provider: github.token for GitHub and GitHub Enterprise, bitbucket.pat for your Bitbucket host, ado.pat for your Azure DevOps host. pncli hands the token to git through the environment for each call, so it never shows up on git's command line and is never left in the clone's .git/config.
  2. Everyone else's git. An agent host that clones a marketplace itself — Claude Code's /plugin marketplace add, for instance — runs plain git, and plain git has no idea about pncli's token. git-auth fixes that:
pncli skills git-auth enable                 # every marketplace that has a credential
pncli skills git-auth status                 # per marketplace: mode, and whether git sends pncli's token

git-auth has two modes:

ModeHow it worksAfter a token rotation
helper (default)git asks pncli skills git-credential --marketplace <name> on each operationNothing to do — git always gets pncli's current token
keychainthe token is stored in git's own credential store (Git Credential Manager, macOS Keychain, libsecret)Re-run git-auth enable --mode keychain; doctor flags the stale copy

Use helper unless something runs git without pncli on its PATH. Some GUI git clients and containers do that, and for those keychain is the right mode.

Entries are scoped to each marketplace's own repository URL, so every other repo on the same host keeps your usual login (gh, Git Credential Manager, the macOS Keychain), untouched. git-auth disable puts your previous setup back exactly. A whole-host entry (--host) is available, but only when you ask for it.

Which GitHub token? A classic personal access token (ghp_…) with the repo scope works across every repository your account can see, which suits a marketplace. A fine-grained token (github_pat_…) also works, but only for the repositories you selected when you created it. If your org uses SAML single sign-on, authorize the token for the org (Settings → Developer settings → Tokens → Configure SSO). pncli doctor checks the scope, the SSO authorization, and the expiry date for you.

Several marketplaces, several secrets. Each marketplace keeps its own --token (and --username), and every git path — pncli's clone and pull, the git helper, doctor's access check — uses exactly that pair. Rotate one with pncli skills marketplace update <name> --token <new-token>.

Bitbucket and Azure DevOps. Both work like GitHub. Bitbucket Data Center personal access tokens are usually sent with your Bitbucket username, so give the marketplace --username <you>. Azure DevOps PATs need the Code (Read) scope and accept any username. pncli doctor tries an authenticated git ls-remote for each marketplace, so a wrong username shows up the same way an expired token does.

Keeping credentials in the OS keychain

Diagrams of both storage options, and of both git-auth modes, are on the website: https://kolatts.github.io/pncli/credentials/

Any secret in ~/.pncli/config.json can live in your operating system's credential store instead: the macOS Keychain, Windows Credential Manager, or the Secret Service on Linux. The config file then holds only a reference such as "token": "keychain:github.token".

pncli config keychain migrate --dry-run           # what would move
pncli config keychain migrate                     # config → keychain, every plaintext secret
pncli config keychain set github.token            # store one (prompts; or pipe it with --stdin)
pncli config keychain status                      # every reference, and whether it resolves
pncli config keychain migrate --to config         # keychain → config (entries kept)
pncli config keychain migrate --to config --purge # …and delete the keychain entries
  • PNCLI_* environment variables still win over everything, so CI is unaffected. Set PNCLI_KEYCHAIN_BACKEND=none on a machine that should ignore references altogether.
  • migrate reads each secret back before it rewrites your config, and leaves a config.json.pre-keychain.bak behind. Delete that file once pncli config check passes.
  • marketplace add --token … --keychain stores a marketplace token the same way from the start.
  • Lookups cost a little time. On Windows each pncli command that needs a keychain secret starts PowerShell once (typically well under a second); macOS and Linux are faster.
  • The keychain and git-auth helper mode work together. Git asks pncli, pncli reads the keychain, and the token never sits in a file anywhere.

Troubleshooting

SymptomTry
The agent doesn't see a skillpncli skills status, then check the host's directory in pncli skills locations
"I ran marketplace add but nothing shows up"pncli doctor — it flags marketplaces with nothing installed from them
sync fails with "Invalid username or token"pncli doctor: look for an expired token, a missing repo scope, or SSO not authorized
Claude Code's /plugin marketplace add can't clonepncli skills git-auth enable --host ghe.imagile.dev
The bundled skill is out of date after an upgradepncli skills install (add --all-agents / --scope user as before)
A plugin added upstream never arrivedpncli skills marketplace sync --force, or name it explicitly
A command says "not configured" but the token is in the keychainpncli config keychain status — the reference may point at a missing entry
Some ordinary clone (not a marketplace) says "repository not found"pncli git credentials inspect in that clone, or pncli git credentials inspect --scan ~/src --problems-only
git keeps using the wrong account or an old tokenpncli git credentials stored — shows shadowed and stale stored credentials, then pncli git credentials forget

pncli doctor runs every one of these checks at once and prints a fix command next to each problem it finds.