Skip to content

Commit ed79522

Browse files
garymeyercaclaude
andcommitted
Fix claude agent posting raw stream-JSON instead of reply text
`claude -p --output-format json` now returns a single-line JSON array of events ([system/init, ...assistant, result]) rather than an object with a top-level `.result`. runClaude() parsed line-by-line looking for `.result`, never found it on the array, and fell back to dumping raw stdout onto the channel. Parse the whole stdout and walk events for the `result` element, keeping fallbacks for the legacy single-object and NDJSON/stream-json shapes. Fixes #13 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 392b988 commit ed79522

1 file changed

Lines changed: 18 additions & 7 deletions

File tree

bin/walkie.js

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -173,13 +173,24 @@ function runClaude(prompt, sessionId, model, extraArgs) {
173173

174174
const stdout = (result.stdout || '').trim()
175175
const out = { text: stdout, sessionId: null }
176-
const lines = stdout.split('\n').filter(l => l.trim())
177-
for (let i = lines.length - 1; i >= 0; i--) {
178-
try {
179-
const obj = JSON.parse(lines[i])
180-
if (obj.session_id) out.sessionId = obj.session_id
181-
if (obj.result !== undefined) { out.text = obj.result; break }
182-
} catch {}
176+
177+
// `claude -p --output-format json` returns a single-line JSON array of
178+
// events ([system/init, ...assistant, result]); the reply text is on the
179+
// element with type "result". Older CLIs returned a single result object,
180+
// and stream-json emits newline-delimited objects. Handle all three.
181+
const applyEvent = (obj) => {
182+
if (!obj || typeof obj !== 'object') return
183+
if (obj.session_id) out.sessionId = obj.session_id
184+
if (obj.type === 'result' && typeof obj.result === 'string') out.text = obj.result
185+
else if (obj.result !== undefined) out.text = obj.result
186+
}
187+
188+
let whole
189+
try { whole = JSON.parse(stdout) } catch {}
190+
if (Array.isArray(whole)) whole.forEach(applyEvent)
191+
else if (whole && typeof whole === 'object') applyEvent(whole)
192+
else for (const line of stdout.split('\n')) {
193+
try { applyEvent(JSON.parse(line)) } catch {}
183194
}
184195
return out
185196
}

0 commit comments

Comments
 (0)