{"id":50929962,"url":"https://github.com/mk668a/claude-muster","last_synced_at":"2026-06-17T03:04:44.556Z","repository":{"id":365049672,"uuid":"1270238146","full_name":"mk668a/claude-muster","owner":"mk668a","description":"Open Claude Code in your polyrepo root and use every child repo's skills, agents, commands \u0026 hooks at once. claude-muster federates them into one .claude/ —   namespaced repo:name, fully reversible, no LLM.","archived":false,"fork":false,"pushed_at":"2026-06-15T15:55:17.000Z","size":528,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-15T17:25:28.899Z","etag":null,"topics":["ai-agents","claude","claude-code","cli","monorepo","polyrepo","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/mk668a.png","metadata":{"files":{"readme":"README.es.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":null,"dco":null,"cla":null}},"created_at":"2026-06-15T14:15:14.000Z","updated_at":"2026-06-15T15:58:11.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/mk668a/claude-muster","commit_stats":null,"previous_names":["mk668a/claude-muster"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/mk668a/claude-muster","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mk668a%2Fclaude-muster","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mk668a%2Fclaude-muster/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mk668a%2Fclaude-muster/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mk668a%2Fclaude-muster/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mk668a","download_url":"https://codeload.github.com/mk668a/claude-muster/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mk668a%2Fclaude-muster/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34431810,"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-17T02:00:05.408Z","response_time":127,"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","claude-code","cli","monorepo","polyrepo","typescript"],"created_at":"2026-06-17T03:04:43.892Z","updated_at":"2026-06-17T03:04:44.550Z","avatar_url":"https://github.com/mk668a.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# claude-muster\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"./assets/header.jpg\" alt=\"claude-muster — orchestrate every agent, from one root\" width=\"100%\"\u003e\n\u003c/p\u003e\n\n[English](./README.md) · [日本語](./README.ja.md) · [中文](./README.zh-CN.md) · [한국어](./README.ko.md) · Español · [Français](./README.fr.md)\n\n**Orquesta cada agente. Desde una sola raíz.**\n\nTrabaja en todos tus repos desde una única sesión de Claude dejando que el Claude propio de cada repo haga su trabajo, en su propia carpeta, con sus skills, agentes, hooks y ajustes intactos.\n\n## La situación\n\nSupón que tu trabajo vive en una carpeta llena de repos git independientes:\n\n```\n~/work/\n├── webapp/    → tiene .claude/skills/deploy, .claude/commands/release\n├── api/       → tiene .claude/skills/lint, .claude/agents/db-reviewer, .claude/hooks/pre-commit\n└── mobile/    → tiene .claude/commands/build\n```\n\nCada repo lleva su propio `.claude/`: las skills, agentes, comandos, hooks y ajustes que escribió su equipo.\n\nAbre Claude Code **dentro de `api/`** y obtienes todo el instrumental de api. Perfecto. Pero ábrelo **en `~/work/`** para trabajar en los tres a la vez y ese instrumental desaparece, porque Claude Code lee `.claude/` de la carpeta actual y de las carpetas que están por encima, nunca de las que están por debajo.\n\nEl arreglo obvio es subirlo todo: copiar o enlazar (symlink) el `.claude/` de cada repo en `~/work/.claude/`. Eso funciona para las skills, pero rompe lo demás en silencio. Un hook escrito para correr dentro de `api/` ahora corre desde `~/work/` con el directorio de trabajo equivocado. Un permiso `deny` de un repo bloquea sin avisar a todos los demás. Dos repos que definen `API_URL` colisionan en un único valor. Los agentes hay que copiarlos, así que quedan desactualizados. Acabas cuidando un `.claude/` fusionado en vez de trabajar.\n\n## Qué hace claude-muster\n\nToma el enfoque contrario. En lugar de subir el instrumental de cada repo *hacia* una sola sesión, deja el `.claude/` de cada repo exactamente donde está y ejecuta **el Claude propio de ese repo dentro de ese repo**. El Claude de tu raíz se vuelve un orquestador: decide a qué repo pertenece una tarea, se la entrega y lee de vuelta el resultado.\n\n```console\n$ cd ~/work\n$ claude-muster repos\n\n  3 repos you can dispatch to:\n\n  webapp\n  api\n  mobile\n\n$ claude-muster dispatch api \"arregla el test que falla en handler.ts\"\n\n  [api] ok\n\n  Lo encontré: handler.ts llamaba al viejo `parse()` de dos argumentos. Actualicé la llamada y el test pasa.\n```\n\nEl hijo ejecutó `claude` **dentro de `api/`**, así que tuvo el directorio de trabajo real de api, su entorno, sus skills, agentes, hooks y permisos, exactamente como si tú mismo hubieras abierto Claude ahí. No se copió nada. No se fusionó nada. No hay nada que se desactualice ni que limpiar.\n\nMejor aún: instala la skill de enrutado y tu Claude raíz aprende a hacerlo por su cuenta:\n\n```console\n$ claude-muster install     # añade una pequeña skill a ~/work/.claude/\n\n$ claude\n\u003e arregla el test que falla en api y dime cuál es el comando de build de web\n\n  (Claude despacha a api, despacha a web y reporta ambos resultados)\n```\n\n¿Quieres que tu Claude raíz conozca sus repos en el instante en que arranca una sesión, sin esperar a que la skill se active? Añade `--hook`:\n\n```console\n$ claude-muster install --hook    # registra además un hook SessionStart en ~/work/.claude/settings.json\n```\n\nAhora cada sesión aquí abre con un resumen de una línea de a qué repos puede despachar. Es lo único que claude-muster escribe en tu `settings.json`, y `uninstall` lo retira con exactitud.\n\nEsa es toda la herramienta. **claude-muster nunca llama a un LLM por sí mismo.** `dispatch` lanza tu CLI local `claude`, que corre con tu propia autenticación y tu propia cartera. claude-muster solo decide adónde enviar el trabajo y recoge lo que vuelve.\n\n## Instalación\n\n\u003e **Aún no está en npm.** Por ahora, clónalo y compílalo. Está previsto publicar `npx claude-muster`.\n\n```bash\ngit clone https://github.com/mk668a/claude-muster\ncd claude-muster\nnpm install \u0026\u0026 npm run build\nnpm link            # deja `claude-muster` disponible en todas partes\n```\n\nLuego ejecútalo desde la raíz de cualquier workspace:\n\n```bash\ncd ~/work\nclaude-muster repos\n```\n\nNode 18+. También necesitas el CLI `claude` en tu `PATH` (es lo que ejecuta `dispatch`).\n\n¿Prefieres no usar `npm link`? Llama directamente al archivo compilado: `node /path/to/claude-muster/dist/cli.js`.\n\n### Eliminar claude-muster de tu máquina\n\nOjo a la diferencia: `claude-muster uninstall` quita la skill de enrutado de un workspace, **no** la herramienta. Para desinstalar la herramienta en sí, deshaz el `npm link` y borra el clon:\n\n```bash\nnpm rm -g claude-muster        # o: npm unlink -g claude-muster (deshace `npm link`)\nrm -rf /path/to/claude-muster  # la carpeta que clonaste\n```\n\nSi te saltaste `npm link` y ejecutabas `node .../dist/cli.js` directamente, basta con borrar el clon.\n\n## Uso\n\n```bash\nclaude-muster repos                      # lista los repos hijos a los que puedes despachar\nclaude-muster dispatch \u003crepo\u003e \"\u003ctask\u003e\"   # ejecuta `claude -p \"\u003ctask\u003e\"` dentro de ese repo\nclaude-muster dispatch --all \"\u003ctask\u003e\"    # reparte la misma tarea a todos los repos\nclaude-muster install                    # añade la skill de enrutado para que tu Claude raíz delegue\nclaude-muster install --hook             # informa además a tu Claude raíz sobre sus repos al iniciar la sesión\nclaude-muster uninstall                  # quita la skill (y cualquier entrada --hook) de esta raíz\nclaude-muster --version                  # muestra la versión instalada (forma corta: -v)\n```\n\nPara deshacer una instalación, ejecuta `claude-muster uninstall` desde la misma raíz en la que instalaste. Quita la skill `muster-dispatch` y, si usaste `--hook`, retira la entrada SessionStart de `settings.json`, borrando el archivo si no queda nada más en él. Solo elimina lo que claude-muster añadió.\n\nPara comprobar qué versión tienes, ejecuta `claude-muster --version` (o `claude-muster -v`).\n\nFlags útiles:\n\n```bash\n--root \u003cdir\u003e     # raíz del workspace a escanear (por defecto: directorio actual)\n--json           # emite los resultados de dispatch / repos como JSON, para que la sesión padre los parsee\n--timeout \u003cms\u003e   # corta un hijo despachado si tarda demasiado\n--depth \u003cn\u003e      # hasta qué profundidad buscar carpetas .claude/ hijas (por defecto: 1)\n--path \u003cdir\u003e     # incluye también un repo que viva en otro lugar de esta máquina; repetible\n--force          # sobrescribe una skill existente (con `install`)\n-v, --version    # muestra la versión\n-h, --help       # muestra todos los comandos y flags\n```\n\n### Despacha a un repo, o reparte a todos\n\n`dispatch \u003crepo\u003e \"\u003ctask\u003e\"` envía una tarea autocontenida a un repo. Escribe la tarea como se la dirías a un Claude recién abierto en ese repo, porque eso es exactamente lo que es: el hijo arranca sin memoria de tu conversación en la raíz.\n\n`dispatch --all \"\u003ctask\u003e\"` envía la misma tarea a todos los repos en paralelo y recoge los resultados. Está pensado para sondeos y barridos: *\"¿cuál es tu comando de test?\"*, *\"¿hay algún TODO sobre auth en alguna parte?\"*, *\"sube la versión a 2.0\"*. Combínalo con `--json` cuando quieras agregar las respuestas tú mismo.\n\n### Configuración opcional\n\nPor defecto se incluye todo repo hermano que tenga un `.claude/`. Coloca un `claude-muster.json` en la raíz para acotarlo:\n\n```jsonc\n{\n  \"include\": [\"webapp\", \"api/*\", \"services/**\"],  // qué repos apuntar (globs, relativos a la raíz)\n  \"exclude\": [\"legacy-*\"],                          // repos a omitir\n  \"depth\": 2,                                        // cuántas carpetas de profundidad mirar (por defecto: 1)\n  \"paths\": [\"../shared-tools\", \"/abs/path/to/repo\"]  // repos extra en cualquier lugar de esta máquina (también: --path)\n}\n```\n\n## Cómo funciona\n\nClaude Code lee el `.claude/` de cada repo desde la carpeta propia del repo y las carpetas que están por encima. claude-muster nunca pelea contra eso. Solo arranca `claude` con el repo hijo como directorio de trabajo:\n\n| Paso | Qué ocurre |\n|---|---|\n| **discover** | Recorre la raíz buscando directorios hermanos que contengan un `.claude/` (respetando `claude-muster.json`). |\n| **decide** | El Claude de tu raíz (o tú en la línea de comandos) elige a qué repo pertenece una tarea. |\n| **dispatch** | Ejecuta `claude -p \"\u003ctask\u003e\" --output-format json` con `cwd` apuntando a ese repo. |\n| **collect** | Parsea el resultado final del hijo y se lo devuelve al orquestador. |\n\nComo el hijo es un proceso `claude` real enraizado en su propio repo, todos los problemas que crea el enfoque de copiarlo todo simplemente no aparecen:\n\n- **El directorio de trabajo es el correcto.** Los hooks y scripts corren desde el repo para el que fueron escritos.\n- **Sin disparos cruzados.** Los hooks y permisos de cada repo aplican solo a la sesión de ese repo, nunca a los demás.\n- **Nada se queda obsoleto.** Los agentes se leen en vivo desde el repo, nunca se copian.\n- **Sin colisiones de entorno.** Cada proceso hijo tiene su propio entorno.\n- **Nada que limpiar.** Sin symlinks, sin ajustes fusionados, sin manifiesto. `install` añade una skill y `uninstall` la quita.\n\n## Por qué es seguro confiar en ello\n\n- **claude-muster nunca llama a un LLM.** Ejecuta tu CLI local `claude`, con tu autenticación y tu cartera. Sin API keys, sin red propia, sin telemetría.\n- **Cambia casi nada en disco.** `dispatch` y `repos` solo leen tus carpetas para descubrir repos. Lo único que llega a escribir es la skill de enrutado de `install`, y `uninstall` la retira.\n- **Cada hijo es el de verdad.** Despachar a `api` es lo mismo que abrir Claude en `api/` tú mismo, así que no hay sorpresas sobre qué instrumental está en efecto.\n\n## Qué no hace (todavía)\n\n- **Sesiones hijas persistentes.** Cada `dispatch` es una ejecución `claude -p` fresca y de un solo disparo, así que un hijo no recuerda la tarea anterior que le enviaste. Mantener sesiones cálidas y duraderas por repo es un seguimiento previsto.\n- **Repos en otras máquinas.** Funciona cualquier lugar de tu sistema de archivos local (ver `paths`), pero no los repos remotos o en red.\n- **Decidir por ti cuando hay ambigüedad.** Si una tarea podría pertenecer a varios repos, el orquestador debería preguntar en vez de adivinar. La skill de enrutado está escrita para hacer justo eso.\n\n## Tu cuenta, tus términos\n\n`dispatch` ejecuta tu propio CLI `claude` instalado localmente bajo tu propia cuenta de Anthropic (una suscripción de Claude o una API key). claude-muster nunca provee, almacena ni comparte credenciales, y usa el modo headless documentado de Claude Code (`claude -p`). Eres responsable de cumplir con los [términos y políticas de uso de Anthropic](https://www.anthropic.com/legal/aup) para tu propio plan.\n\nUna nota práctica: `dispatch --all` arranca varios procesos `claude` a la vez, lo que puede chocar con los límites de tasa de Anthropic si repartes a muchos repos. Mantén la concurrencia en niveles razonables.\n\n## Licencia\n\nMIT.\n\u003c/content\u003e\n\u003c/invoke\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmk668a%2Fclaude-muster","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmk668a%2Fclaude-muster","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmk668a%2Fclaude-muster/lists"}