karajan-code 4.1.3 → 4.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/docs/README.es.md CHANGED
@@ -1,286 +1,69 @@
1
1
  <p align="center">
2
- <img src="karajan-code-logo-small.png" alt="Karajan Code" width="180">
2
+ <img src="karajan-orbit.svg" alt="Karajan Code" width="220">
3
3
  </p>
4
4
 
5
5
  <h1 align="center">Karajan Code</h1>
6
6
 
7
7
  <p align="center">
8
- Orquestador local multi-agente. TDD-first, basado en MCP, JavaScript vanilla.
8
+ El entorno que gobierna el desarrollo con IA — tu agente orquesta, Karajan gobierna.
9
9
  </p>
10
10
 
11
11
  <p align="center">
12
- <a href="https://www.npmjs.com/package/karajan-code"><img src="https://img.shields.io/npm/v/karajan-code.svg" alt="npm version"></a>
13
- <a href="https://www.npmjs.com/package/karajan-code"><img src="https://img.shields.io/npm/dw/karajan-code.svg" alt="npm downloads"></a>
14
- <a href="https://github.com/manufosela/karajan-code/actions"><img src="https://github.com/manufosela/karajan-code/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
15
- <a href="https://www.gnu.org/licenses/agpl-3.0"><img src="https://img.shields.io/badge/license-AGPL--3.0-blue.svg" alt="License"></a>
16
- <a href="https://nodejs.org"><img src="https://img.shields.io/badge/node-%3E%3D18-brightgreen.svg" alt="Node.js"></a>
17
- <a href="https://github.com/manufosela/homebrew-tap"><img src="https://img.shields.io/badge/homebrew-tap-orange.svg" alt="Homebrew"></a>
18
- </p>
19
-
20
- <p align="center">
21
- <a href="../README.md">Read in English</a> · <a href="https://karajancode.com">Documentacion</a> · <a href="https://planning-game-xp.web.app/public/?project=Karajan%20Code">Roadmap publico</a>
12
+ <a href="../README.md">Read in English</a> · <a href="https://karajancode.com">Documentación</a> · <a href="https://planning-game-xp.web.app/public/?project=Karajan%20Code">Roadmap público</a>
22
13
  </p>
23
14
 
24
15
  ---
25
16
 
26
- Tu describes lo que quieres construir. Karajan orquesta multiples agentes de IA para planificarlo, implementarlo, testearlo, revisarlo con SonarQube e iterar. Sin que tengas que supervisar cada paso.
27
-
28
- ## Que es Karajan?
29
-
30
- Karajan es un orquestador de codigo local. Corre en tu maquina, usa tus proveedores de IA existentes (Claude, Codex, Gemini, Aider, OpenCode) y coordina un pipeline de agentes especializados que trabajan juntos en tu codigo.
31
-
32
- No es un servicio en la nube. No es una extension de VS Code. Es una herramienta que instalas una vez y usas desde la terminal o como servidor MCP dentro de tu agente de IA.
33
-
34
- El nombre viene de Herbert von Karajan, el director de orquesta que creia que las mejores orquestas estan formadas por grandes musicos independientes que saben exactamente cuando tocar y cuando escuchar. La misma idea, aplicada a agentes de IA.
35
-
36
- ## Por que no usar solo Claude Code?
37
-
38
- Claude Code es excelente. Usalo para codificacion interactiva basada en sesiones.
39
-
40
- Usa Karajan cuando quieras:
41
-
42
- - **Un pipeline repetible y documentado** que corre igual cada vez
43
- - **TDD por defecto.** Los tests se escriben antes de la implementacion, no despues
44
- - **Integracion con SonarQube.** Quality gates como parte del flujo, no como algo secundario
45
- - **Solomon como jefe del pipeline.** Cada rechazo del reviewer es evaluado por un supervisor que decide si es valido o solo ruido de estilo
46
- - **Enrutamiento multi-proveedor.** Claude como coder, Codex como reviewer, o cualquier combinacion
47
- - **Operacion zero-config.** Auto-detecta frameworks de test, arranca SonarQube, simplifica el pipeline para tareas triviales
48
- - **Arquitectura de roles composable.** Comportamientos de agente definidos como ficheros markdown que viajan con tu proyecto
49
- - **Local-first.** Tu codigo, tus claves, tu maquina. Ningun dato sale salvo que tu lo digas
50
- - **Zero costes de API.** Karajan usa CLIs de agentes de IA (Claude Code, Codex, Gemini CLI), no APIs. Pagas tu suscripcion existente (Claude Pro, ChatGPT Plus), no tarifas por token
51
-
52
- Si Claude Code es un programador de pares inteligente, Karajan es el pipeline CI/CD para desarrollo asistido por IA. Funcionan genial juntos: Karajan esta diseñado para usarse como servidor MCP dentro de Claude Code.
53
-
54
- ## Instalacion
55
-
56
- **npm** (recomendado):
57
- ```bash
58
- npm install -g karajan-code
59
- ```
60
-
61
- **Homebrew** (macOS):
62
- ```bash
63
- brew install manufosela/tap/karajan-code
64
- ```
65
-
66
- **Binario standalone** (sin Node.js):
67
- ```bash
68
- # macOS (Apple Silicon)
69
- curl -L https://github.com/manufosela/karajan-code/releases/latest/download/kj-darwin-arm64 -o kj && chmod +x kj
70
-
71
- # Linux x64
72
- curl -L https://github.com/manufosela/karajan-code/releases/latest/download/kj-linux-x64 -o kj && chmod +x kj
73
-
74
- # Windows
75
- curl -L https://github.com/manufosela/karajan-code/releases/latest/download/kj-win-x64.exe -o kj.exe
76
- ```
77
-
78
- **One-liner** (detecta SO, instala via npm):
79
- ```bash
80
- curl -fsSL https://raw.githubusercontent.com/manufosela/karajan-code/main/scripts/install-kj.sh | sh
81
- ```
82
-
83
- **Docker**:
84
- ```bash
85
- docker run --rm -v $(pwd):/workspace karajan-code kj --version
86
- ```
87
-
88
- `kj init` auto-detecta tus agentes instalados e instala RTK para optimizacion de tokens.
89
-
90
- ## Tres formas de usar Karajan
91
-
92
- Karajan instala **tres comandos**: `kj`, `kj-tail` y `karajan-mcp`.
93
-
94
- ### 1. CLI: directamente desde terminal
95
-
96
- Ejecuta Karajan directamente. Ves la salida completa del pipeline en tiempo real.
97
-
98
- ```bash
99
- kj run "Crea una utilidad que valide numeros de DNI español, con tests"
100
- kj code "Añade validacion de inputs al formulario de registro" # Solo coder
101
- kj review "Revisa los cambios de autenticacion" # Revisar diff actual
102
- kj audit "Analisis completo de salud de este codebase" # Auditoria solo-lectura
103
- kj plan "Refactorizar la capa de base de datos" # Planificar sin codificar
104
- ```
105
-
106
- ### 2. MCP: dentro de tu agente de IA
107
-
108
- Este es el caso de uso principal. Karajan corre como servidor MCP dentro de Claude Code, Codex o Gemini. Le pides algo a tu agente de IA y el delega el trabajo pesado al pipeline de Karajan.
109
-
110
- ```
111
- Tu → Claude Code → kj_run (via MCP) → triage → coder → sonar → reviewer → tester → security
112
- ```
113
-
114
- El servidor MCP se auto-registra durante `npm install`. Tu agente de IA ve 27 herramientas (`kj_run`, `kj_code`, `kj_review`, `kj_hu`, etc.) y las usa segun necesite.
17
+ Tu agente de IA (Claude Code, Codex, Gemini CLI, Cursor…) escribe el código. **Karajan gobierna cómo ocurre**: instala un método que tu agente sigue en cada tarea y lo hace cumplir con gates de git que hacen el falso verde estructuralmente imposible.
115
18
 
116
- **El problema**: cuando Karajan corre dentro de un agente de IA, pierdes visibilidad. El agente te muestra el resultado final, pero no las etapas del pipeline, iteraciones o decisiones de Solomon en tiempo real.
19
+ - **RAG antes de suponer** — `kj rag query` responde qué hace tu código; ningún agente adivina.
20
+ - **Card primero** — todo trabajo se registra (`kj hu add|move|list`) antes de empezar; las decisiones de arquitectura viven como ADRs en git (`kj adr add|list`).
21
+ - **Los tests prueban el comportamiento** — el test que falla existe primero; la suite nunca se queda en rojo.
22
+ - **Revisión IA-cruzada en cada commit** — `kj review --staged` liga el veredicto de una IA *distinta* al sha256 del diff exacto. Cambia el código y hay que revisarlo de nuevo. Sin veredicto aprobado, **el commit no entra** (gate pre-commit).
23
+ - **Una tercera IA arbitra las disputas** — `kj solomon` decide cuando brain y reviewer discrepan. Los hallazgos de seguridad no los anula nadie — ni siquiera el arbitraje.
24
+ - **Rama primero** — la rama base solo se mueve por PRs atómicas.
117
25
 
118
- ### 3. kj-tail: monitorizar desde otro terminal
26
+ Este repo corre bajo su propio entorno: cada commit de karajan-code lleva un veredicto de IA cruzada.
119
27
 
120
- **La herramienta compañera.** Abre un segundo terminal en el **mismo directorio del proyecto** donde esta trabajando tu agente de IA:
28
+ ## Instalación
121
29
 
122
- ```bash
123
- kj-tail
124
- ```
125
-
126
- Veras la salida del pipeline en vivo (etapas, resultados, iteraciones, errores) tal como ocurren. La misma vista que ejecutar `kj run` directamente.
127
-
128
- ```
129
- kj-tail # Seguir pipeline en tiempo real (por defecto)
130
- kj-tail -v # Verbose: incluir heartbeats de agente y presupuesto
131
- kj-tail -t # Mostrar timestamps
132
- kj-tail -s # Snapshot: mostrar log actual y salir
133
- kj-tail -n 50 # Mostrar ultimas 50 lineas y seguir
134
- kj-tail --help # Todas las opciones
135
- ```
136
-
137
- > **Importante**: `kj-tail` debe ejecutarse desde el mismo directorio donde el agente de IA esta trabajando. Lee `<proyecto>/.kj/run.log`, que se crea cuando Karajan arranca un pipeline via MCP.
138
-
139
- [**Ver la demo completa del pipeline**](https://karajancode.com#demo): triage, arquitectura, TDD, SonarQube, code review, arbitraje de Solomon, auditoria de seguridad.
140
-
141
- ## El pipeline
142
-
143
- ```
144
- pre-loop: intent → hu-reviewer? → triage? → domain-curator? → discover? → skills? → researcher? → architect? → planner? → acceptance?
145
- iteration: coder → refactorer? → guard(output) → guard(perf) → sonar? → tdd → reviewer → solomon? → brain? (bucle 1..N)
146
- post-loop: tester? → security? → perf? → impeccable? → audit?
147
- ```
148
-
149
- **24 etapas** repartidas en tres fases: 18 roles respaldados por agente IA (tabla abajo), 6 etapas deterministas sin llamada al LLM (`intent`, `skills`, `acceptance`, `guard(output)`, `guard(perf)`, `tdd`). Dos clases extra (`commiter`, `repairer`) son post-aprobación / auxiliares internas, no etapas independientes del pipeline. Cada rol IA es ejecutado por el agente que tú elijas:
150
-
151
- | Rol | Que hace | Por defecto |
152
- |-----|----------|-------------|
153
- | **hu-reviewer** | Certifica historias de usuario antes de codificar (6 dimensiones, 7 antipatrones) | Auto (media/compleja) |
154
- | **triage** | Clasifica complejidad, activa roles, detecta domain hints | **On** |
155
- | **domain-curator** | Descubre, propone y sintetiza conocimiento de dominio de negocio para el pipeline | Auto (cuando existen dominios) |
156
- | **discover** | Detecta huecos en requisitos (Mom Test, Wendel, JTBD) | Off |
157
- | **architect** | Diseña la arquitectura de la solucion antes de planificar | Off |
158
- | **planner** | Genera planes de implementacion estructurados | Off |
159
- | **coder** | Escribe codigo y tests siguiendo metodologia TDD | **Siempre on** |
160
- | **refactorer** | Mejora la claridad del codigo sin cambiar comportamiento | Off |
161
- | **sonar** | Analisis estatico SonarQube con quality gate enforcement | On (auto-gestionado) |
162
- | **impeccable** | Auditoria UI/UX para tareas frontend (a11y, rendimiento, theming) | Auto (frontend) |
163
- | **reviewer** | Code review con perfiles de exigencia configurables | **Siempre on** |
164
- | **tester** | Quality gate de tests y verificacion de cobertura | **On** |
165
- | **security** | Auditoria de seguridad OWASP | **On** |
166
- | **solomon** | Jefe del pipeline: evalua cada rechazo, anula bloqueos solo de estilo | **On** |
167
- | **commiter** | Automatizacion de git commit, push y PR tras aprobacion | Off |
168
- | **researcher** | Investiga el codebase antes de planificar (mapa de ficheros + signatures + tests relacionados) | Off |
169
- | **perf** | Quality gate WebPerf — Core Web Vitals (LCP, CLS, INP) via Lighthouse | Off |
170
- | **brain** | Orquestador IA central: routing, enriquecimiento de feedback, compresión de salidas | **On** |
171
- | **audit** | Analisis de salud del codebase solo-lectura (5 dimensiones, scores A-F) | Standalone |
172
-
173
- > **Etapas deterministas (sin clase):** `intent` (clasificador de tipo de tarea — `sw` / `infra` / `doc` / `add-tests` / `refactor` / `audit`), `skills` (superficie de slash-commands), `acceptance` (tests de aceptación ejecutables), `guard(output)` (operaciones destructivas + fugas de credenciales), `guard(perf)` (anti-patrones frontend), `tdd` (verificación de cobertura).
174
- >
175
- > **Auxiliares internas (tienen clase, no etapa independiente):** `commiter` (automatización git post-aprobación), `repairer` (repara tests de aceptación rotos en runtime, invocado por `acceptance` / `tdd`).
176
- >
177
- > Referencia completa por etapa: [Roles del pipeline](https://karajan-code.web.app/docs/es/handbook/pipeline-roles/) (handbook).
178
-
179
- ## 5 agentes de IA soportados
180
-
181
- | Agente | CLI | Instalacion |
182
- |--------|-----|-------------|
183
- | **Claude** | `claude` | `npm install -g @anthropic-ai/claude-code` |
184
- | **Codex** | `codex` | `npm install -g @openai/codex` |
185
- | **Gemini** | `gemini` | Ver [Gemini CLI docs](https://github.com/google-gemini/gemini-cli) |
186
- | **Aider** | `aider` | `pipx install aider-chat` (o `pip3 install aider-chat`) |
187
- | **OpenCode** | `opencode` | Ver [OpenCode docs](https://github.com/nicepkg/opencode) |
188
-
189
- Mezcla y combina. Usa Claude como coder y Codex como reviewer. Karajan auto-detecta agentes instalados durante `kj init`.
190
-
191
- ## Servidor MCP (27 herramientas)
192
-
193
- Tras `npm install -g karajan-code`, el servidor MCP se auto-registra en Claude y Codex. Config manual si es necesario:
30
+ Dile a tu agente — en el directorio donde quieras trabajar:
194
31
 
195
- ```bash
196
- # Claude: añadir a ~/.claude.json → "mcpServers":
197
- # { "karajan-mcp": { "command": "karajan-mcp" } }
198
-
199
- # Codex: añadir a ~/.codex/config.toml → [mcp_servers."karajan-mcp"]
200
- # command = "karajan-mcp"
32
+ ```text
33
+ Quiero usar Karajan en este proyecto: lee https://karajancode.com/start.md
34
+ y haz lo que dice.
201
35
  ```
202
36
 
203
- **27 herramientas** disponibles: `kj_run`, `kj_code`, `kj_review`, `kj_plan`, `kj_board`, `kj_audit`, `kj_scan`, `kj_doctor`, `kj_config`, `kj_report`, `kj_resume`, `kj_roles`, `kj_agents`, `kj_preflight`, `kj_status`, `kj_init`, `kj_discover`, `kj_triage`, `kj_researcher`, `kj_architect`, `kj_hu`, `kj_skills`, `kj_suggest`, `kj_undo`, `kj_clean`, `kj_rag_query`, `kj_rag_index`.
204
-
205
- Usa `kj-tail` en un terminal separado para ver lo que el pipeline esta haciendo en tiempo real (ver [Tres formas de usar Karajan](#tres-formas-de-usar-karajan)).
206
-
207
- ## La arquitectura de roles
37
+ El prompt enrutador instala el stack completo si hace falta, detecta si el proyecto es nuevo o existente, activa el entorno, y **para a esperarte** cuando un paso necesita sudo o una cuenta (código de salida 3 de `kj` = pendiente de ti — una instalación parcial es una instalación fallida).
208
38
 
209
- Cada rol en Karajan esta definido por un fichero markdown: un documento plano que describe como debe comportarse el agente, que revisar y como es un buen output.
39
+ Equivalente manual:
210
40
 
41
+ ```sh
42
+ curl -fsSL https://karajancode.com/install.sh | sh # producto completo (npm-first; --standalone para solo-CLI)
43
+ kj doctor && kj install-tools # completa el stack
44
+ kj init && kj env install && kj harden && kj review --install-gate
45
+ git config core.hooksPath .karajan/hooks
211
46
  ```
212
- .karajan/roles/ # Overrides de proyecto (opcional)
213
- ~/.karajan/roles/ # Overrides globales (opcional)
214
- templates/roles/ # Defaults built-in (incluidos en el paquete)
215
- ```
216
-
217
- Puedes sobreescribir cualquier rol built-in o crear nuevos. Sin codigo. Los agentes leen los ficheros de rol y adaptan su comportamiento. Codifica las convenciones de tu equipo, reglas de dominio y estandares de calidad, y cada ejecucion de Karajan los aplica automaticamente.
218
-
219
- Usa `kj roles show <rol>` para inspeccionar cualquier template.
220
-
221
- ## Zero-config por diseño
222
-
223
- Karajan auto-detecta y auto-configura todo lo que puede:
224
-
225
- - **TDD**: Detecta framework de tests para 12 lenguajes (vitest, jest, JUnit, pytest, go test, cargo test, y mas). Auto-activa TDD para tareas de codigo, lo salta para doc/infra
226
- - **Bootstrap gate**: Valida todos los prerequisitos (repo git, remote, config, agentes, SonarQube) antes de ejecutar. Falla con instrucciones claras, nunca degrada silenciosamente
227
- - **Injection guard**: Escanea diffs en busca de prompt injection antes del review de IA. Detecta directivas de override, Unicode invisible, payloads en comentarios sobredimensionados. Tambien como GitHub Action en cada PR
228
- - **SonarQube**: Auto-arranca contenedor Docker, espera hasta 60s al arranque, genera config si falta
229
- - **Complejidad del pipeline**: Triage clasifica la tarea, las triviales saltan el loop del reviewer
230
- - **Caidas de proveedor**: Reintentos en 500/502/503/504 con backoff (igual que rate limits)
231
- - **Cobertura**: Fallos de quality gate solo por cobertura se tratan como advisory
232
- - **HU Manager**: Las tareas complejas se descomponen automaticamente en historias de usuario formales con dependencias. Cada HU se ejecuta como su propio sub-pipeline con seguimiento de estado visible en el HU Board
233
-
234
- Sin configuracion por proyecto requerida. Si quieres personalizar, la config se apila: sesion > proyecto > global.
235
47
 
236
- ## Por que JavaScript vanilla?
48
+ Requiere git y al menos un CLI de agente de IA — con dos hay revisión cruzada; con tres, arbitraje. Todas las rutas de instalación (npm, binarios, brew, wrapper Python) en la [doc de instalación](https://karajancode.com/docs/es/v4/install/).
237
49
 
238
- No es nostalgia ni cabezoneria. Es que llevo usando JavaScript desde 1997, cuando Brendan Eich lo creo en una semana y nos cambio la vida a los que haciamos webs. Conozco sus tripas, sus bugs, sus rarezas. Y se que quien conoce JS de verdad convierte esos bugs en features. TypeScript existe para que developers acostumbrados a lenguajes fuertemente tipados no entren en panico al ver JS. Respeto eso. Pero yo no lo necesito. Los tests son mi seguridad de tipos. JSDoc y un buen IDE son mi intellisense. Y no tener un compilador entre el codigo y yo es lo que me permite moverme a 57 releases en 45 dias sin miedo.
50
+ ## El bucle diario
239
51
 
240
- [Por que JavaScript vanilla: la version larga](why-vanilla-js.md)
52
+ 1. Describes lo que quieres. Tu agente crea la card (`kj hu add`), consulta el RAG, escribe el test que falla y después el código.
53
+ 2. `kj review --staged` — una IA distinta revisa el diff exacto. Aprobado → el commit entra. Rechazado → se corrige, o se escala a `kj solomon`.
54
+ 3. PR atómica a la rama base. `kj report` muestra el rastro; el HU Board (`kj board`) muestra el trabajo.
55
+ 4. ¿Tu agente choca con un bug de kj? `kj report-issue` lo sube — sanitizado, deduplicado y solo con tu aprobación. El ecosistema se repara solo.
241
56
 
242
- ## Compañeros recomendados
57
+ Método completo: [Trabaja con tu agente](https://karajancode.com/docs/es/v4/working-with-your-agent/) · [Los gates](https://karajancode.com/docs/es/v4/gates/) · [Referencia de comandos](https://karajancode.com/docs/es/v4/commands/).
243
58
 
244
- | Herramienta | Por que |
245
- |-------------|---------|
246
- | [**RTK**](https://github.com/rtk-ai/rtk) | Reduce consumo de tokens 60-90% en salidas de comandos Bash |
247
- | [**Planning Game MCP**](https://github.com/AgenteIA-Geniova/planning-game-mcp) | Gestion agil de proyectos (tareas, sprints, estimacion), nativo XP |
248
- | [**GitHub MCP**](https://github.com/modelcontextprotocol/servers/tree/main/src/github) | Crear PRs, gestionar issues directamente desde el agente |
249
- | [**Chrome DevTools MCP**](https://github.com/anthropics/anthropic-quickstarts/tree/main/chrome-devtools-mcp) | Verificar cambios de UI visualmente tras modificar frontend |
59
+ ## Modo headless
250
60
 
251
- ## Contribuir
61
+ El pipeline multiagente clásico sigue vivo para CI y automatización: `kj run "<tarea>"` orquesta roles coder/reviewer/tester en subprocesos sin humano delante, con los mismos gates. `kj advanced` lista la superficie completa. [Doc del modo headless](https://karajancode.com/docs/es/v4/headless/).
252
62
 
253
- ```bash
254
- git clone https://github.com/manufosela/karajan-code.git
255
- cd karajan-code
256
- npm install
257
- npm test # Ejecutar ~5 368 tests en 482 ficheros con Vitest
258
- npm run validate # Lint + test
259
- ```
260
-
261
- Issues y pull requests bienvenidos. Si algo no funciona como esta documentado, [abre un issue](https://github.com/manufosela/karajan-code/issues). Es la contribucion mas util en esta fase.
262
-
263
- ## Telemetria
264
-
265
- Karajan recopila estadisticas de uso anonimas para mejorar la herramienta:
266
- version, sistema operativo, comando utilizado, duracion del pipeline y tasa de exito.
267
- No se envia nunca codigo, descripciones de tareas ni datos personales.
268
-
269
- Desactivar: establece `telemetry: false` en `~/.karajan/kj.config.yml`
270
-
271
- ## Enlaces
272
-
273
- - [Web](https://karajancode.com) (tambien [kj-code.com](https://kj-code.com))
274
- - [Documentacion completa](https://karajancode.com/docs/)
275
- - [Changelog](../CHANGELOG.md)
276
- - [Politica de seguridad](../SECURITY.md)
277
- - [Licencia (AGPL-3.0)](../LICENSE)
278
-
279
- ---
63
+ ## v3 (histórico)
280
64
 
281
- Construido por [@manufosela](https://github.com/manufosela). Head of Engineering en Geniova Technologies, co-organizador de NodeJS Madrid, autor de [Liderazgo Afectivo](https://www.liderazgoafectivo.com). 90+ paquetes npm publicados.
65
+ Karajan v1–v3 fue un pipeline multiagente headless dirigido por completo mediante orquestación de subprocesos. Su historia íntegra — pipeline, 24 roles, servidor MCP, step mode, carriles paralelos — se conserva en el **[README de v3 (archivo histórico)](README.v3.es.md)** y en el [archivo de docs v3](https://karajancode.com/docs/es/getting-started/introduction/).
282
66
 
283
- ### Contributors
67
+ ## Contribuir y licencia
284
68
 
285
- - [@aitormf](https://github.com/aitormf) — Agente OpenCode (5o agente built-in)
286
- - [@reiaguilera](https://github.com/reiaguilera) — Beta testing, propuestas de mejora y feedback de calidad
69
+ Issues y PRs bienvenidas — los informes de fricción vía `kj report-issue` valen oro. Licencia [AGPL-3.0](../LICENSE).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "karajan-code",
3
- "version": "4.1.3",
3
+ "version": "4.1.5",
4
4
  "description": "Local multi-agent coding orchestrator with TDD, SonarQube, and code review pipeline",
5
5
  "type": "module",
6
6
  "license": "AGPL-3.0",
@@ -37,12 +37,16 @@ function extractGeminiUsage(text) {
37
37
  }
38
38
 
39
39
  export class GeminiAgent extends BaseAgent {
40
+ // Overridden by forks with the same headless interface (QwenAgent).
41
+ get cliBin() { return "gemini"; }
42
+ get spawnEnv() { return { GEMINI_CLI_TRUST_WORKSPACE: "true" }; }
43
+
40
44
  async runTask(task) {
41
45
  const role = task.role || "coder";
42
46
  const model = this.getRoleModel(role);
43
47
  const result = await this._exec(task, model, "run");
44
48
  if (!result.ok && model && this.isModelNotSupportedError(result)) {
45
- this.logger?.warn(`Gemini model "${model}" not supported — retrying with agent default`);
49
+ this.logger?.warn(`${this.cliBin} model "${model}" not supported — retrying with agent default`);
46
50
  return this._exec(task, null, "run");
47
51
  }
48
52
  return result;
@@ -53,17 +57,24 @@ export class GeminiAgent extends BaseAgent {
53
57
  const model = this.getRoleModel(role);
54
58
  const result = await this._exec(task, model, "review");
55
59
  if (!result.ok && model && this.isModelNotSupportedError(result)) {
56
- this.logger?.warn(`Gemini model "${model}" not supported — retrying with agent default`);
60
+ this.logger?.warn(`${this.cliBin} model "${model}" not supported — retrying with agent default`);
57
61
  return this._exec(task, null, "review");
58
62
  }
59
63
  return result;
60
64
  }
61
65
 
62
66
  async _exec(task, model, mode) {
63
- const args = ["-p", task.prompt];
67
+ // KJC-BUG-0121: the prompt NEVER travels as a CLI argument — a solomon
68
+ // prompt embeds the full diff, and large diffs blow past the kernel's
69
+ // per-argument limit (E2BIG). gemini reads the prompt from stdin in
70
+ // headless mode. Same bug's layer 2: headless gemini refuses untrusted
71
+ // workspaces unless GEMINI_CLI_TRUST_WORKSPACE is set.
72
+ const args = [];
64
73
  if (mode === "review") args.push("--output-format", "json");
65
74
  if (model) args.push("--model", model);
66
- const res = await this.runCommand(resolveBin("gemini"), args, {
75
+ const res = await this.runCommand(resolveBin(this.cliBin), args, {
76
+ input: task.prompt,
77
+ env: this.spawnEnv,
67
78
  onOutput: task.onOutput,
68
79
  silenceTimeoutMs: task.silenceTimeoutMs,
69
80
  timeout: task.timeoutMs
@@ -3,6 +3,7 @@ import { CodexAgent } from "./codex-agent.js";
3
3
  import { GeminiAgent } from "./gemini-agent.js";
4
4
  import { AiderAgent } from "./aider-agent.js";
5
5
  import { OpenCodeAgent } from "./opencode-agent.js";
6
+ import { QwenAgent } from "./qwen-agent.js";
6
7
 
7
8
  const agentRegistry = new Map();
8
9
 
@@ -49,3 +50,4 @@ registerAgent("codex", CodexAgent, { bin: "codex", installUrl: "https://develope
49
50
  registerAgent("gemini", GeminiAgent, { bin: "gemini", installUrl: "https://github.com/google-gemini/gemini-cli" });
50
51
  registerAgent("aider", AiderAgent, { bin: "aider", installUrl: "https://aider.chat/docs/install.html" });
51
52
  registerAgent("opencode", OpenCodeAgent, { bin: "opencode", installUrl: "https://opencode.ai" });
53
+ registerAgent("qwen", QwenAgent, { bin: "qwen", installUrl: "https://github.com/QwenLM/qwen-code" });
@@ -0,0 +1,20 @@
1
+ import { GeminiAgent } from "./gemini-agent.js";
2
+
3
+ /**
4
+ * Qwen Code (@qwen-code/qwen-code, binary `qwen`) — KJC-TSK-0665.
5
+ *
6
+ * A gemini-cli fork with the same headless interface (prompt on stdin,
7
+ * `--output-format json`, `--model`, identical usageMetadata shape), so it
8
+ * inherits everything from GeminiAgent including the KJC-BUG-0121 stdin
9
+ * contract. Cloud-backed and free with a Qwen account: the sixth built-in
10
+ * agent, and the natural third AI for solomon arbitration now that the
11
+ * gemini individual tier is retired.
12
+ */
13
+ export class QwenAgent extends GeminiAgent {
14
+ get cliBin() { return "qwen"; }
15
+ // qwen has no workspace-trust gate. execa merges this object over
16
+ // process.env, so the explicit undefined REMOVES gemini's var from the
17
+ // child even when the parent shell exported it (manual workarounds) —
18
+ // returning no env at all would let it leak through inheritance.
19
+ get spawnEnv() { return { GEMINI_CLI_TRUST_WORKSPACE: undefined }; }
20
+ }
@@ -81,7 +81,18 @@ export async function runSolomonArbitration({
81
81
  logger?.info?.(`kj solomon: brain=${hostAgent || "?"} vs reviewer=${verdict.reviewer} → arbiter=${solomon}`);
82
82
  const agent = createAgentFn(solomon, config, logger);
83
83
  const result = await agent.reviewTask({ prompt, role: "solomon" });
84
- if (!result?.ok) throw new Error(`solomon ${solomon} failed: ${result?.error || "no output"}`);
84
+ if (!result?.ok) {
85
+ // KJC-BUG-0121 layer 3: a binary on PATH is not an OPERATIONAL arbiter
86
+ // (dead account tier, auth, trust). Fail with the way out, not just the
87
+ // wreckage: name the other agents that could arbitrate instead.
88
+ const others = (await detectAgents())
89
+ .filter((a) => a.available && a.name !== solomon && a.name !== hostAgent && a.name !== verdict.reviewer)
90
+ .map((a) => a.name);
91
+ const hint = others.length > 0
92
+ ? `If ${solomon} is not operational on this machine (account tier, auth, workspace trust), set roles.solomon.provider in your kj config to another agent: ${others.join(", ")}.`
93
+ : `No other agent CLI on this machine can arbitrate (needs one distinct from brain "${hostAgent}" and reviewer "${verdict.reviewer}") — install a third agent CLI or fix ${solomon}.`;
94
+ throw new Error(`solomon ${solomon} failed: ${String(result?.error || "no output").slice(0, 400)}\n${hint}`);
95
+ }
85
96
  const parsed = parseMaybeJsonString(result.output);
86
97
  if (!parsed || !["approve", "reject"].includes(parsed.ruling)) {
87
98
  throw new Error(`solomon ${solomon} returned no parseable ruling`);
@@ -7,7 +7,8 @@ const KNOWN_AGENTS = [
7
7
  { name: "codex", install: getInstallCommand("codex") },
8
8
  { name: "gemini", install: getInstallCommand("gemini") },
9
9
  { name: "aider", install: getInstallCommand("aider") },
10
- { name: "opencode", install: getInstallCommand("opencode") }
10
+ { name: "opencode", install: getInstallCommand("opencode") },
11
+ { name: "qwen", install: getInstallCommand("qwen") }
11
12
  ];
12
13
 
13
14
  export async function checkBinary(name, versionArg = "--version") {
@@ -44,6 +44,12 @@ export function osvScannerSource(platform = process.platform, arch = process.arc
44
44
  */
45
45
  export function semgrepFallback(available = {}) {
46
46
  if (available.docker) return { via: "docker", command: "docker pull semgrep/semgrep" };
47
+ // KJC-BUG-0120 (issue #1256): on Debian/Ubuntu-like systems the system
48
+ // Python is externally managed (PEP 668) and often ships without pip at
49
+ // all — `python3 -m pip install --user` is guaranteed to fail there.
50
+ // pipx must come from the distro's own package manager.
51
+ if (available.apt) return { via: "apt", command: "sudo apt update && sudo apt install -y pipx && pipx install semgrep" };
52
+ if (available.dnf) return { via: "dnf", command: "sudo dnf install -y pipx && pipx install semgrep" };
47
53
  return { via: "pipx", command: "python3 -m pip install --user pipx && pipx install semgrep" };
48
54
  }
49
55
 
@@ -4,7 +4,6 @@ import { fileURLToPath } from "node:url";
4
4
  import { printBanner } from "../banner.js";
5
5
  import { ANSI } from "./formatters.js";
6
6
 
7
- // TODO: i18n display messages
8
7
  const DISPLAY_PKG_PATH = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../../../package.json");
9
8
  const DISPLAY_VERSION = JSON.parse(readFileSync(DISPLAY_PKG_PATH, "utf8")).version;
10
9
 
@@ -80,8 +80,13 @@ export async function getInstallHint(tool, available = null) {
80
80
  for (const { manager, command } of candidates) {
81
81
  if (avail[manager]) return { command, manager, manualUrl: MANUAL_URLS[tool] };
82
82
  }
83
- // Nothing matched — fall back to the first candidate's command as a
84
- // suggestion, so the user at least sees a working recipe.
83
+ // Nothing matched — suggest a recipe that actually works on this system.
84
+ // KJC-BUG-0120 (issue #1256): distro-aware fallbacks first (PEP 668 makes
85
+ // the generic pip bootstrap fail on Debian/Ubuntu); these are display-only
86
+ // (manager: null), never auto-run — sudo stays in the user's hands.
87
+ for (const { when, command } of DISTRO_FALLBACKS[tool] || []) {
88
+ if (avail[when]) return { command, manager: null, manualUrl: MANUAL_URLS[tool] };
89
+ }
85
90
  const first = candidates[0];
86
91
  return {
87
92
  command: first ? first.command : null,
@@ -90,6 +95,13 @@ export async function getInstallHint(tool, available = null) {
90
95
  };
91
96
  }
92
97
 
98
+ const DISTRO_FALLBACKS = {
99
+ semgrep: [
100
+ { when: "apt", command: "sudo apt update && sudo apt install -y pipx && pipx install semgrep" },
101
+ { when: "dnf", command: "sudo dnf install -y pipx && pipx install semgrep" },
102
+ ],
103
+ };
104
+
93
105
  const INSTALL_CANDIDATES = {
94
106
  semgrep: [
95
107
  { manager: "pipx", command: "pipx install semgrep" },
@@ -51,6 +51,11 @@ const INSTALL_COMMANDS = {
51
51
  linux: "curl -fsSL https://opencode.ai/install | bash",
52
52
  windows: "See https://github.com/nicepkg/opencode for Windows install"
53
53
  },
54
+ qwen: {
55
+ macos: "npm install -g @qwen-code/qwen-code",
56
+ linux: "npm install -g @qwen-code/qwen-code",
57
+ windows: "npm install -g @qwen-code/qwen-code"
58
+ },
54
59
  docker: {
55
60
  macos: "brew install --cask docker",
56
61
  linux: "sudo apt install docker.io docker-compose-v2 (or see https://docs.docker.com/engine/install/)",
@@ -25,7 +25,9 @@ const OS_COMMANDS = {
25
25
  win32: ["winget install Git.Git"],
26
26
  },
27
27
  semgrep: {
28
- linux: ["python3 -m pip install --user semgrep # or: pipx install semgrep"],
28
+ // PEP 668 (#1256): system Python is externally managed on modern
29
+ // distros — pipx comes from the distro package manager, never from pip.
30
+ linux: ["sudo apt update && sudo apt install -y pipx && pipx install semgrep # Debian/Ubuntu", "sudo dnf install -y pipx && pipx install semgrep # Fedora/RHEL"],
29
31
  darwin: ["brew install semgrep"],
30
32
  win32: ["python -m pip install --user semgrep"],
31
33
  },
@@ -75,10 +77,11 @@ export function renderPendingBlock(pending, { platform = process.platform, retry
75
77
  for (const r of pending) {
76
78
  const why = r.error ? `install failed: ${r.error}` : r.reason || "no automatic route on this machine";
77
79
  lines.push(` ▸ ${r.tool} (${why})`);
78
- const commands = r.commands
79
- ?? (r.command ? [r.command] : null)
80
- ?? (r.suggested ? [r.suggested] : null)
81
- ?? (osCommandsFor(r.tool, platform).length > 0 ? osCommandsFor(r.tool, platform) : null)
80
+ const os = osCommandsFor(r.tool, platform);
81
+ const own = r.commands ?? (r.command ? [r.command] : null) ?? (r.suggested ? [r.suggested] : null);
82
+ // A FAILED install must not be re-suggested verbatim (#1256: the pip
83
+ // route that just broke) — the curated per-OS route goes first there.
84
+ const commands = (r.action === "failed" ? (os.length > 0 ? os : own) : (own ?? (os.length > 0 ? os : null)))
82
85
  ?? [`see ${r.manualUrl || "the tool's install docs"}`];
83
86
  for (const c of commands) lines.push(` ${c}`);
84
87
  lines.push("");