karajan-code 4.1.8 → 4.1.9

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "karajan-code",
3
- "version": "4.1.8",
3
+ "version": "4.1.9",
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",
@@ -208,9 +208,27 @@ function showPromptModal(prompt) {
208
208
  if (activePromptId === prompt.promptId) return;
209
209
  activePromptId = prompt.promptId;
210
210
  const dlg = ensureDialog();
211
+ // KJC-BUG-0125 (issue #1275): findings render as a readable, open list —
212
+ // "4 findings at severity fail" alone gives the user nothing to act on.
213
+ // Each finding shows its message and the concrete suggestion.
214
+ const sevColor = (s) => (s === 'fail' ? '#f87171' : s === 'warn' ? '#fbbf24' : '#60a5fa');
215
+ const findings = prompt.context?.detail?.findings || prompt.context?.findings;
216
+ const findingsBlock = Array.isArray(findings) && findings.length
217
+ ? `<div style="margin-top:10px;display:flex;flex-direction:column;gap:8px;max-height:280px;overflow:auto">`
218
+ + findings.map((f) => `
219
+ <div style="border-left:3px solid ${sevColor(f.severity)};padding:6px 10px;background:var(--bg-primary);border-radius:var(--radius-sm)">
220
+ <div style="font-size:0.78rem;color:var(--text-muted)">
221
+ <strong style="color:${sevColor(f.severity)}">${esc(String(f.severity || '').toUpperCase())}</strong>
222
+ · ${esc(f.category || '')}${f.id ? ` · ${esc(f.id)}` : ''}
223
+ </div>
224
+ <div style="font-size:0.86rem;line-height:1.45;margin-top:2px">${esc(f.message || '')}</div>
225
+ ${f.suggestion ? `<div style="font-size:0.8rem;color:var(--text-muted);margin-top:2px">→ ${esc(f.suggestion)}</div>` : ''}
226
+ </div>`).join('')
227
+ + `</div>`
228
+ : '';
211
229
  const ctxBlock = prompt.context
212
230
  ? `<details style="margin-top:8px">
213
- <summary style="cursor:pointer;color:var(--text-muted);font-size:0.85rem">Context</summary>
231
+ <summary style="cursor:pointer;color:var(--text-muted);font-size:0.85rem">Raw context</summary>
214
232
  <pre style="white-space:pre-wrap;font-size:0.78rem;background:var(--bg-primary);padding:8px;border-radius:var(--radius-sm);overflow:auto;max-height:240px">${esc(JSON.stringify(prompt.context, null, 2))}</pre>
215
233
  </details>`
216
234
  : '';
@@ -221,6 +239,7 @@ function showPromptModal(prompt) {
221
239
  </div>
222
240
  <div style="padding:14px 18px">
223
241
  <div style="white-space:pre-wrap;font-size:0.95rem;line-height:1.55">${esc(prompt.question)}</div>
242
+ ${findingsBlock}
224
243
  ${ctxBlock}
225
244
  <textarea id="prompt-answer" rows="3"
226
245
  placeholder="Type your answer (or 'stop' to abort the run)"
@@ -11,6 +11,16 @@ import { RISK } from "../autonomy/policy.js";
11
11
 
12
12
  const MAX_REFINE_ITERATIONS = 5;
13
13
 
14
+ // KJC-BUG-0125 (issue #1275): the prompt used to carry only counts and
15
+ // categories — the dashboard modal showed "4 findings at severity fail"
16
+ // with nothing to act on. The full findings travel with the prompt now
17
+ // (capped: a runaway reviewer must not blow up the prompt payload).
18
+ const MAX_FINDINGS_IN_PROMPT = 20;
19
+ const findingsForPrompt = (findings) => findings.slice(0, MAX_FINDINGS_IN_PROMPT).map((f) => ({
20
+ id: f.id, severity: f.severity, category: f.category,
21
+ message: f.message, suggestion: f.suggestion || null,
22
+ }));
23
+
14
24
  /**
15
25
  * Decide the gate action (`continue` | `refine`) autonomously: the Arbiter
16
26
  * picks PROCEED (proceed with the best reading) or RETRY_DIFFERENT_APPROACH
@@ -24,7 +34,7 @@ async function decideGateAutonomously(resolve, { severity, findings }) {
24
34
  { value: "PROCEED", label: "proceed with the best reading", conservative: true },
25
35
  { value: "RETRY_DIFFERENT_APPROACH", label: "auto-refine the spec" },
26
36
  ],
27
- context: { severity, findingCount: findings.length, categories: [...new Set(findings.map((f) => f.category))] },
37
+ context: { severity, findingCount: findings.length, categories: [...new Set(findings.map((f) => f.category))], findings: findingsForPrompt(findings) },
28
38
  risk: severity === "fail" ? RISK.HIGH : RISK.LOW,
29
39
  });
30
40
  return choice === "RETRY_DIFFERENT_APPROACH" ? "refine" : "continue";
@@ -71,7 +81,7 @@ export async function runSpecReview({ spec, config, logger, askQuestion, flags =
71
81
  const answer = await askQuestion(
72
82
  `Spec review: ${findings.length} finding${findings.length === 1 ? "" : "s"} at severity ${severity}. [c]ontinue / [r]efine / [x]cancel? (default: continue)`,
73
83
  {
74
- detail: { severity, findingCount: findings.length, categories: [...new Set(findings.map((f) => f.category))], iteration: iter + 1 },
84
+ detail: { severity, findingCount: findings.length, categories: [...new Set(findings.map((f) => f.category))], iteration: iter + 1, findings: findingsForPrompt(findings) },
75
85
  // KJC-BUG-0109: mirrors the interactive default — --yes presses Enter.
76
86
  defaultAnswer: "continue",
77
87
  },