{"id":50965351,"url":"https://github.com/fmind/agent-supagents","last_synced_at":"2026-06-18T19:33:21.924Z","repository":{"id":356384133,"uuid":"1227100657","full_name":"fmind/agent-supagents","owner":"fmind","description":"Compile a single AI supagent into multiple AI subagents (Claude Code, Gemini CLI, GitHub Copilot, Cursor, OpenCode, Kilo Code).","archived":false,"fork":false,"pushed_at":"2026-05-31T17:32:55.000Z","size":499,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-11T15:41:47.026Z","etag":null,"topics":["ai-agents","claude-code","cli","code-generation","cursor","developer-tools","gemini-cli","gemini-cli-extension","github-copilot","kilo-code","opencode","pre-commit-hook","python","subagents"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/supagents/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fmind.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-05-02T07:47:32.000Z","updated_at":"2026-06-02T17:00:11.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/fmind/agent-supagents","commit_stats":null,"previous_names":["fmind/agent-supagents"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/fmind/agent-supagents","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fmind%2Fagent-supagents","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fmind%2Fagent-supagents/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fmind%2Fagent-supagents/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fmind%2Fagent-supagents/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fmind","download_url":"https://codeload.github.com/fmind/agent-supagents/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fmind%2Fagent-supagents/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34505420,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-18T02:00:06.871Z","response_time":128,"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-agents","claude-code","cli","code-generation","cursor","developer-tools","gemini-cli","gemini-cli-extension","github-copilot","kilo-code","opencode","pre-commit-hook","python","subagents"],"created_at":"2026-06-18T19:33:21.155Z","updated_at":"2026-06-18T19:33:21.917Z","avatar_url":"https://github.com/fmind.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# supagents\n\n\u003e **Compile a single AI supagent into multiple AI subagents.**\n\nSupagents is a small Python CLI that compiles a single markdown file into target-specific subagent files for [Claude Code], [Gemini CLI], [GitHub Copilot], [Cursor], [OpenCode], and [Kilo Code]. You write the agent's persona once and ship it to every agent CLI you use.\n\n[![CI](https://github.com/fmind/agent-supagents/actions/workflows/ci.yml/badge.svg)](https://github.com/fmind/agent-supagents/actions/workflows/ci.yml)\n[![Python](https://img.shields.io/badge/python-3.12%2B-blue)](https://www.python.org/)\n[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)\n[![Type checked: ty](https://img.shields.io/badge/ty-checked-blue)](https://docs.astral.sh/ty/)\n\n[Claude Code]: https://docs.claude.com/en/docs/claude-code/sub-agents\n[Gemini CLI]: https://github.com/google-gemini/gemini-cli\n[GitHub Copilot]: https://docs.github.com/en/copilot\n[Cursor]: https://cursor.com/docs/subagents\n[OpenCode]: https://opencode.ai/docs/agents/\n[Kilo Code]: https://kilo.ai/docs/customize/custom-subagents\n\n![supagents — compile one AI supagent into multiple AI subagents](image.jpeg)\n\n## Why\n\nEvery agent CLI has its own subagent format. The persona is the same (\"You are a code-investigation expert...\"), but each one wants a different YAML frontmatter shape and a different output directory. Hand-syncing every file every time you tweak a prompt is miserable.\n\nSupagents takes the **opposite** approach from format-conversion tools: it makes you write each target's frontmatter **verbatim** in named blocks, and then it does the boring parts — splitting the body, copying shared keys, writing files atomically, and cleaning up stale outputs.\n\n```\n   one source                                 many outputs\n   ─────────                                  ────────────\n                                              ~/.claude/agents/code_investigator.md\n                                              ~/.gemini/agents/code_investigator.md\n~/.agents/supagents/code_investigator.md  →   ~/.copilot/agents/code_investigator.agent.md\n                                              ~/.cursor/agents/code_investigator.md\n                                              ~/.config/opencode/agents/code_investigator.md\n                                              ~/.config/kilo/agents/code_investigator.md\n```\n\nThe diagram shows the full fan-out. Declare any subset of target blocks in your source and supagents emits just those — the example below picks three.\n\n## Install\n\n```bash\nuv tool install supagents\n# or:\npipx install supagents\n# or, from this repo:\nuv tool install --from /path/to/supagents supagents\n```\n\nRequires Python 3.12+.\n\n## Install as a plugin or extension\n\nThe same repo doubles as a Claude Code plugin, a Gemini CLI extension, and a GitHub Copilot plugin — install it through your agent CLI and it pulls in the bundled [`use-agent-supagents` Agent Skill](skills/use-agent-supagents/SKILL.md). Your agent learns the source format and CLI semantics up front, so you don't have to paste docs into prompts.\n\n| Tool           | Manifest in the repo                                | What it installs                |\n|----------------|-----------------------------------------------------|---------------------------------|\n| Claude Code    | `.claude-plugin/plugin.json` (+ `marketplace.json`) | Plugin + bundled marketplace.   |\n| Gemini CLI     | `gemini-extension.json`                             | Gemini CLI extension.           |\n| GitHub Copilot | `plugin.json`                                       | Copilot plugin manifest.        |\n\nThese manifests register the Skill — they don't install the `supagents` CLI binary. Install the CLI separately (above) so `supagents build` lives on `$PATH`.\n\n## Quick start\n\nScaffold a new source with `supagents init \u003cname\u003e` (writes a template with all default target blocks), or drop one yourself at `~/.agents/supagents/code_investigator.md`. The example below declares three blocks to keep things short — add `CURSOR:`, `OPENCODE:`, or `KILO:` blocks to emit those targets too:\n\n```markdown\n---\nname: code_investigator\ndescription: Use to explore unfamiliar codebases — trace symbols, map data flow across modules, and explain how a feature is implemented.\n\nCLAUDE:\n  model: sonnet\n  tools: Read, Grep, Glob, Bash\n\nGEMINI:\n  kind: local\n  tools: [\"*\"]\n  mcp_servers:\n    context7:\n      command: npx\n      args: [\"-y\", \"@upstash/context7-mcp@latest\"]\n\nCOPILOT:\n  target: vscode\n  model: [\"gpt-5\", \"gpt-4.1\"]\n  APPEND_BODY: |\n\n    ## Copilot-specific\n    Reference tools inline with `#tool:\u003cname\u003e`.\n---\n\n# Code Investigator Agent\n\nYou are the specialized code investigation agent. Help the user explore unfamiliar codebases: trace symbols, map data flow across modules, and explain how features are implemented.\n```\n\nThen build:\n\n```bash\nsupagents build\n```\n\nYou'll get one file per declared target — three in this example:\n\n```\n~/.claude/agents/code_investigator.md           # Claude Code subagent\n~/.gemini/agents/code_investigator.md           # Gemini CLI agent\n~/.copilot/agents/code_investigator.agent.md    # GitHub Copilot agent\n```\n\nEach output gets the **shared keys** (`name`, `description`) plus the **target's own keys**, the shared body, and a generation marker comment so `supagents clean` can safely identify what it owns.\n\nSource filenames must match `^[a-z0-9][a-z0-9_-]*\\.md$` — lowercase letters, digits, hyphens, and underscores only.\n\n## How it works\n\nThe frontmatter is partitioned by case:\n\n| Case | Where it goes |\n|---|---|\n| `lowercase` keys at the top | shared frontmatter — copied to every output |\n| `UPPERCASE` keys at the top | target sections (`CLAUDE`, `GEMINI`, `COPILOT`) |\n| `lowercase` keys inside a target | that target's frontmatter (overrides shared) |\n| `UPPERCASE` keys inside a target | directives — not emitted |\n\nTwo directives are recognized:\n\n| Directive | What it does |\n|---|---|\n| `OUTPUT` | Override the output path for this target only |\n| `APPEND_BODY` | Append target-specific markdown to the shared body |\n\nA target section's **presence** triggers an emit. Drop the `COPILOT:` block and you stop generating Copilot files. There is **no** field-level conversion — what you write is what gets written.\n\nFor validation rules, scope resolution, and idempotency guarantees, see the inline docstrings in [`src/supagents/`](src/supagents/) — `core.py` and `config.py`.\n\n## CLI\n\n```text\nsupagents --version\nsupagents build [SCOPE] [--dry-run | --check] [--target T]... [--config PATH] [-v]\nsupagents clean [SCOPE] [--dry-run]           [--target T]... [--config PATH]\nsupagents list  [SCOPE]                       [--target T]... [--config PATH]\nsupagents init  NAME [SCOPE] [--force]\n```\n\n`SCOPE` is `--global`/`-g` or `--project`/`-p`; if omitted, supagents auto-detects.\n\n| Command | Purpose |\n|---|---|\n| `build` | Compile sources to outputs. Idempotent — unchanged files aren't rewritten (mtimes preserved). Warnings and errors print to stderr. `--check` exits 1 if anything would change — handy as a CI guard against stale outputs. See [Exit codes](#exit-codes). |\n| `clean` | Delete marker-bearing outputs whose source is gone. Hand-written files in the same directory are preserved. |\n| `list`  | Print a table of every source and the per-target outputs it would produce. |\n| `init`  | Scaffold a new source file at `\u003cscope\u003e/.../NAME.md` with the default target blocks pre-filled. Refuses to overwrite without `--force`. |\n\n### Flags\n\n| Flag | Applies to | Notes |\n|---|---|---|\n| `--target T`, `-t` | `build`, `clean`, `list` | Operate only on the named target(s); repeatable, case-insensitive. Unknown targets are rejected. |\n| `--check` | `build` | Don't write; exit 1 if any output would change. Mutually exclusive with `--dry-run`. Useful as a CI guard against stale generated files. |\n| `--verbose`, `-v` | `build` | Also print files that were left unchanged — useful when sanity-checking idempotency. |\n| `--config PATH`, `-c` | all | Override the default config path (`$XDG_CONFIG_HOME/supagents/config.yaml`). |\n| `--force`, `-f` | `init` | Overwrite the file if it already exists. |\n| `--version` | top-level | Print the installed version and exit. |\n\n### Exit codes\n\nEvery command resolves to one of three exit codes — pick them up in CI to fail fast on the right thing:\n\n| Code | Meaning |\n|---|---|\n| `0` | Success. Nothing wrong, nothing stale. |\n| `1` | Per-target errors, or `--check` detected drift you'd need to commit. |\n| `2` | Fatal parse error, or a write failed mid-build. |\n\n### Scopes\n\n| Scope | Source location |\n|---|---|\n| **Global** | `~/.agents/supagents/*.md` |\n| **Project** | `./.agents/supagents/*.md` |\n\nIf neither `--global` nor `--project` is passed, supagents auto-detects: project scope when `.agents/supagents/` exists in the current directory, global otherwise.\n\n### Bundled targets\n\nA target only emits when its block appears in the source frontmatter. The bundled defaults:\n\n| Target | Global output | Project output | Suffix |\n|---|---|---|---|\n| `CLAUDE` | `~/.claude/agents/` | `.claude/agents/` | `.md` |\n| `GEMINI` | `~/.gemini/agents/` | `.gemini/agents/` | `.md` |\n| `COPILOT` | `~/.copilot/agents/` | `.github/agents/` | `.agent.md` |\n| `CURSOR` | `~/.cursor/agents/` | `.cursor/agents/` | `.md` |\n| `OPENCODE` | `~/.config/opencode/agents/` | `.opencode/agents/` | `.md` |\n| `KILO` | `~/.config/kilo/agents/` | `.kilo/agents/` | `.md` |\n\nOverride any path or add a new target via the config file (see below).\n\n## Pre-commit integration\n\nDrop this in your repo's `.pre-commit-config.yaml`:\n\n```yaml\n- repo: https://github.com/fmind/agent-supagents\n  rev: v1.0.0  # pin to a tagged release — see https://github.com/fmind/agent-supagents/releases\n  hooks:\n    - id: supagents-build\n```\n\nThe hook runs whenever a source file under `.agents/supagents/` (or chezmoi source state under `dot_agents/supagents/`) changes, and rewrites the generated outputs in place. Commit them alongside the sources so PRs stay self-consistent. To enforce that on the CI side, run `supagents build --check` — it exits non-zero if any generated file would change.\n\nIf you'd rather not depend on a remote hook repo, use the local form:\n\n```yaml\n- repo: local\n  hooks:\n    - id: supagents-build\n      name: supagents build\n      entry: supagents build\n      language: system\n      files: ^(\\.agents/supagents/|dot_agents/supagents/)[a-z0-9][a-z0-9_-]*\\.md$\n      pass_filenames: false\n```\n\n## chezmoi integration\n\nIf you manage your dotfiles with [chezmoi], put your sources in:\n\n```\n~/.local/share/chezmoi/dot_agents/supagents/\u003cname\u003e.md\n```\n\n`chezmoi apply` materializes them at `~/.agents/supagents/\u003cname\u003e.md`. Supagents reads from the **materialized** path, so a typical flow is:\n\n```bash\nchezmoi edit ~/.agents/supagents/code_investigator.md\nchezmoi apply\nsupagents build --global\n```\n\nThe pre-commit hook above already watches the chezmoi source path (`dot_agents/supagents/`), so committing inside your dotfiles repo regenerates the outputs automatically.\n\n[chezmoi]: https://www.chezmoi.io/\n\n## Configuration\n\nSix targets ship by default (`CLAUDE`, `GEMINI`, `COPILOT`, `CURSOR`, `OPENCODE`, `KILO`). To override their paths or add a new one, drop a YAML config at `~/.config/supagents/config.yaml` (XDG-compliant — honours `$XDG_CONFIG_HOME`):\n\n```yaml\ntargets:\n  claude:\n    global_path: ~/.claude/agents\n    project_path: .claude/agents\n```\n\nPer-field merge: any field you omit falls back to the bundled default. Lowercase keys in the file are normalised to UPPERCASE to match the source frontmatter convention. Once a target is registered, sources can use its UPPERCASE name in their frontmatter and supagents will emit for it.\n\n## Development\n\n```bash\ngit clone https://github.com/fmind/agent-supagents.git\ncd agent-supagents\njust install   # uv sync + pre-commit install\njust lint      # ruff format check + ruff check + ty + uv lock --check\njust test      # pytest with coverage (≥ 90% gate)\njust format    # auto-fix imports and formatting\njust update    # bump locked deps + pre-commit autoupdate\njust clean     # drop caches and __pycache__\n```\n\n`just lint` and `just test` are exactly what CI runs — green locally means green in CI.\n\nThe build is small on purpose: a tight dependency surface (`typer`, `rich`, `ruamel.yaml`, `pydantic`), no I/O outside documented paths, [`ty`](https://docs.astral.sh/ty/) for type checks, ruff with a strict ruleset, pre-commit as the single source of truth wired into CI.\n\n## Design\n\nA few principles worth calling out:\n\n- **Verbatim per-target frontmatter.** Each target gets its own block in the source; supagents copies it through unchanged. No schema conversion, no surprises.\n- **Open-list targets.** Adding a new target is a few lines in `~/.config/supagents/config.yaml`. The source format already supports it.\n- **Idempotent builds.** Two consecutive `supagents build` runs against an unchanged source tree perform zero writes. Generated files keep their mtimes.\n- **Safe cleanup.** `supagents clean` only deletes files it can prove it generated, by checking for the marker comment at the top.\n\n## License\n\n[MIT](LICENSE) — Médéric Hurier (Fmind).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffmind%2Fagent-supagents","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffmind%2Fagent-supagents","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffmind%2Fagent-supagents/lists"}