Catalog PyPI
Back to packageRELEASE DETAILS

0.6.3

PyPI

ai-config-cli

Declarative plugin manager for Claude Code

aiclaudeclaude-codeconfigurationplugin
Published25 Sept 2026
Direct dependencies19
Transitive dependenciesNot calculated

README

Version 0.6.3 documentation

ai-config

Declarative plugin manager for Claude Code — with cross-tool conversion to Codex, Cursor, OpenCode, and Pi.

Why this exists

You've spent time building up your AI coding setup: custom skills, MCP servers, hooks, workflows. Then you want to try Codex or Pi, and you're starting from scratch. Or you get a new machine and have to remember what you installed.

ai-config solves both problems. You define your setup in one YAML file, then use it to:

  1. Install your Claude Code plugins reproducibly across machines with ai-config sync.
  2. Convert those plugins for other tools — same skills, same config, less manual porting.

No more vendor lock-in because your customizations are trapped in one tool's config directory. No more hand-maintaining Claude plugins, Codex packages, Cursor/OpenCode config, and Pi extensions.

Or more simply: run ai-config init and it walks you through the config.

What this isn't

This README does not have:

  • 14 shields.io badges declaring build status, coverage, npm downloads, discord members, twitter followers, and mass-to-charge ratio
  • A mass of emojis to make it look "friendly" and "approachable"
  • Claims about revolutionizing your development workflow
  • A "Quick Start" that's actually 73 steps
  • Screenshots of a dashboard that doesn't exist
  • A "Powered by AI" badge despite just being a for-loop

It's a config file and some commands. That's it.

Install

pip install ai-config-cli
# or
uv tool install ai-config-cli

This installs the ai-config command. Check that it resolves before changing any tool config:

ai-config --help

From source, use the repo URL instead:

uv tool install git+https://github.com/alex-furrier/ai-config

Quick start: preview before you sync

1. Create a config

ai-config init

The wizard adds marketplaces and plugins, then writes .ai-config/config.yaml unless you pass -o. If the wizard offers to run sync immediately, say no when you want to inspect the file first.

2. Preview the changes

ai-config sync --dry-run

This is the safe checkpoint. It shows what would be installed, removed, or converted without writing plugin output.

3. Apply the sync

ai-config sync --verify

This makes installed plugins match your config and verifies the result. If your config enables conversion, sync also writes target-tool output for Codex, Cursor, OpenCode, and Pi according to your conversion scope.

4. Check for problems

ai-config doctor

Claude Code loads plugins at session start. After sync changes plugins, restart Claude Code to apply them. Use claude --resume if you want to continue the previous session.

What sync does

A config can install Claude Code plugins and convert them for other tools:

version: 1
targets:
  - type: claude
    config:
      marketplaces:
        my-plugins:
          source: github
          repo: myorg/ai-plugins
      plugins:
        - id: code-review@my-plugins
          scope: user
      conversion:
        enabled: true
        targets: [codex, cursor, opencode, pi]
        scope: user

With conversion enabled, ai-config sync can write outputs such as:

  • Claude Code: plugins installed through Claude Code's plugin system
  • Codex: installable plugin packages and ai-config-owned local marketplaces under .ai-config/codex/; sync manages them through codex plugin
  • Cursor: skills, commands, hooks, and MCP config under .cursor/ or ~/.cursor/
  • OpenCode: skills plus opencode.json / opencode.lsp.json
  • Pi: skills, prompt templates, and hook extensions under .pi/ or ~/.pi/

The exact paths depend on conversion scope and output_dir. Codex 0.6.0 is a breaking migration from loose .codex output; review the Codex migration guide before syncing. See Configuration and Conversion for full rules.

Config lookup

By default, commands look for config in this order:

  1. .ai-config/config.yaml
  2. .ai-config/config.yml
  3. ~/.ai-config/config.yaml
  4. ~/.ai-config/config.yml

Project-local config wins over global config. Pass -c /path/to/config.yaml to use a specific file.

Relative local marketplace paths and conversion output paths are resolved from the config's project root. Environment variables and ~ are expanded at load time, so paths like $DOTS_REPO/plugins can stay portable in dotfiles.

Common workflows

WorkflowCommandNotes
Create or update config interactivelyai-config initWrites .ai-config/config.yaml by default.
Preview syncai-config sync --dry-runUse before the first real sync or after large config edits.
Apply and verify syncai-config sync --verifyInstalls/uninstalls plugins and runs configured conversion.
See installed stateai-config statusAdd --verify to compare against config.
Validate config or outputai-config doctorUse --target codex, --target cursor, --target opencode, or --target pi for converted output.
Rebuild stale outputai-config sync --freshClears Claude's plugin cache and reconverts configured outputs while preserving target homes and ownership ledgers.
Re-run conversion onlyai-config sync --force-convertUseful after changing conversion targets.
Develop local pluginsai-config watchAdd --dry-run if you only want file-change reports.

For options and examples, use Commands. For target behavior and fidelity notes, use Conversion.

Development

git clone https://github.com/alex-furrier/ai-config.git
cd ai-config
uv sync --all-extras
uv run ruff check src/
uv run ty check src/
uv run pytest tests/unit/ -v

If you use just, the shortcut is:

just setup
just check

Troubleshooting

DO preview first, NOT blind sync, BECAUSE sync can install/uninstall plugins and write converted tool config.

ai-config sync --dry-run

DO use --fresh when Claude's cached plugins or converted output look stale, NOT hand-delete random target files first, BECAUSE sync preserves and reconciles its target ownership state.

ai-config sync --fresh

DO validate converted output with target doctor, NOT assume every Claude feature maps 1:1, BECAUSE some hooks, MCP settings, commands, and agents degrade or skip depending on the target.

ai-config doctor --target all ./output-dir

Further reading

  • Commands — complete CLI reference
  • Configuration — config schema, path resolution, scopes, and examples
  • Conversion — target mappings, dry runs, reports, and validation

License

MIT

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Declared dependencies 19

Native requirements
19 direct targetsNot calculated transitive count
Package / targetRequirementRelationship
click
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
click>=8.0runtime
pydantic
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
pydantic>=2.0runtime
pyyaml
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
pyyaml>=6.0runtime
questionary
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
questionary>=2.0runtime
requests
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
requests>=2.28runtime
rich
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
rich>=13.0runtime
tomli
Environment
{
  "extras": "",
  "marker": "python_full_version < \"3.11\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
tomli>=1.0.0; python_full_version < "3.11"runtime
watchdog
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
watchdog>=3.0runtime
docker
Environment
{
  "extras": "",
  "marker": "extra == \"dev\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
docker>=7.0; extra == "dev"runtime
pre-commit
Environment
{
  "extras": "",
  "marker": "extra == \"dev\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
pre-commit>=3.6.0; extra == "dev"runtime
pytest-asyncio
Environment
{
  "extras": "",
  "marker": "extra == \"dev\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
pytest-asyncio>=0.23.0; extra == "dev"runtime
pytest-cov
Environment
{
  "extras": "",
  "marker": "extra == \"dev\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
pytest-cov>=5.0.0; extra == "dev"runtime
pytest
Environment
{
  "extras": "",
  "marker": "extra == \"dev\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
pytest>=8.1.1; extra == "dev"runtime
ruff
Environment
{
  "extras": "",
  "marker": "extra == \"dev\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
ruff>=0.3.0; extra == "dev"runtime
ty
Environment
{
  "extras": "",
  "marker": "extra == \"dev\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
ty>=0.0.2; extra == "dev"runtime
types-pyyaml
Environment
{
  "extras": "",
  "marker": "extra == \"dev\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
types-pyyaml>=6.0; extra == "dev"runtime
types-requests
Environment
{
  "extras": "",
  "marker": "extra == \"dev\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
types-requests>=2.28; extra == "dev"runtime
mkdocs-material
Environment
{
  "extras": "",
  "marker": "extra == \"docs\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
mkdocs-material>=9.6.14; extra == "docs"runtime
mkdocstrings
Environment
{
  "extras": "python",
  "marker": "extra == \"docs\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
mkdocstrings[python]>=0.26.1; extra == "docs"runtime

Distribution files

2 collected
ai_config_cli-0.6.3-py3-none-any.whl

bdist_wheel · 154.04 KB · Python py3

Source file
ai_config_cli-0.6.3.tar.gz

sdist · 404.25 KB · Python source

Source file

Repository

PENDING
alex-furrier/ai-config

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 21 Oct, 10:15 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package_version:b80ca2bf43502e66d6f78c6dc5c0ceb969ea1fb46afe0ab05b961325512bd32c

Other collected versions

View all collected versions →