{"id":48537088,"url":"https://github.com/pivoshenko/kasetto","last_synced_at":"2026-05-07T22:03:24.980Z","repository":{"id":345136739,"uuid":"1184635586","full_name":"pivoshenko/kasetto","owner":"pivoshenko","description":"📼 A declarative AI agent environment manager, written in Rust","archived":false,"fork":false,"pushed_at":"2026-04-17T10:03:37.000Z","size":419,"stargazers_count":61,"open_issues_count":2,"forks_count":4,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-17T11:33:45.023Z","etag":null,"topics":["ai","ai-agents","ai-skills","claude-code","codex","copilot","cursor","declarative","developer-tools","devex","mcp","openclaw","opencode","package-manager","rust","skills"],"latest_commit_sha":null,"homepage":"https://www.kasetto.dev","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pivoshenko.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yaml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":"docs/roadmap.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"docs/agents.md","dco":null,"cla":null},"funding":{"github":"pivoshenko"}},"created_at":"2026-03-17T19:27:54.000Z","updated_at":"2026-04-17T10:03:41.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/pivoshenko/kasetto","commit_stats":null,"previous_names":["pivoshenko/sukiro","pivoshenko/sukiru"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/pivoshenko/kasetto","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pivoshenko%2Fkasetto","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pivoshenko%2Fkasetto/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pivoshenko%2Fkasetto/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pivoshenko%2Fkasetto/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pivoshenko","download_url":"https://codeload.github.com/pivoshenko/kasetto/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pivoshenko%2Fkasetto/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32022561,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T20:23:30.271Z","status":"online","status_checked_at":"2026-04-19T02:00:07.110Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","ai-agents","ai-skills","claude-code","codex","copilot","cursor","declarative","developer-tools","devex","mcp","openclaw","opencode","package-manager","rust","skills"],"created_at":"2026-04-08T02:30:28.206Z","updated_at":"2026-05-07T22:03:24.973Z","avatar_url":"https://github.com/pivoshenko.png","language":"Rust","funding_links":["https://github.com/sponsors/pivoshenko"],"categories":["Harnesses \u0026 orchestration"],"sub_categories":["Agent infrastructure"],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg alt=\"Kasetto logo\" src=\"assets/logo.svg\" width=\"450\" /\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/pivoshenko/kasetto/actions/workflows/ci.yaml\"\u003e\u003cimg alt=\"CI\" src=\"https://img.shields.io/github/actions/workflow/status/pivoshenko/kasetto/ci.yaml?style=flat-square\u0026logo=github\u0026logoColor=white\u0026label=CI\u0026color=0A6847\"\u003e\u003c/a\u003e\n  \u003cimg alt=\"Rust\" src=\"https://img.shields.io/badge/Rust-Stable-0A6847?style=flat-square\u0026logo=rust\u0026logoColor=white\"\u003e\n  \u003ca href=\"https://github.com/pivoshenko/kasetto/releases\"\u003e\u003cimg alt=\"Release\" src=\"https://img.shields.io/github/v/release/pivoshenko/kasetto?style=flat-square\u0026logo=github\u0026logoColor=white\u0026color=4856CD\u0026label=Release\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/pivoshenko/kasetto/blob/main/LICENSE-MIT\"\u003e\u003cimg alt=\"License\" src=\"https://img.shields.io/badge/License-MIT%20%7C%20Apache--2.0-0A6847?style=flat-square\u0026logo=opensourceinitiative\u0026logoColor=white\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://stand-with-ukraine.pp.ua\"\u003e\u003cimg alt=\"Stand with Ukraine\" src=\"https://img.shields.io/badge/Stand_With-Ukraine-FFD700?style=flat-square\u0026labelColor=0057B7\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  A declarative AI agent environment manager, written in Rust.\n\u003c/p\u003e\n\nName comes from the Japanese word **カセット** (*kasetto*) - cassette. Think of skills and MCPs as cassettes you plug in, swap out, and share across machines.\n\n## Why Kasetto\n\nThere are good tools in this space already - [Vercel Skills](https://github.com/vercel-labs/skills) installs skills from a curated catalog, and [Claude Plugins](https://claude.com/plugins) offer runtime integrations. Both work well for one-off installs, but neither gives you a declarative, version-controlled config.\n\nKasetto is a **community-first** project that solves a different problem: **declarative, reproducible skill management across machines and agents.**\n\n- **Declarative** — one YAML config describes your entire skill setup. Version it, share it, bootstrap a whole team in seconds. The config is the source of truth — readable, auditable, version-controlled.\n- **Enterprise \u0026 private repos** — GitHub, GitLab, Bitbucket, Codeberg, Gitea, and self-hosted instances out of the box. Onboard new engineers in one command. Everyone gets the exact same environment — zero drift, zero surprises.\n- **Multi-agent** — 21 built-in agent presets: Claude Code, Cursor, Codex, Windsurf, Copilot, Gemini CLI, and [many more](#supported-agents). One config, every agent updated.\n- **Skills \u0026 MCP** — any directory with a `SKILL.md` is a skill — no registry, no boilerplate. MCP server configs are auto-merged into every supported format (Cursor JSON, Claude JSON, Copilot VS Code, Codex TOML).\n- **Speed** — written in Rust. SHA-256 content hashing and lock file diffing mean only what changed gets touched. Full sync across all 21 agents finishes in seconds.\n- **Universal** — single static binary for macOS, Linux, and Windows. Install as `kasetto`, run as `kst`. CI-friendly with `--json` output and proper exit codes.\n\n\u003e Inspired by [uv](https://github.com/astral-sh/uv) - what uv did for Python packages, Kasetto aims to do for AI skills.\n\n## Install\n\n### Standalone Installer\n\n**macOS and Linux:**\n\n```bash\ncurl -fsSL kasetto.dev/install | sh\n```\n\n**Windows:**\n\n```powershell\npowershell -ExecutionPolicy Bypass -c \"irm kasetto.dev/install.ps1 | iex\"\n```\n\nBy default the binary is placed in `~/.local/bin`. You can override this with environment variables:\n\n| Variable              | Description            | Default                                                      |\n| --------------------- | ---------------------- | ------------------------------------------------------------ |\n| `KASETTO_VERSION`     | Version tag to install | Latest release                                               |\n| `KASETTO_INSTALL_DIR` | Installation directory | `~/.local/bin` (Unix) / `%USERPROFILE%\\.local\\bin` (Windows) |\n\n### Homebrew\n\n```bash\nbrew install pivoshenko/tap/kasetto\n```\n\n### Scoop (Windows)\n\n```bash\nscoop bucket add kasetto https://github.com/pivoshenko/scoop-bucket\nscoop install kasetto\n```\n\n### Cargo\n\n```bash\ncargo install kasetto\n```\n\n### From Source\n\n```bash\ngit clone https://github.com/pivoshenko/kasetto \u0026\u0026 cd kasetto\ncargo install --path .\n```\n\n## Getting Started\n\n**1. Sync from a remote config or a local file:**\n\n```bash\n# pull a shared team config from a URL\nkst sync --config https://example.com/team-skills.yaml\n\n# or use a local file\nkst sync --config kasetto.yaml\n```\n\nThat's it. Kasetto pulls the skills and installs them into the right agent directory. The next time you run `sync`, only what changed gets updated.\n\nSee [pivoshenko/pivoshenko.ai](https://github.com/pivoshenko/pivoshenko.ai) for a community example pulling skills from multiple packs for Claude Code and OpenCode.\n\n**2. See what's installed:**\n\n```bash\nkst list      # interactive browser with vim-style navigation\nkst doctor    # version, paths, last sync status\n```\n\n## Commands\n\n### `kst init`\n\nGenerates a starter config file (`./kasetto.yaml` by default, or global config with `--global`).\n\n```bash\nkst init [--global] [--force]\n```\n\n| Flag       | What it does                                                                        |\n| ---------- | ----------------------------------------------------------------------------------- |\n| `--global` | Write `$XDG_CONFIG_HOME/kasetto/kasetto.yaml` (or `~/.config/kasetto/kasetto.yaml`) |\n| `--force`  | Overwrite an existing config file without asking                                    |\n\n### `kst sync`\n\nReads the config, discovers skills, and makes the local destination match.\n\n```bash\nkst sync [--config \u003cpath-or-url\u003e] [--dry-run] [--quiet] [--json] [--plain] [--verbose] [--project | --global]\n```\n\n| Flag        | What it does                                                                                                                                       |\n| ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `--config`  | Path or HTTPS URL to a YAML config (default order: `$KASETTO_CONFIG`, saved preference, `./kasetto.yaml`, `$XDG_CONFIG_HOME/kasetto/kasetto.yaml`) |\n| `--dry-run` | Preview what would change without writing anything                                                                                                 |\n| `--quiet`   | Suppress non-error output                                                                                                                          |\n| `--json`    | Print the sync report as JSON                                                                                                                      |\n| `--plain`   | Disable colors and spinner animations                                                                                                              |\n| `--verbose` | Show per-skill action details                                                                                                                      |\n| `--project` | Install into the current project directory                                                                                                         |\n| `--global`  | Install globally (default)                                                                                                                         |\n\nMissing skills are reported as broken but won't stop the rest of the run. The exit code is non-zero only for source-level failures.\n\n### `kst list`\n\nShows skills and MCP servers from the lock file(s). **Without** `--project` or `--global`, both scopes are merged so you can tell global and project installs apart (scope is shown per row / in JSON).\n\n```bash\nkst list [--json] [--quiet] [--plain] [--project | --global]\n```\n\nIn a terminal (and without `--plain`), this opens an interactive browser — Skills and MCPs tabs with detail panes. Navigate with `j`/`k`, switch tabs with Tab or `h`/`l`, scroll with `PgUp`/`PgDn`, jump with `gg`/`G`. Use `--plain`, set `NO_TUI=1`, or pipe stdout for a plain text listing.\n\n### `kst doctor`\n\nPrints local diagnostics: version, lock file path, installation paths, last sync time, and any failed skills from the latest run.\n\n```bash\nkst doctor [--json] [--quiet] [--plain] [--project | --global]\n```\n\n### `kst clean`\n\nRemoves all tracked skills and MCP configs for the given scope.\n\n```bash\nkst clean [--dry-run] [--json] [--quiet] [--plain] [--project | --global]\n```\n\n| Flag        | What it does                                               |\n| ----------- | ---------------------------------------------------------- |\n| `--dry-run` | Preview what would be removed (prints paths and MCP packs) |\n| `--json`    | Print output as JSON                                       |\n| `--quiet`   | Suppress non-error output                                  |\n| `--plain`   | Disable colors and banner-style header                     |\n| `--project` | Clean project-scoped assets                                |\n| `--global`  | Clean globally-scoped assets (default)                     |\n\n### `kst self update`\n\nChecks GitHub for the latest release, verifies the SHA256 checksum against `checksums.txt`, and replaces the current binary in-place.\n\n```bash\nkst self update [--json]\n```\n\n### `kst self uninstall`\n\nRemoves installed skills, MCP configs, Kasetto data, and the binary.\n\n```bash\nkst self uninstall [--yes]\n```\n\n### `kst completions`\n\nGenerates shell completion scripts.\n\n```bash\nkst completions \u003cshell\u003e\n```\n\nSupported shells: `bash`, `zsh`, `fish`, `powershell`.\n\n## Configuration\n\nWhen `--config` is omitted, Kasetto looks for config in this order:\n\n1. `$KASETTO_CONFIG` env var\n2. `source:` key in `$XDG_CONFIG_HOME/kasetto/config.yaml`\n3. `./kasetto.yaml`\n4. `$XDG_CONFIG_HOME/kasetto/kasetto.yaml` (or `~/.config/kasetto/kasetto.yaml`)\n\nPoint it at a specific file or URL with `--config`, or run `kst init` for local `./kasetto.yaml` (`kst init --global` writes the global config file).\nTo persist a remote URL as your default, add a `source:` key to `~/.config/kasetto/config.yaml`.\n\n```yaml\n# Choose an agent preset (single or multiple)...\nagent: codex\n# agent:\n#   - claude-code\n#   - cursor\n\n# ...or set an explicit path (overrides agent)\n# destination: ./my-skills\n\n# Install scope: \"global\" (default) or \"project\"\n# scope: project\n\nskills:\n  # Pull specific skills from a GitHub repo\n  - source: https://github.com/org/skill-pack\n    branch: main\n    skills:\n      - code-reviewer\n      - name: design-system\n\n  # Sync everything from a local folder\n  - source: ~/Development/my-skills\n    skills: \"*\"\n\n  # Pin to a git tag or commit\n  - source: https://github.com/acme/stable-skills\n    ref: v1.2.0\n    skills:\n      - name: custom-skill\n        path: tools/skills\n\n  # Scope discovery to a nested directory inside the source\n  - source: https://github.com/acme/agents\n    sub-dir: plugins/swift-apple-expert\n    skills: \"*\"\n\n# MCP servers (optional)\nmcps:\n  # Discover all packs in the repo\n  - source: https://github.com/org/mcp-pack\n    mcps: \"*\"\n\n  # Pick specific files from a monorepo (names resolved from mcps/ dir)\n  - source: https://github.com/org/monorepo\n    ref: v1.4.0\n    mcps:\n      - github        # → mcps/github.json\n      - linear        # → mcps/linear.json\n```\n\n| Key                | Required | Description                                                                  |\n| ------------------ | -------- | ---------------------------------------------------------------------------- |\n| `agent`            | no       | One or more [supported agent presets](#supported-agents)                     |\n| `destination`      | no       | Explicit install path - overrides `agent` if both are set                    |\n| `scope`            | no       | `\"global\"` (default) or `\"project\"` - where to install                       |\n| `skills`           | **yes**  | List of skill sources                                                        |\n| `skills[].source`  | **yes**  | Git host URL or local path                                                   |\n| `skills[].branch`  | no       | Branch for remote sources (default: `main`, falls back to `master`)          |\n| `skills[].ref`     | no       | Git tag, commit SHA, or ref (takes priority over `branch`)                   |\n| `skills[].sub-dir` | no       | Relative subdirectory to use as source root (`sub_dir` alias also supported) |\n| `skills[].skills`  | **yes**  | `\"*\"` for all, or a list of names / `{ name, path }` objects                 |\n| `mcps`             | no       | List of MCP server sources                                                   |\n| `mcps[].source`    | **yes**  | Git host URL or local path containing MCP config                             |\n| `mcps[].branch`    | no       | Branch for remote sources                                                    |\n| `mcps[].ref`       | no       | Git tag, commit SHA, or ref                                                  |\n| `mcps[].mcps`      | **yes**  | `\"*\"` to discover all, or a list of names / `{ name, path }` objects         |\n\n## Supported Agents\n\nSet the `agent` field and Kasetto figures out where to put things.\n\n\u003cdetails\u003e\n\u003csummary\u003eFull list of supported agents\u003c/summary\u003e\n\n\u003cbr /\u003e\n\n| Agent          | Config value     | Install path                    |\n| -------------- | ---------------- | ------------------------------- |\n| Amp            | `amp`            | `~/.config/agents/skills/`      |\n| Antigravity    | `antigravity`    | `~/.gemini/antigravity/skills/` |\n| Augment        | `augment`        | `~/.augment/skills/`            |\n| Claude Code    | `claude-code`    | `~/.claude/skills/`             |\n| Cline          | `cline`          | `~/.agents/skills/`             |\n| Codex          | `codex`          | `~/.codex/skills/`              |\n| Continue       | `continue`       | `~/.continue/skills/`           |\n| Cursor         | `cursor`         | `~/.cursor/skills/`             |\n| Gemini CLI     | `gemini-cli`     | `~/.gemini/skills/`             |\n| GitHub Copilot | `github-copilot` | `~/.copilot/skills/`            |\n| Goose          | `goose`          | `~/.config/goose/skills/`       |\n| Junie          | `junie`          | `~/.junie/skills/`              |\n| Kiro CLI       | `kiro-cli`       | `~/.kiro/skills/`               |\n| OpenClaw       | `openclaw`       | `~/.openclaw/skills/`           |\n| OpenCode       | `opencode`       | `~/.config/opencode/skills/`    |\n| OpenHands      | `openhands`      | `~/.openhands/skills/`          |\n| Replit         | `replit`         | `~/.config/agents/skills/`      |\n| Roo Code       | `roo`            | `~/.roo/skills/`                |\n| Trae           | `trae`           | `~/.trae/skills/`               |\n| Warp           | `warp`           | `~/.agents/skills/`             |\n| Windsurf       | `windsurf`       | `~/.codeium/windsurf/skills/`   |\n\n\u003c/details\u003e\n\nDon't see your agent? Use the `destination` field to point at any path.\n\n## Private Repositories \u0026 Enterprise\n\nSet an environment variable and private sources just work — no login command, no credentials file:\n\n| Host                        | Environment variable                                                                       |\n| --------------------------- | ------------------------------------------------------------------------------------------ |\n| GitHub / GitHub Enterprise  | `GITHUB_TOKEN` or `GH_TOKEN`                                                               |\n| GitLab / GitLab self-hosted | `GITLAB_TOKEN` or `CI_JOB_TOKEN`                                                           |\n| Bitbucket Cloud             | `BITBUCKET_EMAIL` + `BITBUCKET_TOKEN` (or `BITBUCKET_USERNAME` + `BITBUCKET_APP_PASSWORD`) |\n| Codeberg / Gitea / Forgejo  | `GITEA_TOKEN`, `CODEBERG_TOKEN`, or `FORGEJO_TOKEN`                                        |\n\nKasetto auto-detects GitHub Enterprise for any hostname with an `owner/repo` path, and GitLab self-hosted when the hostname starts with `gitlab.`.\n\n```yaml\nskills:\n  # GitHub Enterprise\n  - source: https://ghe.example.com/acme/skill-pack\n    skills: \"*\"\n\n  # Self-hosted GitLab (nested groups supported)\n  - source: https://gitlab.example.com/team/ai/skills\n    skills:\n      - code-reviewer\n```\n\nThe same tokens apply when you fetch a remote config via `--config https://...`.\n\n## Roadmap\n\n- Agents management\n- Hooks management\n- Audit command — scan config and MCP servers for security issues\n- Smart URL rewriting — auto-rewrite GitHub `/blob/` URLs to raw content\n- Your idea? [Open an issue](https://github.com/pivoshenko/kasetto/issues)\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and guidelines.\n\n## License\n\nLicensed under either [MIT](LICENSE-MIT) or [Apache-2.0](LICENSE-APACHE), at your option.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpivoshenko%2Fkasetto","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpivoshenko%2Fkasetto","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpivoshenko%2Fkasetto/lists"}