karajan-code 1.9.3 → 1.9.4

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 CHANGED
@@ -420,6 +420,18 @@ After `npm install -g karajan-code`, the MCP server is auto-registered in Claude
420
420
  | `kj_review` | Run reviewer-only mode |
421
421
  | `kj_plan` | Generate implementation plan with heartbeat/stall telemetry and clearer diagnostics |
422
422
 
423
+ ### MCP restart after version updates
424
+
425
+ If you update Karajan Code (for example `npm install -g karajan-code` to a new version) while your MCP host session is still open, the current `karajan-mcp` process may exit and the host can show `Transport closed`.
426
+
427
+ This is expected behavior: the MCP server detects a version mismatch and exits so the host can spawn a fresh process with the new code.
428
+
429
+ Quick recovery:
430
+
431
+ 1. Restart your MCP host session (Claude/Codex/new terminal session).
432
+ 2. Verify the server is listed (`codex mcp list` or your host equivalent).
433
+ 3. Run a lightweight check (`kj_config`) before continuing with larger runs.
434
+
423
435
  ### Recommended Companion MCPs
424
436
 
425
437
  Karajan Code works great on its own, but combining it with these MCP servers gives your AI agent a complete development environment:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "karajan-code",
3
- "version": "1.9.3",
3
+ "version": "1.9.4",
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",
@@ -21,6 +21,7 @@ import { parseMaybeJsonString } from "../review/parser.js";
21
21
  import { computeBaseRef, generateDiff } from "../review/diff-generator.js";
22
22
  import { resolveReviewProfile } from "../review/profiles.js";
23
23
  import { createRunLog, readRunLog } from "../utils/run-log.js";
24
+ import { currentBranch } from "../utils/git.js";
24
25
 
25
26
  /**
26
27
  * Resolve the user's project directory via MCP roots.
@@ -109,6 +110,13 @@ export function classifyError(error) {
109
110
  };
110
111
  }
111
112
 
113
+ if (lower.includes("you are on the base branch")) {
114
+ return {
115
+ category: "branch_error",
116
+ suggestion: "Create a feature branch before running Karajan. Use 'git checkout -b feat/<task-description>' and then retry. Do NOT run kj_code directly on the base branch."
117
+ };
118
+ }
119
+
112
120
  if (lower.includes("not a git repository")) {
113
121
  return {
114
122
  category: "git_error",
@@ -119,6 +127,23 @@ export function classifyError(error) {
119
127
  return { category: "unknown", suggestion: null };
120
128
  }
121
129
 
130
+ export async function assertNotOnBaseBranch(config) {
131
+ const baseBranch = config?.base_branch || "main";
132
+ let branch;
133
+ try {
134
+ branch = await currentBranch();
135
+ } catch {
136
+ return; // not a git repo or detached HEAD — let downstream handle it
137
+ }
138
+ if (branch === baseBranch) {
139
+ throw new Error(
140
+ `You are on the base branch '${baseBranch}'. Karajan needs a feature branch to compute the diff for review. ` +
141
+ `Create a new branch first (e.g. 'git checkout -b feat/<task-description>') and then run this command again. ` +
142
+ `Do NOT run kj_code directly — create the branch first so the full pipeline (code + review) works correctly.`
143
+ );
144
+ }
145
+ }
146
+
122
147
  export function enrichedFailPayload(error, toolName) {
123
148
  const msg = error?.message || String(error);
124
149
  const { category, suggestion } = classifyError(error);
@@ -161,6 +186,7 @@ export function buildAskQuestion(server) {
161
186
 
162
187
  export async function handleRunDirect(a, server, extra) {
163
188
  const config = await buildConfig(a);
189
+ await assertNotOnBaseBranch(config);
164
190
  const logger = createLogger(config.output.log_level, "mcp");
165
191
 
166
192
  const requiredProviders = [
@@ -304,6 +330,7 @@ export async function handlePlanDirect(a, server, extra) {
304
330
 
305
331
  export async function handleCodeDirect(a, server, extra) {
306
332
  const config = await buildConfig(a, "code");
333
+ await assertNotOnBaseBranch(config);
307
334
  const logger = createLogger(config.output.log_level, "mcp");
308
335
 
309
336
  const coderRole = resolveRole(config, "coder");
@@ -352,6 +379,7 @@ export async function handleCodeDirect(a, server, extra) {
352
379
 
353
380
  export async function handleReviewDirect(a, server, extra) {
354
381
  const config = await buildConfig(a, "review");
382
+ await assertNotOnBaseBranch(config);
355
383
  const logger = createLogger(config.output.log_level, "mcp");
356
384
 
357
385
  const reviewerRole = resolveRole(config, "reviewer");