Skip to content

Commit ba09184

Browse files
Ark0Nclaude
andcommitted
fix: wizard "No JSON found" — Claude CLI stream-json returns empty result field
Claude CLI's --output-format stream-json now returns "result": "" in the result message. The actual response text lives in assistant message text blocks, which _textOutput correctly accumulates. runPrompt() was returning the empty resultMsg.result without falling back to _textOutput.value. Also improved plan-orchestrator JSON extraction to try code-block-wrapped JSON first (```json {...} ```) before the greedy regex, plus debug logging. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 93719b4 commit ba09184

2 files changed

Lines changed: 38 additions & 6 deletions

File tree

src/plan-orchestrator.ts

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -414,9 +414,24 @@ export class PlanOrchestrator {
414414

415415
const durationMs = Date.now() - startTime;
416416

417-
// Extract JSON from response
418-
const jsonMatch = response.match(/\{[\s\S]*\}/);
417+
console.log(
418+
`[PlanOrchestrator] Research response length: ${response.length}, first 500 chars:`,
419+
response.substring(0, 500)
420+
);
421+
422+
// Extract JSON from response — try multiple strategies
423+
let jsonMatch = response.match(/```(?:json)?\s*(\{[\s\S]*?\})\s*```/);
424+
if (jsonMatch) {
425+
jsonMatch = [jsonMatch[1]]; // Use captured group (inside code block)
426+
} else {
427+
jsonMatch = response.match(/\{[\s\S]*\}/);
428+
}
429+
419430
if (!jsonMatch) {
431+
console.error(
432+
`[PlanOrchestrator] No JSON found in research response. Full response:`,
433+
response.substring(0, 2000)
434+
);
420435
onSubagent?.({
421436
type: 'failed',
422437
agentId,
@@ -587,9 +602,24 @@ export class PlanOrchestrator {
587602

588603
const durationMs = Date.now() - startTime;
589604

590-
// Extract JSON from response
591-
const jsonMatch = response.match(/\{[\s\S]*\}/);
605+
console.log(
606+
`[PlanOrchestrator] Planner response length: ${response.length}, first 500 chars:`,
607+
response.substring(0, 500)
608+
);
609+
610+
// Extract JSON from response — try multiple strategies
611+
let jsonMatch = response.match(/```(?:json)?\s*(\{[\s\S]*?\})\s*```/);
612+
if (jsonMatch) {
613+
jsonMatch = [jsonMatch[1]]; // Use captured group (inside code block)
614+
} else {
615+
jsonMatch = response.match(/\{[\s\S]*\}/);
616+
}
617+
592618
if (!jsonMatch) {
619+
console.error(
620+
`[PlanOrchestrator] No JSON found in planner response. Full response:`,
621+
response.substring(0, 2000)
622+
);
593623
onSubagent?.({
594624
type: 'failed',
595625
agentId,

src/session.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1516,9 +1516,11 @@ export class Session extends EventEmitter {
15161516
this._status = 'idle';
15171517
const cost = resultMsg.total_cost_usd || 0;
15181518
this._totalCost += cost;
1519-
this.emit('completion', resultMsg.result || '', cost);
1519+
// Claude CLI stream-json may return empty result field — fall back to accumulated text output
1520+
const result = resultMsg.result || this._textOutput.value || '';
1521+
this.emit('completion', result, cost);
15201522
if (resolve) {
1521-
resolve({ result: resultMsg.result || '', cost });
1523+
resolve({ result, cost });
15221524
}
15231525
} else if (exitCode !== 0 || (resultMsg && resultMsg.is_error)) {
15241526
this._status = 'error';

0 commit comments

Comments
 (0)