karajan-code 1.36.0 → 1.36.1
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 +133 -17
- package/bin/kj-tail +294 -41
- package/docs/README.es.md +122 -20
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -58,31 +58,143 @@ npm install -g karajan-code
|
|
|
58
58
|
|
|
59
59
|
That's it. No Docker required (SonarQube uses Docker, but Karajan auto-manages it). No config files to copy. `kj init` auto-detects your installed agents.
|
|
60
60
|
|
|
61
|
-
##
|
|
61
|
+
## Three ways to use Karajan
|
|
62
62
|
|
|
63
|
-
|
|
64
|
-
# Run a task — Karajan handles the rest
|
|
65
|
-
kj run "Create a utility function that validates Spanish DNI numbers, with tests"
|
|
66
|
-
```
|
|
63
|
+
Karajan installs **three commands**: `kj`, `kj-tail`, and `karajan-mcp`.
|
|
67
64
|
|
|
68
|
-
|
|
65
|
+
### 1. CLI — Direct from terminal
|
|
69
66
|
|
|
70
|
-
Karajan
|
|
71
|
-
1. Triage the task complexity and activate the right roles
|
|
72
|
-
2. Write tests first (TDD)
|
|
73
|
-
3. Implement code to pass those tests
|
|
74
|
-
4. Run SonarQube analysis (auto-starts Docker if needed)
|
|
75
|
-
5. Review the code (Solomon evaluates every rejection)
|
|
76
|
-
6. Iterate until approved or escalate to you
|
|
67
|
+
Run Karajan directly. You see the full pipeline output in real time.
|
|
77
68
|
|
|
78
69
|
```bash
|
|
79
|
-
|
|
70
|
+
kj run "Create a utility function that validates Spanish DNI numbers, with tests"
|
|
80
71
|
kj code "Add input validation to the signup form" # Coder only
|
|
81
72
|
kj review "Check the authentication changes" # Review current diff
|
|
82
73
|
kj audit "Full health analysis of this codebase" # Read-only audit
|
|
83
74
|
kj plan "Refactor the database layer" # Plan without coding
|
|
84
75
|
```
|
|
85
76
|
|
|
77
|
+
### 2. MCP — Inside your AI agent
|
|
78
|
+
|
|
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
|
+
|
|
81
|
+
```
|
|
82
|
+
You → Claude Code → kj_run (via MCP) → triage → coder → sonar → reviewer → tester → security
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
The MCP server auto-registers during `npm install`. Your AI agent sees 20 tools (`kj_run`, `kj_code`, `kj_review`, etc.) and uses them as needed.
|
|
86
|
+
|
|
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
|
+
|
|
89
|
+
### 3. kj-tail — Monitor from a separate terminal
|
|
90
|
+
|
|
91
|
+
**This is the companion tool.** Open a second terminal in the **same project directory** where your AI agent is working, and run:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
kj-tail
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
You'll see the live pipeline output — stages, results, iterations, errors — as they happen. Same view as running `kj run` directly.
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
kj-tail # Follow pipeline in real time (default)
|
|
101
|
+
kj-tail -v # Verbose: include agent heartbeats and budget
|
|
102
|
+
kj-tail -t # Show timestamps
|
|
103
|
+
kj-tail -s # Snapshot: show current log and exit
|
|
104
|
+
kj-tail -n 50 # Show last 50 lines then follow
|
|
105
|
+
kj-tail --help # Full options
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
> **Important**: `kj-tail` must run from the same directory where the AI agent is executing. It reads `<project>/.kj/run.log`, which is created when Karajan starts a pipeline via MCP.
|
|
109
|
+
|
|
110
|
+
**Typical workflow:**
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
┌─────────────────────────┐ ┌─────────────────────────┐
|
|
114
|
+
│ Terminal 1 │ │ Terminal 2 │
|
|
115
|
+
│ │ │ │
|
|
116
|
+
│ $ claude │ │ $ kj-tail │
|
|
117
|
+
│ > implement the next │ │ │
|
|
118
|
+
│ priority task │ │ ├─ 📋 Triage: medium │
|
|
119
|
+
│ │ │ ├─ 🔬 Researcher ✅ │
|
|
120
|
+
│ (Claude calls kj_run │ │ ├─ 🧠 Planner ✅ │
|
|
121
|
+
│ via MCP — you see │ │ ├─ 🔨 Coder ✅ │
|
|
122
|
+
│ only the final result) │ │ ├─ 🔍 Sonar: OK │
|
|
123
|
+
│ │ │ ├─ 👁️ Reviewer ❌ │
|
|
124
|
+
│ │ │ ├─ ⚖️ Solomon: 2 cond. │
|
|
125
|
+
│ │ │ ├─ 🔨 Coder (iter 2) ✅ │
|
|
126
|
+
│ │ │ ├─ ✅ Review: APPROVED │
|
|
127
|
+
│ │ │ ├─ 🧪 Tester: passed │
|
|
128
|
+
│ │ │ └─ 🏁 Result: APPROVED │
|
|
129
|
+
└─────────────────────────┘ └─────────────────────────┘
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
**Full pipeline example** — a complex task with all roles:
|
|
133
|
+
|
|
134
|
+
```
|
|
135
|
+
┌─ Terminal 1 ─────────────────────────────────────────────────────────────────┐
|
|
136
|
+
│ │
|
|
137
|
+
│ $ claude │
|
|
138
|
+
│ │
|
|
139
|
+
│ > Build a REST API for a booking system. Requirements: │
|
|
140
|
+
│ > - Express + TypeScript with Zod validation on every endpoint │
|
|
141
|
+
│ > - Endpoints: POST /bookings, GET /bookings/:id, PATCH /bookings/:id/cancel│
|
|
142
|
+
│ > - A booking has: id, guestName, roomType (standard|suite|penthouse), │
|
|
143
|
+
│ > checkIn, checkOut, status (confirmed|cancelled) │
|
|
144
|
+
│ > - Validate: checkOut must be after checkIn, no past dates, │
|
|
145
|
+
│ > roomType must be a valid enum value │
|
|
146
|
+
│ > - Cancel returns 409 if already cancelled │
|
|
147
|
+
│ > - Use TDD. Run it through Karajan with architect and planner enabled, │
|
|
148
|
+
│ > paranoid review mode. Coder claude, reviewer codex. │
|
|
149
|
+
│ │
|
|
150
|
+
│ Claude calls kj_run via MCP with: │
|
|
151
|
+
│ --enable-architect --enable-researcher --enable-planner --mode paranoid │
|
|
152
|
+
│ │
|
|
153
|
+
└──────────────────────────────────────────────────────────────────────────────┘
|
|
154
|
+
|
|
155
|
+
┌─ Terminal 2: kj-tail ────────────────────────────────────────────────────────┐
|
|
156
|
+
│ │
|
|
157
|
+
│ kj-tail v1.36.1 — .kj/run.log │
|
|
158
|
+
│ │
|
|
159
|
+
│ ├─ 📋 Triage: medium (sw) — enabling researcher, architect, planner │
|
|
160
|
+
│ ├─ ⚙️ Preflight passed — all checks OK │
|
|
161
|
+
│ ├─ 🔬 Researcher: 8 files analyzed, 3 patterns, 5 constraints │
|
|
162
|
+
│ ├─ 🏗️ Architect: 3-layer design (routes → service → validators) │
|
|
163
|
+
│ ├─ 🧠 Planner: 6 steps — tests first, then routes, service, validators │
|
|
164
|
+
│ │ │
|
|
165
|
+
│ ▶ Iteration 1/5 │
|
|
166
|
+
│ ├─ 🔨 Coder (claude): implemented 3 endpoints + 18 tests │
|
|
167
|
+
│ ├─ 📋 TDD: PASS (3 src, 2 test files) │
|
|
168
|
+
│ ├─ 🔍 Sonar: Quality gate OK — 0 blockers │
|
|
169
|
+
│ ├─ 👁️ Reviewer (codex): REJECTED (2 blocking) │
|
|
170
|
+
│ │ "Missing 404 for GET nonexistent booking" │
|
|
171
|
+
│ │ "Cancel endpoint lacks idempotency test" │
|
|
172
|
+
│ ├─ ⚖️ Solomon: approve_with_conditions (2 conditions) │
|
|
173
|
+
│ │ "Add 404 response and test for GET /bookings/:id with unknown id" │
|
|
174
|
+
│ │ "Add test: cancel already-cancelled booking returns 409, not 500" │
|
|
175
|
+
│ │ │
|
|
176
|
+
│ ▶ Iteration 2/5 │
|
|
177
|
+
│ ├─ 🔨 Coder (claude): fixed — 22 tests now │
|
|
178
|
+
│ ├─ 📋 TDD: PASS │
|
|
179
|
+
│ ├─ 🔍 Sonar: OK │
|
|
180
|
+
│ ├─ 👁️ Reviewer (codex): APPROVED │
|
|
181
|
+
│ ├─ 🧪 Tester: passed — coverage 94%, 22 tests │
|
|
182
|
+
│ ├─ 🔒 Security: passed — 0 critical, 1 low (helmet recommended) │
|
|
183
|
+
│ ├─ 📊 Audit: CERTIFIED (with 3 advisory warnings) │
|
|
184
|
+
│ │ │
|
|
185
|
+
│ 🏁 Result: APPROVED │
|
|
186
|
+
│ 🔬 Research: 8 files, 3 patterns identified │
|
|
187
|
+
│ 🗺 Plan: 6 steps (tests first) │
|
|
188
|
+
│ 🧪 Coverage: 94%, 22 tests │
|
|
189
|
+
│ 🔒 Security: passed │
|
|
190
|
+
│ 🔍 Sonar: OK │
|
|
191
|
+
│ 💰 Budget: $0.42 (claude: $0.38, codex: $0.04) │
|
|
192
|
+
│ │
|
|
193
|
+
└──────────────────────────────────────────────────────────────────────────────┘
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
[**▶ Watch the full pipeline demo**](https://karajancode.com#demo) — triage, architecture, TDD, SonarQube, code review, Solomon arbitration, security audit.
|
|
197
|
+
|
|
86
198
|
## The pipeline
|
|
87
199
|
|
|
88
200
|
```
|
|
@@ -123,16 +235,20 @@ Mix and match. Use Claude as coder and Codex as reviewer. Karajan auto-detects i
|
|
|
123
235
|
|
|
124
236
|
## MCP server — 20 tools
|
|
125
237
|
|
|
126
|
-
|
|
238
|
+
After `npm install -g karajan-code`, the MCP server auto-registers in Claude and Codex. Manual config if needed:
|
|
127
239
|
|
|
128
240
|
```bash
|
|
129
|
-
#
|
|
130
|
-
# Add to ~/.claude.json → "mcpServers":
|
|
241
|
+
# Claude: add to ~/.claude.json → "mcpServers":
|
|
131
242
|
# { "karajan-mcp": { "command": "karajan-mcp" } }
|
|
243
|
+
|
|
244
|
+
# Codex: add to ~/.codex/config.toml → [mcp_servers."karajan-mcp"]
|
|
245
|
+
# command = "karajan-mcp"
|
|
132
246
|
```
|
|
133
247
|
|
|
134
248
|
**20 tools** available: `kj_run`, `kj_code`, `kj_review`, `kj_plan`, `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_impeccable`.
|
|
135
249
|
|
|
250
|
+
Use `kj-tail` in a separate terminal to see what the pipeline is doing in real time (see [Three ways to use Karajan](#three-ways-to-use-karajan)).
|
|
251
|
+
|
|
136
252
|
## The role architecture
|
|
137
253
|
|
|
138
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.
|
package/bin/kj-tail
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# kj-tail —
|
|
3
|
-
#
|
|
2
|
+
# kj-tail — Real-time pipeline monitor for Karajan Code
|
|
3
|
+
# Follows the run log and displays colorized, filtered output.
|
|
4
4
|
|
|
5
5
|
set -euo pipefail
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
VERSION="1.36.0"
|
|
8
|
+
|
|
9
|
+
# ── Colors ──────────────────────────────────────────────
|
|
8
10
|
RED='\033[0;31m'
|
|
9
11
|
GREEN='\033[0;32m'
|
|
10
12
|
YELLOW='\033[0;33m'
|
|
@@ -13,58 +15,309 @@ CYAN='\033[0;36m'
|
|
|
13
15
|
MAGENTA='\033[0;35m'
|
|
14
16
|
GRAY='\033[0;90m'
|
|
15
17
|
BOLD='\033[1m'
|
|
18
|
+
DIM='\033[2m'
|
|
16
19
|
RESET='\033[0m'
|
|
17
20
|
|
|
21
|
+
# ── Defaults ────────────────────────────────────────────
|
|
18
22
|
VERBOSE=false
|
|
23
|
+
SHOW_AGENT_OUTPUT=false
|
|
24
|
+
SHOW_TIMESTAMPS=false
|
|
25
|
+
FOLLOW=true
|
|
26
|
+
NUM_LINES=0
|
|
19
27
|
PROJECT_DIR=""
|
|
20
28
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
29
|
+
# ── Help ────────────────────────────────────────────────
|
|
30
|
+
show_help() {
|
|
31
|
+
cat <<EOF
|
|
32
|
+
${BOLD}kj-tail${RESET} — Real-time pipeline monitor for Karajan Code
|
|
33
|
+
|
|
34
|
+
${BOLD}USAGE${RESET}
|
|
35
|
+
kj-tail [options] [project-dir]
|
|
36
|
+
|
|
37
|
+
${BOLD}DESCRIPTION${RESET}
|
|
38
|
+
Follows the Karajan run log (<project>/.kj/run.log) and displays
|
|
39
|
+
colorized, filtered output. By default shows the same pipeline
|
|
40
|
+
progress view as 'kj run': stages, results, iterations, and errors.
|
|
41
|
+
|
|
42
|
+
Run this in a separate terminal while kj executes via MCP/CLI.
|
|
43
|
+
|
|
44
|
+
${BOLD}OPTIONS${RESET}
|
|
45
|
+
-v, --verbose Show agent heartbeats, budget, and metadata
|
|
46
|
+
-a, --agent-output Show raw agent output lines (very noisy)
|
|
47
|
+
-t, --timestamps Show timestamps on each line
|
|
48
|
+
-n, --lines <N> Show last N lines then follow (default: follow only new)
|
|
49
|
+
-s, --snapshot Show current log (no follow) — like 'cat' with colors
|
|
50
|
+
-h, --help Show this help
|
|
51
|
+
--version Show version
|
|
52
|
+
|
|
53
|
+
${BOLD}EXAMPLES${RESET}
|
|
54
|
+
kj-tail # Follow current directory's run log
|
|
55
|
+
kj-tail /path/to/project # Follow a specific project's log
|
|
56
|
+
kj-tail -v # Verbose: include heartbeats and budget
|
|
57
|
+
kj-tail -a # Show everything including agent output
|
|
58
|
+
kj-tail -n 50 # Show last 50 lines then follow
|
|
59
|
+
kj-tail -s # Snapshot: show full log and exit
|
|
60
|
+
kj-tail -t # Show timestamps
|
|
61
|
+
|
|
62
|
+
${BOLD}LOG LOCATION${RESET}
|
|
63
|
+
<project-dir>/.kj/run.log
|
|
64
|
+
Created automatically when kj_run, kj_code, or kj_review starts.
|
|
65
|
+
|
|
66
|
+
EOF
|
|
67
|
+
exit 0
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
# ── Parse args ──────────────────────────────────────────
|
|
71
|
+
while [[ $# -gt 0 ]]; do
|
|
72
|
+
case "$1" in
|
|
73
|
+
-h|--help) show_help ;;
|
|
74
|
+
--version) echo "kj-tail $VERSION"; exit 0 ;;
|
|
75
|
+
-v|--verbose) VERBOSE=true; shift ;;
|
|
76
|
+
-a|--agent-output) SHOW_AGENT_OUTPUT=true; VERBOSE=true; shift ;;
|
|
77
|
+
-t|--timestamps) SHOW_TIMESTAMPS=true; shift ;;
|
|
78
|
+
-s|--snapshot) FOLLOW=false; shift ;;
|
|
79
|
+
-n|--lines)
|
|
80
|
+
shift
|
|
81
|
+
NUM_LINES="${1:-50}"
|
|
82
|
+
shift
|
|
83
|
+
;;
|
|
84
|
+
-*)
|
|
85
|
+
echo -e "${RED}Unknown option: $1${RESET}" >&2
|
|
86
|
+
echo "Run 'kj-tail --help' for usage." >&2
|
|
87
|
+
exit 1
|
|
88
|
+
;;
|
|
89
|
+
*) PROJECT_DIR="$1"; shift ;;
|
|
25
90
|
esac
|
|
26
91
|
done
|
|
27
92
|
|
|
28
93
|
PROJECT_DIR="${PROJECT_DIR:-$(pwd)}"
|
|
29
94
|
LOG_FILE="${PROJECT_DIR}/.kj/run.log"
|
|
30
95
|
|
|
96
|
+
# ── Locate log ──────────────────────────────────────────
|
|
31
97
|
if [[ ! -f "$LOG_FILE" ]]; then
|
|
32
|
-
echo -e "${RED}No run
|
|
33
|
-
echo "
|
|
98
|
+
echo -e "${RED}No run log found at ${LOG_FILE}${RESET}"
|
|
99
|
+
echo ""
|
|
100
|
+
echo "The run log is created when Karajan starts a pipeline."
|
|
101
|
+
echo "Make sure you're in the project directory, or pass it as argument:"
|
|
102
|
+
echo ""
|
|
103
|
+
echo " kj-tail /path/to/project"
|
|
104
|
+
echo ""
|
|
34
105
|
exit 1
|
|
35
106
|
fi
|
|
36
107
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
108
|
+
# ── Filter & colorize ──────────────────────────────────
|
|
109
|
+
filter_line() {
|
|
110
|
+
local line="$1"
|
|
111
|
+
local ts=""
|
|
112
|
+
local clean="$line"
|
|
40
113
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
# Strip [agent:output] tag — it's the default, no need to show it
|
|
46
|
-
clean="${clean/\[agent:output\] /}"
|
|
47
|
-
|
|
48
|
-
# Colorize by content
|
|
49
|
-
if [[ "$clean" == *"[coder:start]"* ]] || [[ "$clean" == *"[coder:done]"* ]] || [[ "$clean" == *"[coder]"* ]]; then
|
|
50
|
-
echo -e "${GREEN}${clean}${RESET}"
|
|
51
|
-
elif [[ "$clean" == *"[reviewer"* ]]; then
|
|
52
|
-
echo -e "${YELLOW}${clean}${RESET}"
|
|
53
|
-
elif [[ "$clean" == *"[sonar"* ]]; then
|
|
54
|
-
echo -e "${BLUE}${clean}${RESET}"
|
|
55
|
-
elif [[ "$clean" == *"[solomon"* ]]; then
|
|
56
|
-
echo -e "${MAGENTA}${clean}${RESET}"
|
|
57
|
-
elif [[ "$clean" == *"[iteration"* ]] || [[ "$clean" == *"[session"* ]] || [[ "$clean" == *"[kj_run]"* ]] || [[ "$clean" == *"[kj_code]"* ]]; then
|
|
58
|
-
echo -e "${BOLD}${CYAN}${clean}${RESET}"
|
|
59
|
-
elif [[ "$clean" == *"fail"* ]] || [[ "$clean" == *"error"* ]] || [[ "$clean" == *"FAIL"* ]] || [[ "$clean" == *"ERROR"* ]]; then
|
|
60
|
-
echo -e "${RED}${clean}${RESET}"
|
|
61
|
-
elif [[ "$clean" == *"[agent:heartbeat]"* ]]; then
|
|
62
|
-
echo -e "${GRAY}${clean}${RESET}"
|
|
63
|
-
elif [[ "$clean" == *"[standby]"* ]] || [[ "$clean" == *"standby"* ]]; then
|
|
64
|
-
echo -e "${YELLOW}${clean}${RESET}"
|
|
65
|
-
elif [[ "$clean" == "---"* ]]; then
|
|
66
|
-
echo -e "${BOLD}${clean}${RESET}"
|
|
67
|
-
else
|
|
68
|
-
echo "$clean"
|
|
114
|
+
# Extract and optionally strip timestamp (HH:MM:SS.mmm)
|
|
115
|
+
if [[ "$clean" =~ ^([0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3})\ (.*) ]]; then
|
|
116
|
+
ts="${BASH_REMATCH[1]}"
|
|
117
|
+
clean="${BASH_REMATCH[2]}"
|
|
69
118
|
fi
|
|
70
|
-
|
|
119
|
+
|
|
120
|
+
# Skip noise in default mode
|
|
121
|
+
if [[ "$VERBOSE" == "false" ]]; then
|
|
122
|
+
# Skip agent heartbeats
|
|
123
|
+
[[ "$clean" == *"[agent:heartbeat]"* ]] && return
|
|
124
|
+
[[ "$clean" == *"heartbeat"* ]] && return
|
|
125
|
+
# Skip budget lines
|
|
126
|
+
[[ "$clean" == *"Budget:"* ]] && return
|
|
127
|
+
# Skip agent raw output
|
|
128
|
+
[[ "$clean" == *"[agent:output]"* ]] && return
|
|
129
|
+
# Skip internal metadata
|
|
130
|
+
[[ "$clean" == *"[agent:start]"* ]] && return
|
|
131
|
+
[[ "$clean" == *"[agent:end]"* ]] && return
|
|
132
|
+
# Skip noisy JSON dumps (system init, tool lists, etc.)
|
|
133
|
+
[[ "${#clean}" -gt 500 ]] && return
|
|
134
|
+
fi
|
|
135
|
+
|
|
136
|
+
if [[ "$SHOW_AGENT_OUTPUT" == "false" ]]; then
|
|
137
|
+
# Skip raw agent output (often JSON/stream data)
|
|
138
|
+
[[ "$clean" == "{"* ]] && [[ "$clean" == *"}" ]] && return
|
|
139
|
+
[[ "$clean" == *'"type":'* ]] && [[ "${#clean}" -gt 200 ]] && return
|
|
140
|
+
fi
|
|
141
|
+
|
|
142
|
+
# Build prefix
|
|
143
|
+
local prefix=""
|
|
144
|
+
if [[ "$SHOW_TIMESTAMPS" == "true" ]] && [[ -n "$ts" ]]; then
|
|
145
|
+
prefix="${DIM}${ts}${RESET} "
|
|
146
|
+
fi
|
|
147
|
+
|
|
148
|
+
# ── Colorize by content ──────────────────────────────
|
|
149
|
+
# Session markers
|
|
150
|
+
if [[ "$clean" == "---"* ]]; then
|
|
151
|
+
echo -e "${prefix}${BOLD}${CYAN}${clean}${RESET}"
|
|
152
|
+
return
|
|
153
|
+
fi
|
|
154
|
+
|
|
155
|
+
# Stage: started/finished
|
|
156
|
+
if [[ "$clean" == *"started"* ]] && [[ "$clean" == *"[kj_"* ]]; then
|
|
157
|
+
echo -e "${prefix}${BOLD}${CYAN}▶ ${clean}${RESET}"
|
|
158
|
+
return
|
|
159
|
+
fi
|
|
160
|
+
if [[ "$clean" == *"finished"* ]] && [[ "$clean" == *"[kj_"* ]]; then
|
|
161
|
+
echo -e "${prefix}${BOLD}${GREEN}✓ ${clean}${RESET}"
|
|
162
|
+
return
|
|
163
|
+
fi
|
|
164
|
+
|
|
165
|
+
# Iterations
|
|
166
|
+
if [[ "$clean" == *"[iteration]"* ]] || [[ "$clean" == *"Iteration "* ]]; then
|
|
167
|
+
echo -e "${prefix}${BOLD}${clean}${RESET}"
|
|
168
|
+
return
|
|
169
|
+
fi
|
|
170
|
+
|
|
171
|
+
# Coder
|
|
172
|
+
if [[ "$clean" == *"[coder"* ]] || [[ "$clean" == *"Coder"* ]]; then
|
|
173
|
+
echo -e "${prefix}${GREEN} ├─ 🔨 ${clean}${RESET}"
|
|
174
|
+
return
|
|
175
|
+
fi
|
|
176
|
+
|
|
177
|
+
# Reviewer
|
|
178
|
+
if [[ "$clean" == *"APPROVED"* ]]; then
|
|
179
|
+
echo -e "${prefix}${GREEN} ├─ ✅ ${clean}${RESET}"
|
|
180
|
+
return
|
|
181
|
+
fi
|
|
182
|
+
if [[ "$clean" == *"REJECTED"* ]]; then
|
|
183
|
+
echo -e "${prefix}${RED} ├─ ❌ ${clean}${RESET}"
|
|
184
|
+
return
|
|
185
|
+
fi
|
|
186
|
+
if [[ "$clean" == *"[reviewer"* ]]; then
|
|
187
|
+
echo -e "${prefix}${YELLOW} ├─ 👁️ ${clean}${RESET}"
|
|
188
|
+
return
|
|
189
|
+
fi
|
|
190
|
+
|
|
191
|
+
# Solomon
|
|
192
|
+
if [[ "$clean" == *"[solomon"* ]] || [[ "$clean" == *"Solomon"* ]]; then
|
|
193
|
+
echo -e "${prefix}${MAGENTA} ├─ ⚖️ ${clean}${RESET}"
|
|
194
|
+
return
|
|
195
|
+
fi
|
|
196
|
+
|
|
197
|
+
# Sonar
|
|
198
|
+
if [[ "$clean" == *"[sonar"* ]] || [[ "$clean" == *"SonarQube"* ]] || [[ "$clean" == *"Quality gate"* ]]; then
|
|
199
|
+
echo -e "${prefix}${BLUE} ├─ 🔍 ${clean}${RESET}"
|
|
200
|
+
return
|
|
201
|
+
fi
|
|
202
|
+
|
|
203
|
+
# Tester
|
|
204
|
+
if [[ "$clean" == *"[tester"* ]] || [[ "$clean" == *"Tester"* ]]; then
|
|
205
|
+
echo -e "${prefix}${CYAN} ├─ 🧪 ${clean}${RESET}"
|
|
206
|
+
return
|
|
207
|
+
fi
|
|
208
|
+
|
|
209
|
+
# Security
|
|
210
|
+
if [[ "$clean" == *"[security"* ]] || [[ "$clean" == *"Security"* ]]; then
|
|
211
|
+
echo -e "${prefix}${CYAN} ├─ 🔒 ${clean}${RESET}"
|
|
212
|
+
return
|
|
213
|
+
fi
|
|
214
|
+
|
|
215
|
+
# Researcher
|
|
216
|
+
if [[ "$clean" == *"[researcher"* ]] || [[ "$clean" == *"Researcher"* ]]; then
|
|
217
|
+
echo -e "${prefix}${CYAN} ├─ 🔬 ${clean}${RESET}"
|
|
218
|
+
return
|
|
219
|
+
fi
|
|
220
|
+
|
|
221
|
+
# Architect
|
|
222
|
+
if [[ "$clean" == *"[architect"* ]] || [[ "$clean" == *"Architect"* ]]; then
|
|
223
|
+
echo -e "${prefix}${CYAN} ├─ 🏗️ ${clean}${RESET}"
|
|
224
|
+
return
|
|
225
|
+
fi
|
|
226
|
+
|
|
227
|
+
# Planner
|
|
228
|
+
if [[ "$clean" == *"[planner"* ]] || [[ "$clean" == *"Planner"* ]]; then
|
|
229
|
+
echo -e "${prefix}${CYAN} ├─ 🧠 ${clean}${RESET}"
|
|
230
|
+
return
|
|
231
|
+
fi
|
|
232
|
+
|
|
233
|
+
# Triage
|
|
234
|
+
if [[ "$clean" == *"[triage"* ]] || [[ "$clean" == *"Triage"* ]]; then
|
|
235
|
+
echo -e "${prefix}${CYAN} ├─ 📋 ${clean}${RESET}"
|
|
236
|
+
return
|
|
237
|
+
fi
|
|
238
|
+
|
|
239
|
+
# Audit
|
|
240
|
+
if [[ "$clean" == *"[audit"* ]] || [[ "$clean" == *"Audit"* ]]; then
|
|
241
|
+
echo -e "${prefix}${CYAN} ├─ 📊 ${clean}${RESET}"
|
|
242
|
+
return
|
|
243
|
+
fi
|
|
244
|
+
|
|
245
|
+
# Preflight
|
|
246
|
+
if [[ "$clean" == *"[preflight"* ]] || [[ "$clean" == *"Preflight"* ]]; then
|
|
247
|
+
echo -e "${prefix}${GRAY} ├─ ⚙️ ${clean}${RESET}"
|
|
248
|
+
return
|
|
249
|
+
fi
|
|
250
|
+
|
|
251
|
+
# TDD
|
|
252
|
+
if [[ "$clean" == *"TDD"* ]] || [[ "$clean" == *"tdd"* ]]; then
|
|
253
|
+
echo -e "${prefix}${GREEN} ├─ 📋 ${clean}${RESET}"
|
|
254
|
+
return
|
|
255
|
+
fi
|
|
256
|
+
|
|
257
|
+
# Errors / failures
|
|
258
|
+
if [[ "$clean" == *"fail"* || "$clean" == *"FAIL"* || "$clean" == *"error"* || "$clean" == *"ERROR"* ]]; then
|
|
259
|
+
echo -e "${prefix}${RED} ├─ ⚠️ ${clean}${RESET}"
|
|
260
|
+
return
|
|
261
|
+
fi
|
|
262
|
+
|
|
263
|
+
# Standby / rate limit
|
|
264
|
+
if [[ "$clean" == *"[standby]"* ]] || [[ "$clean" == *"standby"* ]] || [[ "$clean" == *"rate limit"* ]]; then
|
|
265
|
+
echo -e "${prefix}${YELLOW} ├─ ⏸️ ${clean}${RESET}"
|
|
266
|
+
return
|
|
267
|
+
fi
|
|
268
|
+
|
|
269
|
+
# Model fallback
|
|
270
|
+
if [[ "$clean" == *"not supported"* ]] || [[ "$clean" == *"retrying with"* ]]; then
|
|
271
|
+
echo -e "${prefix}${YELLOW} ├─ 🔄 ${clean}${RESET}"
|
|
272
|
+
return
|
|
273
|
+
fi
|
|
274
|
+
|
|
275
|
+
# Result line
|
|
276
|
+
if [[ "$clean" == *"Result:"* ]]; then
|
|
277
|
+
echo -e "${prefix}${BOLD}${GREEN}🏁 ${clean}${RESET}"
|
|
278
|
+
return
|
|
279
|
+
fi
|
|
280
|
+
|
|
281
|
+
# Budget (verbose only — already filtered above)
|
|
282
|
+
if [[ "$clean" == *"Budget:"* ]]; then
|
|
283
|
+
echo -e "${prefix}${GRAY} ├─ 💰 ${clean}${RESET}"
|
|
284
|
+
return
|
|
285
|
+
fi
|
|
286
|
+
|
|
287
|
+
# Agent heartbeat (verbose only)
|
|
288
|
+
if [[ "$clean" == *"heartbeat"* ]] || [[ "$clean" == *"active —"* ]] || [[ "$clean" == *"elapsed"* ]]; then
|
|
289
|
+
echo -e "${prefix}${GRAY} ├─ • ${clean}${RESET}"
|
|
290
|
+
return
|
|
291
|
+
fi
|
|
292
|
+
|
|
293
|
+
# Default
|
|
294
|
+
echo -e "${prefix} ├─ ${clean}"
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
# ── Header ──────────────────────────────────────────────
|
|
298
|
+
echo -e "${BOLD}${CYAN}kj-tail${RESET} ${DIM}v${VERSION} — ${LOG_FILE}${RESET}"
|
|
299
|
+
if [[ "$FOLLOW" == "true" ]]; then
|
|
300
|
+
echo -e "${GRAY}Ctrl+C to stop${RESET}${VERBOSE:+ ${DIM}(verbose)${RESET}}"
|
|
301
|
+
fi
|
|
302
|
+
echo ""
|
|
303
|
+
|
|
304
|
+
# ── Run ─────────────────────────────────────────────────
|
|
305
|
+
if [[ "$FOLLOW" == "false" ]]; then
|
|
306
|
+
# Snapshot mode: show full log and exit
|
|
307
|
+
while IFS= read -r line; do
|
|
308
|
+
filter_line "$line"
|
|
309
|
+
done < "$LOG_FILE"
|
|
310
|
+
exit 0
|
|
311
|
+
fi
|
|
312
|
+
|
|
313
|
+
if [[ "$NUM_LINES" -gt 0 ]]; then
|
|
314
|
+
# Show last N lines then follow
|
|
315
|
+
tail -n "$NUM_LINES" -F "$LOG_FILE" 2>/dev/null | while IFS= read -r line; do
|
|
316
|
+
filter_line "$line"
|
|
317
|
+
done
|
|
318
|
+
else
|
|
319
|
+
# Follow only new lines
|
|
320
|
+
tail -n 0 -F "$LOG_FILE" 2>/dev/null | while IFS= read -r line; do
|
|
321
|
+
filter_line "$line"
|
|
322
|
+
done
|
|
323
|
+
fi
|
package/docs/README.es.md
CHANGED
|
@@ -129,33 +129,135 @@ Guias completas: [`docs/multi-instance.md`](multi-instance.md) | [`docs/install-
|
|
|
129
129
|
|
|
130
130
|
`kj init` auto-detecta los agentes instalados. Si solo hay uno disponible, se asigna a todos los roles automaticamente.
|
|
131
131
|
|
|
132
|
-
##
|
|
132
|
+
## Tres formas de usar Karajan
|
|
133
|
+
|
|
134
|
+
Karajan instala **tres comandos**: `kj`, `kj-tail` y `karajan-mcp`.
|
|
135
|
+
|
|
136
|
+
### 1. CLI — Directamente desde terminal
|
|
133
137
|
|
|
134
138
|
```bash
|
|
135
|
-
# Ejecutar una tarea con defaults (claude=coder, codex=reviewer, TDD)
|
|
136
139
|
kj run "Implementar autenticacion de usuario con JWT"
|
|
137
|
-
|
|
138
|
-
# Solo coder (sin revision)
|
|
139
140
|
kj code "Anadir validacion de inputs al formulario de registro"
|
|
140
|
-
|
|
141
|
-
# Solo reviewer (revisar diff actual)
|
|
142
141
|
kj review "Revisar los cambios de autenticacion"
|
|
142
|
+
kj plan "Refactorizar la capa de base de datos"
|
|
143
|
+
```
|
|
143
144
|
|
|
144
|
-
|
|
145
|
-
kj plan "Refactorizar la capa de base de datos para usar connection pooling"
|
|
145
|
+
### 2. MCP — Dentro de tu agente de IA
|
|
146
146
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
147
|
+
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
|
+
```
|
|
150
|
+
Tu → Claude Code → kj_run (via MCP) → triage → coder → sonar → reviewer → tester → security
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**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
|
+
### 3. kj-tail — Monitorizar desde otro terminal
|
|
156
|
+
|
|
157
|
+
**La herramienta companera.** Abre un segundo terminal en el **mismo directorio del proyecto** donde esta trabajando tu agente de IA:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
kj-tail
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Veras la salida del pipeline en vivo — etapas, resultados, iteraciones, errores — tal como ocurren.
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
kj-tail # Seguir pipeline en tiempo real (por defecto)
|
|
167
|
+
kj-tail -v # Verbose: incluir heartbeats de agente y presupuesto
|
|
168
|
+
kj-tail -t # Mostrar timestamps
|
|
169
|
+
kj-tail -s # Snapshot: mostrar log actual y salir
|
|
170
|
+
kj-tail -n 50 # Mostrar ultimas 50 lineas y seguir
|
|
171
|
+
kj-tail --help # Todas las opciones
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
> **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.
|
|
175
|
+
|
|
176
|
+
**Flujo tipico:**
|
|
177
|
+
|
|
178
|
+
```
|
|
179
|
+
┌──────────────────────────┐ ┌──────────────────────────┐
|
|
180
|
+
│ Terminal 1 │ │ Terminal 2 │
|
|
181
|
+
│ │ │ │
|
|
182
|
+
│ $ claude │ │ $ kj-tail │
|
|
183
|
+
│ > implementa la │ │ │
|
|
184
|
+
│ siguiente tarea │ │ ├─ 📋 Triage: medium │
|
|
185
|
+
│ prioritaria │ │ ├─ 🔬 Researcher ✅ │
|
|
186
|
+
│ │ │ ├─ 🧠 Planner ✅ │
|
|
187
|
+
│ (Claude llama a kj_run │ │ ├─ 🔨 Coder ✅ │
|
|
188
|
+
│ via MCP — solo ves │ │ ├─ 🔍 Sonar: OK │
|
|
189
|
+
│ el resultado final) │ │ ├─ 👁️ Reviewer ❌ │
|
|
190
|
+
│ │ │ ├─ ⚖️ Solomon: 2 cond. │
|
|
191
|
+
│ │ │ ├─ 🔨 Coder (iter 2) ✅ │
|
|
192
|
+
│ │ │ ├─ ✅ Review: APPROVED │
|
|
193
|
+
│ │ │ ├─ 🧪 Tester: passed │
|
|
194
|
+
│ │ │ └─ 🏁 Result: APPROVED │
|
|
195
|
+
└──────────────────────────┘ └──────────────────────────┘
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
**Ejemplo con pipeline completo** — tarea compleja con todos los roles:
|
|
199
|
+
|
|
200
|
+
```
|
|
201
|
+
┌─ Terminal 1 ─────────────────────────────────────────────────────────────────┐
|
|
202
|
+
│ │
|
|
203
|
+
│ $ claude │
|
|
204
|
+
│ │
|
|
205
|
+
│ > Construye una API REST para un sistema de reservas. Requisitos: │
|
|
206
|
+
│ > - Express + TypeScript con validacion Zod en cada endpoint │
|
|
207
|
+
│ > - Endpoints: POST /bookings, GET /bookings/:id, │
|
|
208
|
+
│ > PATCH /bookings/:id/cancel │
|
|
209
|
+
│ > - Una reserva tiene: id, guestName, roomType (standard|suite|penthouse), │
|
|
210
|
+
│ > checkIn, checkOut, status (confirmed|cancelled) │
|
|
211
|
+
│ > - Validar: checkOut posterior a checkIn, sin fechas pasadas, │
|
|
212
|
+
│ > roomType debe ser un valor valido del enum │
|
|
213
|
+
│ > - Cancelar devuelve 409 si ya esta cancelada │
|
|
214
|
+
│ > - Usa TDD. Ejecutalo con Karajan con architect y planner activos, │
|
|
215
|
+
│ > modo paranoid. Coder claude, reviewer codex. │
|
|
216
|
+
│ │
|
|
217
|
+
│ Claude llama a kj_run via MCP con: │
|
|
218
|
+
│ --enable-architect --enable-researcher --enable-planner --mode paranoid │
|
|
219
|
+
│ │
|
|
220
|
+
└──────────────────────────────────────────────────────────────────────────────┘
|
|
221
|
+
|
|
222
|
+
┌─ Terminal 2: kj-tail ────────────────────────────────────────────────────────┐
|
|
223
|
+
│ │
|
|
224
|
+
│ kj-tail v1.36.1 — .kj/run.log │
|
|
225
|
+
│ │
|
|
226
|
+
│ ├─ 📋 Triage: medium (sw) — activando researcher, architect, planner │
|
|
227
|
+
│ ├─ ⚙️ Preflight passed — all checks OK │
|
|
228
|
+
│ ├─ 🔬 Researcher: 8 ficheros, 3 patrones, 5 restricciones │
|
|
229
|
+
│ ├─ 🏗️ Architect: diseno 3 capas (routes → service → validators) │
|
|
230
|
+
│ ├─ 🧠 Planner: 6 pasos — tests primero, luego rutas, servicio, validadores │
|
|
231
|
+
│ │ │
|
|
232
|
+
│ ▶ Iteracion 1/5 │
|
|
233
|
+
│ ├─ 🔨 Coder (claude): 3 endpoints + 18 tests │
|
|
234
|
+
│ ├─ 📋 TDD: PASS (3 src, 2 test) │
|
|
235
|
+
│ ├─ 🔍 Sonar: Quality gate OK │
|
|
236
|
+
│ ├─ 👁️ Reviewer (codex): REJECTED (2 blocking) │
|
|
237
|
+
│ │ "Falta 404 para GET booking inexistente" │
|
|
238
|
+
│ │ "Endpoint cancel sin test de idempotencia" │
|
|
239
|
+
│ ├─ ⚖️ Solomon: approve_with_conditions (2 condiciones) │
|
|
240
|
+
│ │ "Anadir respuesta 404 y test para GET /bookings/:id con id desconocido" │
|
|
241
|
+
│ │ "Anadir test: cancelar reserva ya cancelada devuelve 409, no 500" │
|
|
242
|
+
│ │ │
|
|
243
|
+
│ ▶ Iteracion 2/5 │
|
|
244
|
+
│ ├─ 🔨 Coder (claude): corregido — 22 tests │
|
|
245
|
+
│ ├─ 📋 TDD: PASS │
|
|
246
|
+
│ ├─ 🔍 Sonar: OK │
|
|
247
|
+
│ ├─ 👁️ Reviewer (codex): APPROVED │
|
|
248
|
+
│ ├─ 🧪 Tester: passed — cobertura 94%, 22 tests │
|
|
249
|
+
│ ├─ 🔒 Security: passed — 0 criticos, 1 bajo (helmet recomendado) │
|
|
250
|
+
│ ├─ 📊 Audit: CERTIFIED (3 advertencias) │
|
|
251
|
+
│ │ │
|
|
252
|
+
│ 🏁 Resultado: APPROVED │
|
|
253
|
+
│ 🔬 Investigacion: 8 ficheros, 3 patrones │
|
|
254
|
+
│ 🗺 Plan: 6 pasos (tests primero) │
|
|
255
|
+
│ 🧪 Cobertura: 94%, 22 tests │
|
|
256
|
+
│ 🔒 Seguridad: OK │
|
|
257
|
+
│ 🔍 Sonar: OK │
|
|
258
|
+
│ 💰 Presupuesto: $0.42 (claude: $0.38, codex: $0.04) │
|
|
259
|
+
│ │
|
|
260
|
+
└──────────────────────────────────────────────────────────────────────────────┘
|
|
159
261
|
```
|
|
160
262
|
|
|
161
263
|
## Comandos CLI
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "karajan-code",
|
|
3
|
-
"version": "1.36.
|
|
3
|
+
"version": "1.36.1",
|
|
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",
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
],
|
|
39
39
|
"bin": {
|
|
40
40
|
"kj": "bin/kj.js",
|
|
41
|
+
"kj-tail": "bin/kj-tail",
|
|
41
42
|
"karajan-mcp": "bin/karajan-mcp.js"
|
|
42
43
|
},
|
|
43
44
|
"scripts": {
|