karajan-code 1.36.1 → 1.37.0
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/README.md +31 -30
- package/docs/README.es.md +35 -34
- package/package.json +1 -1
- package/src/orchestrator/iteration-stages.js +50 -15
- package/src/orchestrator/post-loop-stages.js +25 -11
- package/src/orchestrator/pre-loop-stages.js +28 -20
- package/src/orchestrator/preflight-checks.js +3 -3
- package/src/orchestrator/solomon-escalation.js +3 -2
- package/src/orchestrator.js +6 -5
- package/src/utils/display.js +133 -23
- package/src/utils/injection-guard.js +171 -0
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
|
|
23
23
|
---
|
|
24
24
|
|
|
25
|
-
You describe what you want to build. Karajan orchestrates multiple AI agents to plan it, implement it, test it, review it with SonarQube, and iterate
|
|
25
|
+
You describe what you want to build. Karajan orchestrates multiple AI agents to plan it, implement it, test it, review it with SonarQube, and iterate. No babysitting required.
|
|
26
26
|
|
|
27
27
|
## What is Karajan?
|
|
28
28
|
|
|
@@ -30,7 +30,7 @@ Karajan is a local coding orchestrator. It runs on your machine, uses your exist
|
|
|
30
30
|
|
|
31
31
|
It is not a hosted service. It is not a VS Code extension. It is a tool you install once and use from the terminal or as an MCP server inside your AI agent.
|
|
32
32
|
|
|
33
|
-
The name comes from Herbert von Karajan
|
|
33
|
+
The name comes from Herbert von Karajan, the conductor who believed that the best orchestras are made of great independent musicians who know exactly when to play and when to listen. Same idea, applied to AI agents.
|
|
34
34
|
|
|
35
35
|
## Why not just use Claude Code?
|
|
36
36
|
|
|
@@ -39,16 +39,16 @@ Claude Code is excellent. Use it for interactive, session-based coding.
|
|
|
39
39
|
Use Karajan when you want:
|
|
40
40
|
|
|
41
41
|
- **A repeatable, documented pipeline** that runs the same way every time
|
|
42
|
-
- **TDD by default
|
|
43
|
-
- **SonarQube integration
|
|
44
|
-
- **Solomon as pipeline boss
|
|
45
|
-
- **Multi-provider routing
|
|
46
|
-
- **Zero-config operation
|
|
47
|
-
- **Composable role architecture
|
|
48
|
-
- **Local-first
|
|
49
|
-
- **Zero API costs
|
|
42
|
+
- **TDD by default.** Tests are written before implementation, not after
|
|
43
|
+
- **SonarQube integration.** Code quality gates as part of the flow, not an afterthought
|
|
44
|
+
- **Solomon as pipeline boss.** Every reviewer rejection is evaluated by a supervisor that decides if it's valid or just style noise
|
|
45
|
+
- **Multi-provider routing.** Claude as coder, Codex as reviewer, or any combination
|
|
46
|
+
- **Zero-config operation.** Auto-detects test frameworks, starts SonarQube, simplifies pipeline for trivial tasks
|
|
47
|
+
- **Composable role architecture.** Agent behaviors defined as plain markdown files that travel with your project
|
|
48
|
+
- **Local-first.** Your code, your keys, your machine. No data leaves unless you say so
|
|
49
|
+
- **Zero API costs.** Karajan uses AI agent CLIs (Claude Code, Codex, Gemini CLI), not APIs. You pay your existing subscription (Claude Pro, ChatGPT Plus), not per-token API fees
|
|
50
50
|
|
|
51
|
-
If Claude Code is a smart pair programmer, Karajan is the CI/CD pipeline for AI-assisted development. They work great together
|
|
51
|
+
If Claude Code is a smart pair programmer, Karajan is the CI/CD pipeline for AI-assisted development. They work great together: Karajan is designed to be used as an MCP server inside Claude Code.
|
|
52
52
|
|
|
53
53
|
## Install
|
|
54
54
|
|
|
@@ -62,7 +62,7 @@ That's it. No Docker required (SonarQube uses Docker, but Karajan auto-manages i
|
|
|
62
62
|
|
|
63
63
|
Karajan installs **three commands**: `kj`, `kj-tail`, and `karajan-mcp`.
|
|
64
64
|
|
|
65
|
-
### 1. CLI
|
|
65
|
+
### 1. CLI: direct from terminal
|
|
66
66
|
|
|
67
67
|
Run Karajan directly. You see the full pipeline output in real time.
|
|
68
68
|
|
|
@@ -74,7 +74,7 @@ kj audit "Full health analysis of this codebase" # Read-only audit
|
|
|
74
74
|
kj plan "Refactor the database layer" # Plan without coding
|
|
75
75
|
```
|
|
76
76
|
|
|
77
|
-
### 2. MCP
|
|
77
|
+
### 2. MCP: inside your AI agent
|
|
78
78
|
|
|
79
79
|
This is the primary use case. Karajan runs as an MCP server inside Claude Code, Codex, or Gemini. You ask your AI agent to do something, and it delegates the heavy lifting to Karajan's pipeline.
|
|
80
80
|
|
|
@@ -86,7 +86,7 @@ The MCP server auto-registers during `npm install`. Your AI agent sees 20 tools
|
|
|
86
86
|
|
|
87
87
|
**The problem**: when Karajan runs inside an AI agent, you lose visibility. The agent shows you the final result, but not the pipeline stages, iterations, or Solomon decisions happening in real time.
|
|
88
88
|
|
|
89
|
-
### 3. kj-tail
|
|
89
|
+
### 3. kj-tail: monitor from a separate terminal
|
|
90
90
|
|
|
91
91
|
**This is the companion tool.** Open a second terminal in the **same project directory** where your AI agent is working, and run:
|
|
92
92
|
|
|
@@ -94,7 +94,7 @@ The MCP server auto-registers during `npm install`. Your AI agent sees 20 tools
|
|
|
94
94
|
kj-tail
|
|
95
95
|
```
|
|
96
96
|
|
|
97
|
-
You'll see the live pipeline output
|
|
97
|
+
You'll see the live pipeline output (stages, results, iterations, errors) as they happen. Same view as running `kj run` directly.
|
|
98
98
|
|
|
99
99
|
```
|
|
100
100
|
kj-tail # Follow pipeline in real time (default)
|
|
@@ -118,7 +118,7 @@ kj-tail --help # Full options
|
|
|
118
118
|
│ priority task │ │ ├─ 📋 Triage: medium │
|
|
119
119
|
│ │ │ ├─ 🔬 Researcher ✅ │
|
|
120
120
|
│ (Claude calls kj_run │ │ ├─ 🧠 Planner ✅ │
|
|
121
|
-
│ via MCP
|
|
121
|
+
│ via MCP, you see │ │ ├─ 🔨 Coder ✅ │
|
|
122
122
|
│ only the final result) │ │ ├─ 🔍 Sonar: OK │
|
|
123
123
|
│ │ │ ├─ 👁️ Reviewer ❌ │
|
|
124
124
|
│ │ │ ├─ ⚖️ Solomon: 2 cond. │
|
|
@@ -129,7 +129,7 @@ kj-tail --help # Full options
|
|
|
129
129
|
└─────────────────────────┘ └─────────────────────────┘
|
|
130
130
|
```
|
|
131
131
|
|
|
132
|
-
**Full pipeline example
|
|
132
|
+
**Full pipeline example**, a complex task with all roles:
|
|
133
133
|
|
|
134
134
|
```
|
|
135
135
|
┌─ Terminal 1 ─────────────────────────────────────────────────────────────────┐
|
|
@@ -154,7 +154,7 @@ kj-tail --help # Full options
|
|
|
154
154
|
|
|
155
155
|
┌─ Terminal 2: kj-tail ────────────────────────────────────────────────────────┐
|
|
156
156
|
│ │
|
|
157
|
-
│ kj-tail v1.
|
|
157
|
+
│ kj-tail v1.37.0 — .kj/run.log │
|
|
158
158
|
│ │
|
|
159
159
|
│ ├─ 📋 Triage: medium (sw) — enabling researcher, architect, planner │
|
|
160
160
|
│ ├─ ⚙️ Preflight passed — all checks OK │
|
|
@@ -193,7 +193,7 @@ kj-tail --help # Full options
|
|
|
193
193
|
└──────────────────────────────────────────────────────────────────────────────┘
|
|
194
194
|
```
|
|
195
195
|
|
|
196
|
-
[
|
|
196
|
+
[**Watch the full pipeline demo**](https://karajancode.com#demo): triage, architecture, TDD, SonarQube, code review, Solomon arbitration, security audit.
|
|
197
197
|
|
|
198
198
|
## The pipeline
|
|
199
199
|
|
|
@@ -217,7 +217,7 @@ hu-reviewer? → triage → discover? → architect? → planner? → coder →
|
|
|
217
217
|
| **reviewer** | Code review with configurable strictness profiles | **Always on** |
|
|
218
218
|
| **tester** | Test quality gate and coverage verification | **On** |
|
|
219
219
|
| **security** | OWASP security audit | **On** |
|
|
220
|
-
| **solomon** | Pipeline boss
|
|
220
|
+
| **solomon** | Pipeline boss: evaluates every rejection, overrides style-only blocks | **On** |
|
|
221
221
|
| **commiter** | Git commit, push, and PR automation after approval | Off |
|
|
222
222
|
| **audit** | Read-only codebase health analysis (5 dimensions, A-F scores) | Standalone |
|
|
223
223
|
|
|
@@ -233,7 +233,7 @@ hu-reviewer? → triage → discover? → architect? → planner? → coder →
|
|
|
233
233
|
|
|
234
234
|
Mix and match. Use Claude as coder and Codex as reviewer. Karajan auto-detects installed agents during `kj init`.
|
|
235
235
|
|
|
236
|
-
## MCP server
|
|
236
|
+
## MCP server (20 tools)
|
|
237
237
|
|
|
238
238
|
After `npm install -g karajan-code`, the MCP server auto-registers in Claude and Codex. Manual config if needed:
|
|
239
239
|
|
|
@@ -251,7 +251,7 @@ Use `kj-tail` in a separate terminal to see what the pipeline is doing in real t
|
|
|
251
251
|
|
|
252
252
|
## The role architecture
|
|
253
253
|
|
|
254
|
-
Every role in Karajan is defined by a markdown file
|
|
254
|
+
Every role in Karajan is defined by a markdown file: a plain document that describes how the agent should behave, what to check, and what good output looks like.
|
|
255
255
|
|
|
256
256
|
```
|
|
257
257
|
.karajan/roles/ # Project overrides (optional)
|
|
@@ -259,7 +259,7 @@ Every role in Karajan is defined by a markdown file — a plain document that de
|
|
|
259
259
|
templates/roles/ # Built-in defaults (shipped with package)
|
|
260
260
|
```
|
|
261
261
|
|
|
262
|
-
You can override any built-in role or create new ones. No code required. The agents read the role files and adapt their behavior.
|
|
262
|
+
You can override any built-in role or create new ones. No code required. The agents read the role files and adapt their behavior. Encode your team's conventions, domain rules, and quality standards, and every run of Karajan applies them automatically.
|
|
263
263
|
|
|
264
264
|
Use `kj roles show <role>` to inspect any template.
|
|
265
265
|
|
|
@@ -268,7 +268,8 @@ Use `kj roles show <role>` to inspect any template.
|
|
|
268
268
|
Karajan auto-detects and auto-configures everything it can:
|
|
269
269
|
|
|
270
270
|
- **TDD**: Detects test framework (vitest, jest, mocha) → auto-enables TDD
|
|
271
|
-
- **Bootstrap gate**: Validates all prerequisites (git repo, remote, config, agents, SonarQube) before any tool runs. Fails hard with actionable fix instructions
|
|
271
|
+
- **Bootstrap gate**: Validates all prerequisites (git repo, remote, config, agents, SonarQube) before any tool runs. Fails hard with actionable fix instructions, never silently degrades
|
|
272
|
+
- **Injection guard**: Scans diffs for prompt injection before AI review. Detects directive overrides, invisible Unicode, oversized comment payloads. Also runs as a GitHub Action on every PR
|
|
272
273
|
- **SonarQube**: Auto-starts Docker container, generates config if missing
|
|
273
274
|
- **Pipeline complexity**: Triage classifies task → trivial tasks skip reviewer loop
|
|
274
275
|
- **Provider outages**: Retries on 500/502/503/504 with backoff (same as rate limits)
|
|
@@ -280,16 +281,16 @@ No per-project configuration required. If you want to customize, config is layer
|
|
|
280
281
|
|
|
281
282
|
Because it should be.
|
|
282
283
|
|
|
283
|
-
Karajan has **
|
|
284
|
+
Karajan has **2044 tests** across 161 files. It runs on Node.js without a build step. You can read the source, understand it, fork it, and modify it without a TypeScript compiler between you and the code.
|
|
284
285
|
|
|
285
|
-
This is a deliberate choice, not a limitation. The tests are the type safety. The legibility is a feature.
|
|
286
|
+
This is a deliberate choice, not a limitation. The tests are the type safety. The legibility is a feature. 57 releases in 45 days. That velocity is possible precisely because vanilla JS with good tests lets you move fast without fear.
|
|
286
287
|
|
|
287
288
|
## Recommended companions
|
|
288
289
|
|
|
289
290
|
| Tool | Why |
|
|
290
291
|
|------|-----|
|
|
291
292
|
| [**RTK**](https://github.com/rtk-ai/rtk) | Reduces token consumption by 60-90% on Bash command outputs |
|
|
292
|
-
| [**Planning Game MCP**](https://github.com/AgenteIA-Geniova/planning-game-mcp) | Agile project management (tasks, sprints, estimation)
|
|
293
|
+
| [**Planning Game MCP**](https://github.com/AgenteIA-Geniova/planning-game-mcp) | Agile project management (tasks, sprints, estimation), XP-native |
|
|
293
294
|
| [**GitHub MCP**](https://github.com/modelcontextprotocol/servers/tree/main/src/github) | Create PRs, manage issues directly from the agent |
|
|
294
295
|
| [**Chrome DevTools MCP**](https://github.com/anthropics/anthropic-quickstarts/tree/main/chrome-devtools-mcp) | Verify UI changes visually after frontend modifications |
|
|
295
296
|
|
|
@@ -299,11 +300,11 @@ This is a deliberate choice, not a limitation. The tests are the type safety. Th
|
|
|
299
300
|
git clone https://github.com/manufosela/karajan-code.git
|
|
300
301
|
cd karajan-code
|
|
301
302
|
npm install
|
|
302
|
-
npm test # Run
|
|
303
|
+
npm test # Run 2044 tests with Vitest
|
|
303
304
|
npm run validate # Lint + test
|
|
304
305
|
```
|
|
305
306
|
|
|
306
|
-
Issues and pull requests welcome. If something doesn't work as documented, [open an issue](https://github.com/manufosela/karajan-code/issues)
|
|
307
|
+
Issues and pull requests welcome. If something doesn't work as documented, [open an issue](https://github.com/manufosela/karajan-code/issues). That's the most useful contribution at this stage.
|
|
307
308
|
|
|
308
309
|
## Links
|
|
309
310
|
|
|
@@ -315,4 +316,4 @@ Issues and pull requests welcome. If something doesn't work as documented, [open
|
|
|
315
316
|
|
|
316
317
|
---
|
|
317
318
|
|
|
318
|
-
Built by [@manufosela](https://github.com/manufosela)
|
|
319
|
+
Built by [@manufosela](https://github.com/manufosela). Head of Engineering at Geniova Technologies, co-organizer of NodeJS Madrid, author of [Liderazgo Afectivo](https://www.amazon.es/dp/B0D7F4C8KC). 90+ npm packages published.
|
package/docs/README.es.md
CHANGED
|
@@ -23,39 +23,40 @@
|
|
|
23
23
|
|
|
24
24
|
## Que es Karajan Code?
|
|
25
25
|
|
|
26
|
-
Karajan Code (`kj`) orquesta multiples agentes de IA a traves de un pipeline automatizado: generacion de codigo, analisis estatico, revision de codigo, testing y auditorias de seguridad
|
|
26
|
+
Karajan Code (`kj`) orquesta multiples agentes de IA a traves de un pipeline automatizado: generacion de codigo, analisis estatico, revision de codigo, testing y auditorias de seguridad. Todo en un solo comando.
|
|
27
27
|
|
|
28
28
|
En lugar de ejecutar un agente de IA y revisar manualmente su output, `kj` encadena agentes con quality gates. El coder escribe codigo, SonarQube lo analiza, el reviewer lo revisa, y si hay problemas, el coder recibe otra oportunidad. Este bucle se repite hasta que el codigo es aprobado o se alcanza el limite de iteraciones.
|
|
29
29
|
|
|
30
30
|
**Caracteristicas principales:**
|
|
31
31
|
- **Pipeline multi-agente** con 11 roles configurables
|
|
32
32
|
- **5 agentes de IA soportados**: Claude, Codex, Gemini, Aider, OpenCode
|
|
33
|
-
- **Servidor MCP** con 20 herramientas
|
|
34
|
-
- **Bootstrap obligatorio
|
|
35
|
-
- **
|
|
36
|
-
- **
|
|
37
|
-
- **
|
|
38
|
-
- **
|
|
39
|
-
- **
|
|
40
|
-
- **
|
|
41
|
-
- **
|
|
42
|
-
- **
|
|
43
|
-
- **
|
|
44
|
-
- **
|
|
45
|
-
- **
|
|
46
|
-
- **
|
|
47
|
-
- **
|
|
48
|
-
- **
|
|
49
|
-
- **
|
|
50
|
-
- **
|
|
51
|
-
- **
|
|
52
|
-
|
|
53
|
-
|
|
33
|
+
- **Servidor MCP** con 20 herramientas. Usa `kj` desde Claude, Codex o cualquier host compatible con MCP sin salir de tu agente. [Ver configuracion MCP](#servidor-mcp)
|
|
34
|
+
- **Bootstrap obligatorio.** Valida prerequisitos del entorno (git, remote, config, agentes, SonarQube) antes de cada ejecucion. Si algo falta, para con instrucciones claras
|
|
35
|
+
- **Guardia anti-inyeccion.** Escanea diffs antes de pasarlos a la IA: detecta directivas de override, Unicode invisible y payloads ocultos en comentarios. Tambien como GitHub Action en cada PR
|
|
36
|
+
- **TDD obligatorio.** Se exigen cambios en tests cuando se modifican ficheros fuente
|
|
37
|
+
- **Integracion con SonarQube.** Analisis estatico con quality gates (requiere [Docker](#requisitos))
|
|
38
|
+
- **Perfiles de revision.** standard, strict, relaxed, paranoid
|
|
39
|
+
- **Tracking de presupuesto.** Monitorizacion de tokens y costes por sesion con `--trace`
|
|
40
|
+
- **Automatizacion Git.** Auto-commit, auto-push, auto-PR tras aprobacion
|
|
41
|
+
- **Gestion de sesiones.** Pausa/reanudacion con deteccion fail-fast y limpieza automatica de sesiones expiradas
|
|
42
|
+
- **Sistema de plugins.** Extiende con agentes custom via `.karajan/plugins/`
|
|
43
|
+
- **Checkpoints interactivos.** En lugar de matar tareas largas, pausa cada 5 minutos con un informe de progreso y te deja decidir: continuar, parar o ajustar el tiempo
|
|
44
|
+
- **Descomposicion de tareas.** Triage detecta cuando una tarea debe dividirse y recomienda subtareas; con integracion Planning Game, crea cards vinculadas con bloqueo secuencial
|
|
45
|
+
- **Retry con backoff.** Recuperacion automatica ante errores transitorios de API (429, 5xx) con backoff exponencial y jitter
|
|
46
|
+
- **Pipeline stage tracker.** Vista de progreso acumulativo durante `kj_run` mostrando que stages estan completadas, en ejecucion o pendientes, tanto en CLI como via eventos MCP para renderizado en tiempo real en el host
|
|
47
|
+
- **Guardarrailes de observabilidad del planner.** Telemetria continua de heartbeat/stall, proteccion configurable por silencio maximo (`session.max_agent_silence_minutes`) y limite duro de ejecucion (`session.max_planner_minutes`) para evitar bloqueos prolongados en `kj_plan`/planner
|
|
48
|
+
- **Standby por rate-limit.** Cuando un agente alcanza limites de uso, Karajan parsea el tiempo de espera, espera con backoff exponencial y reanuda automaticamente en vez de fallar
|
|
49
|
+
- **Preflight handshake.** `kj_preflight` requiere confirmacion humana de la configuracion de agentes antes de ejecutar, previniendo que la IA cambie asignaciones silenciosamente
|
|
50
|
+
- **Config de 3 niveles.** Sesion > proyecto > global con scoping de `kj_agents`
|
|
51
|
+
- **Mediacion inteligente del reviewer.** El scope filter difiere automaticamente issues del reviewer fuera de scope (ficheros no presentes en el diff) como deuda tecnica rastreada en vez de bloquear; Solomon media reviews estancados; el contexto diferido se inyecta en el prompt del coder
|
|
52
|
+
- **Integracion con Planning Game.** Combina opcionalmente con [Planning Game](https://github.com/AgenteIA-Geniova/planning-game) para gestion agil de proyectos (tareas, sprints, estimacion). Como Jira, pero open-source y nativo XP
|
|
53
|
+
|
|
54
|
+
> **Mejor con MCP.** Karajan Code esta disenado para usarse como servidor MCP dentro de tu agente de IA (Claude, Codex, etc.). El agente envia tareas a `kj_run`, recibe notificaciones de progreso en tiempo real, y obtiene resultados estructurados. Sin copiar y pegar.
|
|
54
55
|
|
|
55
56
|
## Requisitos
|
|
56
57
|
|
|
57
58
|
- **Node.js** >= 18
|
|
58
|
-
- **Docker**
|
|
59
|
+
- **Docker** (necesario para SonarQube). Si no lo necesitas, desactivalo con `--no-sonar` o `sonarqube.enabled: false`
|
|
59
60
|
- Al menos un agente de IA instalado: Claude, Codex, Gemini o Aider
|
|
60
61
|
|
|
61
62
|
## Pipeline
|
|
@@ -66,7 +67,7 @@ triage? ─> researcher? ─> planner? ─> coder ─> refactorer? ─> sonar?
|
|
|
66
67
|
|
|
67
68
|
| Rol | Descripcion | Por defecto |
|
|
68
69
|
|-----|-------------|-------------|
|
|
69
|
-
| **triage** | Director de pipeline
|
|
70
|
+
| **triage** | Director de pipeline: analiza la complejidad y activa roles dinamicamente | **On** |
|
|
70
71
|
| **researcher** | Investiga el contexto del codebase antes de planificar | Off |
|
|
71
72
|
| **planner** | Genera planes de implementacion estructurados | Off |
|
|
72
73
|
| **coder** | Escribe codigo y tests siguiendo metodologia TDD | **Siempre activo** |
|
|
@@ -75,7 +76,7 @@ triage? ─> researcher? ─> planner? ─> coder ─> refactorer? ─> sonar?
|
|
|
75
76
|
| **reviewer** | Revision de codigo con perfiles de exigencia configurables | **Siempre activo** |
|
|
76
77
|
| **tester** | Quality gate de tests y verificacion de cobertura | **On** |
|
|
77
78
|
| **security** | Auditoria de seguridad OWASP | **On** |
|
|
78
|
-
| **solomon** | Supervisor de sesion
|
|
79
|
+
| **solomon** | Supervisor de sesion: monitoriza salud de iteraciones con 5 reglas (incl. reviewer overreach), media reviews estancados, escala ante anomalias | **On** |
|
|
79
80
|
| **commiter** | Automatizacion de git commit, push y PR tras aprobacion | Off |
|
|
80
81
|
|
|
81
82
|
Los roles marcados con `?` son opcionales y se pueden activar por ejecucion o via config.
|
|
@@ -133,7 +134,7 @@ Guias completas: [`docs/multi-instance.md`](multi-instance.md) | [`docs/install-
|
|
|
133
134
|
|
|
134
135
|
Karajan instala **tres comandos**: `kj`, `kj-tail` y `karajan-mcp`.
|
|
135
136
|
|
|
136
|
-
### 1. CLI
|
|
137
|
+
### 1. CLI: directamente desde terminal
|
|
137
138
|
|
|
138
139
|
```bash
|
|
139
140
|
kj run "Implementar autenticacion de usuario con JWT"
|
|
@@ -142,7 +143,7 @@ kj review "Revisar los cambios de autenticacion"
|
|
|
142
143
|
kj plan "Refactorizar la capa de base de datos"
|
|
143
144
|
```
|
|
144
145
|
|
|
145
|
-
### 2. MCP
|
|
146
|
+
### 2. MCP: dentro de tu agente de IA
|
|
146
147
|
|
|
147
148
|
El caso de uso principal. Karajan corre como servidor MCP dentro de Claude Code, Codex o Gemini. El agente tiene acceso a 20 herramientas (`kj_run`, `kj_code`, `kj_review`, etc.) y delega el trabajo pesado al pipeline de Karajan.
|
|
148
149
|
|
|
@@ -152,7 +153,7 @@ Tu → Claude Code → kj_run (via MCP) → triage → coder → sonar → revie
|
|
|
152
153
|
|
|
153
154
|
**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.
|
|
154
155
|
|
|
155
|
-
### 3. kj-tail
|
|
156
|
+
### 3. kj-tail: monitorizar desde otro terminal
|
|
156
157
|
|
|
157
158
|
**La herramienta companera.** Abre un segundo terminal en el **mismo directorio del proyecto** donde esta trabajando tu agente de IA:
|
|
158
159
|
|
|
@@ -160,7 +161,7 @@ Tu → Claude Code → kj_run (via MCP) → triage → coder → sonar → revie
|
|
|
160
161
|
kj-tail
|
|
161
162
|
```
|
|
162
163
|
|
|
163
|
-
Veras la salida del pipeline en vivo
|
|
164
|
+
Veras la salida del pipeline en vivo (etapas, resultados, iteraciones, errores) tal como ocurren.
|
|
164
165
|
|
|
165
166
|
```bash
|
|
166
167
|
kj-tail # Seguir pipeline en tiempo real (por defecto)
|
|
@@ -185,7 +186,7 @@ kj-tail --help # Todas las opciones
|
|
|
185
186
|
│ prioritaria │ │ ├─ 🔬 Researcher ✅ │
|
|
186
187
|
│ │ │ ├─ 🧠 Planner ✅ │
|
|
187
188
|
│ (Claude llama a kj_run │ │ ├─ 🔨 Coder ✅ │
|
|
188
|
-
│ via MCP
|
|
189
|
+
│ via MCP, solo ves │ │ ├─ 🔍 Sonar: OK │
|
|
189
190
|
│ el resultado final) │ │ ├─ 👁️ Reviewer ❌ │
|
|
190
191
|
│ │ │ ├─ ⚖️ Solomon: 2 cond. │
|
|
191
192
|
│ │ │ ├─ 🔨 Coder (iter 2) ✅ │
|
|
@@ -195,7 +196,7 @@ kj-tail --help # Todas las opciones
|
|
|
195
196
|
└──────────────────────────┘ └──────────────────────────┘
|
|
196
197
|
```
|
|
197
198
|
|
|
198
|
-
**Ejemplo con pipeline completo
|
|
199
|
+
**Ejemplo con pipeline completo**, tarea compleja con todos los roles:
|
|
199
200
|
|
|
200
201
|
```
|
|
201
202
|
┌─ Terminal 1 ─────────────────────────────────────────────────────────────────┐
|
|
@@ -221,7 +222,7 @@ kj-tail --help # Todas las opciones
|
|
|
221
222
|
|
|
222
223
|
┌─ Terminal 2: kj-tail ────────────────────────────────────────────────────────┐
|
|
223
224
|
│ │
|
|
224
|
-
│ kj-tail v1.
|
|
225
|
+
│ kj-tail v1.37.0 — .kj/run.log │
|
|
225
226
|
│ │
|
|
226
227
|
│ ├─ 📋 Triage: medium (sw) — activando researcher, architect, planner │
|
|
227
228
|
│ ├─ ⚙️ Preflight passed — all checks OK │
|
|
@@ -332,7 +333,7 @@ Cada rol tiene un template `.md` con instrucciones que el agente de IA sigue. Lo
|
|
|
332
333
|
|
|
333
334
|
Usa `kj roles show <rol>` para inspeccionar cualquier template. Crea un override de proyecto para personalizar el comportamiento por proyecto.
|
|
334
335
|
|
|
335
|
-
**Variantes de revision**: `reviewer-strict`, `reviewer-relaxed`, `reviewer-paranoid
|
|
336
|
+
**Variantes de revision**: `reviewer-strict`, `reviewer-relaxed`, `reviewer-paranoid`, seleccionables via flag `--mode` o config `review_mode`.
|
|
336
337
|
|
|
337
338
|
## Contribuir
|
|
338
339
|
|
|
@@ -340,7 +341,7 @@ Usa `kj roles show <rol>` para inspeccionar cualquier template. Crea un override
|
|
|
340
341
|
git clone https://github.com/manufosela/karajan-code.git
|
|
341
342
|
cd karajan-code
|
|
342
343
|
npm install
|
|
343
|
-
npm test # Ejecutar
|
|
344
|
+
npm test # Ejecutar 2044 tests con Vitest
|
|
344
345
|
npm run test:watch # Modo watch
|
|
345
346
|
npm run validate # Lint + test
|
|
346
347
|
```
|
package/package.json
CHANGED
|
@@ -21,7 +21,7 @@ export async function runCoderStage({ coderRoleInstance, coderRole, config, logg
|
|
|
21
21
|
emitter,
|
|
22
22
|
makeEvent("coder:start", { ...eventBase, stage: "coder" }, {
|
|
23
23
|
message: `Coder (${coderRole.provider}) running`,
|
|
24
|
-
detail: { coder: coderRole.provider }
|
|
24
|
+
detail: { coder: coderRole.provider, provider: coderRole.provider, executorType: "agent" }
|
|
25
25
|
})
|
|
26
26
|
);
|
|
27
27
|
|
|
@@ -89,7 +89,8 @@ export async function runCoderStage({ coderRoleInstance, coderRole, config, logg
|
|
|
89
89
|
emitProgress(
|
|
90
90
|
emitter,
|
|
91
91
|
makeEvent("coder:end", { ...eventBase, stage: "coder" }, {
|
|
92
|
-
message: `Coder completed (fallback: ${fallbackCoder})
|
|
92
|
+
message: `Coder completed (fallback: ${fallbackCoder})`,
|
|
93
|
+
detail: { provider: fallbackCoder, executorType: "agent" }
|
|
93
94
|
})
|
|
94
95
|
);
|
|
95
96
|
return;
|
|
@@ -114,7 +115,8 @@ export async function runCoderStage({ coderRoleInstance, coderRole, config, logg
|
|
|
114
115
|
emitter,
|
|
115
116
|
makeEvent("coder:end", { ...eventBase, stage: "coder" }, {
|
|
116
117
|
status: "fail",
|
|
117
|
-
message: `Coder failed: ${details}
|
|
118
|
+
message: `Coder failed: ${details}`,
|
|
119
|
+
detail: { provider: coderRole.provider, executorType: "agent" }
|
|
118
120
|
})
|
|
119
121
|
);
|
|
120
122
|
throw new Error(`Coder failed: ${details}`);
|
|
@@ -124,7 +126,8 @@ export async function runCoderStage({ coderRoleInstance, coderRole, config, logg
|
|
|
124
126
|
emitProgress(
|
|
125
127
|
emitter,
|
|
126
128
|
makeEvent("coder:end", { ...eventBase, stage: "coder" }, {
|
|
127
|
-
message: "Coder completed"
|
|
129
|
+
message: "Coder completed",
|
|
130
|
+
detail: { provider: coderRole.provider, executorType: "agent" }
|
|
128
131
|
})
|
|
129
132
|
);
|
|
130
133
|
}
|
|
@@ -135,7 +138,7 @@ export async function runRefactorerStage({ refactorerRole, config, logger, emitt
|
|
|
135
138
|
emitter,
|
|
136
139
|
makeEvent("refactorer:start", { ...eventBase, stage: "refactorer" }, {
|
|
137
140
|
message: `Refactorer (${refactorerRole.provider}) running`,
|
|
138
|
-
detail: { refactorer: refactorerRole.provider }
|
|
141
|
+
detail: { refactorer: refactorerRole.provider, provider: refactorerRole.provider, executorType: "agent" }
|
|
139
142
|
})
|
|
140
143
|
);
|
|
141
144
|
const refactorerOnOutput = ({ stream, line }) => {
|
|
@@ -184,7 +187,8 @@ export async function runRefactorerStage({ refactorerRole, config, logger, emitt
|
|
|
184
187
|
emitter,
|
|
185
188
|
makeEvent("refactorer:end", { ...eventBase, stage: "refactorer" }, {
|
|
186
189
|
status: "fail",
|
|
187
|
-
message: `Refactorer failed: ${details}
|
|
190
|
+
message: `Refactorer failed: ${details}`,
|
|
191
|
+
detail: { provider: refactorerRole.provider, executorType: "agent" }
|
|
188
192
|
})
|
|
189
193
|
);
|
|
190
194
|
throw new Error(`Refactorer failed: ${details}`);
|
|
@@ -193,7 +197,8 @@ export async function runRefactorerStage({ refactorerRole, config, logger, emitt
|
|
|
193
197
|
emitProgress(
|
|
194
198
|
emitter,
|
|
195
199
|
makeEvent("refactorer:end", { ...eventBase, stage: "refactorer" }, {
|
|
196
|
-
message: "Refactorer completed"
|
|
200
|
+
message: "Refactorer completed",
|
|
201
|
+
detail: { provider: refactorerRole.provider, executorType: "agent" }
|
|
197
202
|
})
|
|
198
203
|
);
|
|
199
204
|
}
|
|
@@ -287,7 +292,8 @@ export async function runTddCheckStage({ config, logger, emitter, eventBase, ses
|
|
|
287
292
|
ok: tddEval.ok,
|
|
288
293
|
reason: tddEval.reason,
|
|
289
294
|
sourceFiles: tddEval.sourceFiles?.length || 0,
|
|
290
|
-
testFiles: tddEval.testFiles?.length || 0
|
|
295
|
+
testFiles: tddEval.testFiles?.length || 0,
|
|
296
|
+
executorType: "local"
|
|
291
297
|
}
|
|
292
298
|
})
|
|
293
299
|
);
|
|
@@ -386,7 +392,8 @@ export async function runSonarStage({ config, logger, emitter, eventBase, sessio
|
|
|
386
392
|
emitProgress(
|
|
387
393
|
emitter,
|
|
388
394
|
makeEvent("sonar:start", { ...eventBase, stage: "sonar" }, {
|
|
389
|
-
message: "SonarQube scanning"
|
|
395
|
+
message: "SonarQube scanning",
|
|
396
|
+
detail: { provider: "sonarqube", executorType: "local" }
|
|
390
397
|
})
|
|
391
398
|
);
|
|
392
399
|
|
|
@@ -470,7 +477,7 @@ export async function runSonarStage({ config, logger, emitter, eventBase, sessio
|
|
|
470
477
|
makeEvent("sonar:end", { ...eventBase, stage: "sonar" }, {
|
|
471
478
|
status: sonarResult.blocking ? "fail" : "ok",
|
|
472
479
|
message: `Quality gate: ${sonarResult.gateStatus}`,
|
|
473
|
-
detail: { projectKey: sonarResult.projectKey, gateStatus: sonarResult.gateStatus, openIssues: sonarResult.openIssuesTotal }
|
|
480
|
+
detail: { projectKey: sonarResult.projectKey, gateStatus: sonarResult.gateStatus, openIssues: sonarResult.openIssuesTotal, provider: "sonarqube", executorType: "local" }
|
|
474
481
|
})
|
|
475
482
|
);
|
|
476
483
|
|
|
@@ -498,7 +505,8 @@ export async function runSonarCloudStage({ config, logger, emitter, eventBase, s
|
|
|
498
505
|
emitProgress(
|
|
499
506
|
emitter,
|
|
500
507
|
makeEvent("sonarcloud:start", { ...eventBase, stage: "sonarcloud" }, {
|
|
501
|
-
message: "SonarCloud scanning"
|
|
508
|
+
message: "SonarCloud scanning",
|
|
509
|
+
detail: { provider: "sonarcloud", executorType: "local" }
|
|
502
510
|
})
|
|
503
511
|
);
|
|
504
512
|
|
|
@@ -532,7 +540,7 @@ export async function runSonarCloudStage({ config, logger, emitter, eventBase, s
|
|
|
532
540
|
makeEvent("sonarcloud:end", { ...eventBase, stage: "sonarcloud" }, {
|
|
533
541
|
status,
|
|
534
542
|
message,
|
|
535
|
-
detail: { projectKey: result.projectKey, exitCode: result.exitCode }
|
|
543
|
+
detail: { projectKey: result.projectKey, exitCode: result.exitCode, provider: "sonarcloud", executorType: "local" }
|
|
536
544
|
})
|
|
537
545
|
);
|
|
538
546
|
|
|
@@ -681,7 +689,7 @@ export async function runReviewerStage({ reviewerRole, config, logger, emitter,
|
|
|
681
689
|
emitter,
|
|
682
690
|
makeEvent("reviewer:start", { ...eventBase, stage: "reviewer" }, {
|
|
683
691
|
message: `Reviewer (${reviewerRole.provider}) running`,
|
|
684
|
-
detail: { reviewer: reviewerRole.provider }
|
|
692
|
+
detail: { reviewer: reviewerRole.provider, provider: reviewerRole.provider, executorType: "agent" }
|
|
685
693
|
})
|
|
686
694
|
);
|
|
687
695
|
|
|
@@ -692,6 +700,30 @@ export async function runReviewerStage({ reviewerRole, config, logger, emitter,
|
|
|
692
700
|
logger.warn(`Review diff generation failed: ${err.message}`);
|
|
693
701
|
return { approved: false, blocking_issues: [{ description: `Diff generation failed: ${err.message}` }], non_blocking_suggestions: [], summary: `Reviewer failed: cannot generate diff — ${err.message}`, confidence: 0 };
|
|
694
702
|
}
|
|
703
|
+
|
|
704
|
+
// Injection guard: scan diff before sending to AI reviewer
|
|
705
|
+
const { scanDiff } = await import("../utils/injection-guard.js");
|
|
706
|
+
const guardResult = scanDiff(diff);
|
|
707
|
+
if (!guardResult.clean) {
|
|
708
|
+
logger.warn(`Injection guard: ${guardResult.summary}`);
|
|
709
|
+
emitProgress(emitter, makeEvent("guard:injection", { ...eventBase, stage: "reviewer" }, {
|
|
710
|
+
message: `Injection guard blocked review: ${guardResult.summary}`,
|
|
711
|
+
detail: { findings: guardResult.findings, summary: guardResult.summary }
|
|
712
|
+
}));
|
|
713
|
+
return {
|
|
714
|
+
approved: false,
|
|
715
|
+
blocking_issues: guardResult.findings.map((f) => ({
|
|
716
|
+
id: `INJECTION_${f.type.toUpperCase()}`,
|
|
717
|
+
severity: "critical",
|
|
718
|
+
description: `Potential prompt injection (${f.type}): ${f.snippet}`,
|
|
719
|
+
line: f.line,
|
|
720
|
+
})),
|
|
721
|
+
non_blocking_suggestions: [],
|
|
722
|
+
summary: `Review blocked by injection guard: ${guardResult.summary}`,
|
|
723
|
+
confidence: 1,
|
|
724
|
+
};
|
|
725
|
+
}
|
|
726
|
+
|
|
695
727
|
const reviewerOnOutput = ({ stream, line }) => {
|
|
696
728
|
emitProgress(emitter, makeEvent("agent:output", { ...eventBase, stage: "reviewer" }, {
|
|
697
729
|
message: line,
|
|
@@ -754,7 +786,8 @@ export async function runReviewerStage({ reviewerRole, config, logger, emitter,
|
|
|
754
786
|
emitter,
|
|
755
787
|
makeEvent("reviewer:end", { ...eventBase, stage: "reviewer" }, {
|
|
756
788
|
status: "fail",
|
|
757
|
-
message: `Reviewer failed: ${details}
|
|
789
|
+
message: `Reviewer failed: ${details}`,
|
|
790
|
+
detail: { provider: reviewerRole.provider, executorType: "agent" }
|
|
758
791
|
})
|
|
759
792
|
);
|
|
760
793
|
throw new Error(`Reviewer failed: ${details}`);
|
|
@@ -836,7 +869,9 @@ export async function runReviewerStage({ reviewerRole, config, logger, emitter,
|
|
|
836
869
|
blockingCount: review.blocking_issues.length,
|
|
837
870
|
issues: review.blocking_issues.map(
|
|
838
871
|
(x) => `${x.id || "ISSUE"}: ${x.description || "Missing description"}`
|
|
839
|
-
)
|
|
872
|
+
),
|
|
873
|
+
provider: reviewerRole.provider,
|
|
874
|
+
executorType: "agent"
|
|
840
875
|
}
|
|
841
876
|
})
|
|
842
877
|
);
|