@openagents-org/agent-launcher 0.2.29 → 0.2.31

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": "@openagents-org/agent-launcher",
3
- "version": "0.2.29",
3
+ "version": "0.2.31",
4
4
  "description": "OpenAgents Launcher — install, configure, and run AI coding agents from your terminal",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -286,21 +286,31 @@ class OpenClawAdapter extends BaseAdapter {
286
286
  clearInterval(pollInterval);
287
287
  clearTimeout(killTimeout);
288
288
  fs.closeSync(stderrFd);
289
- // Read any remaining stderr
289
+ // Read full stderr content (contains JSON output + trace lines)
290
+ let stderrContent = '';
290
291
  try {
291
- const remaining = fs.readFileSync(stderrFile, 'utf-8').slice(stderrOffset);
292
+ stderrContent = fs.readFileSync(stderrFile, 'utf-8');
293
+ this._log(`CLI exit code=${code}, stdout=${output.length}b, stderr=${stderrContent.length}b`);
294
+ // Process any remaining lines for tool events
295
+ const remaining = stderrContent.slice(stderrOffset);
292
296
  if (remaining) {
293
- output += remaining;
294
297
  for (const line of remaining.split('\n')) processLine(line);
295
298
  }
296
- } catch {}
299
+ } catch (e) {
300
+ this._log(`CLI stderr read error: ${e.message}`);
301
+ }
297
302
  try { fs.unlinkSync(stderrFile); } catch {}
298
303
 
304
+ // OpenClaw --json writes JSON to stderr, so combine stdout + stderr
305
+ const allOutput = output + '\n' + stderrContent;
306
+ const hasPayloads = allOutput.includes('"payloads"');
307
+ this._log(`CLI parse: hasPayloads=${hasPayloads}, total=${allOutput.length}b`);
308
+
299
309
  if (code !== 0) {
300
- reject(new Error(`CLI exited ${code}: ${output.slice(-300)}`));
310
+ reject(new Error(`CLI exited ${code}: ${allOutput.slice(-300)}`));
301
311
  return;
302
312
  }
303
- this._parseCliOutput(output, resolve);
313
+ this._parseCliOutput(allOutput, resolve);
304
314
  });
305
315
  });
306
316
  }
@@ -308,19 +318,65 @@ class OpenClawAdapter extends BaseAdapter {
308
318
  _parseCliOutput(output, resolve) {
309
319
  const text = output.trim();
310
320
  if (!text) { resolve(''); return; }
311
- const jsonStart = text.indexOf('{');
312
- if (jsonStart < 0) { resolve(text); return; }
313
- try {
314
- const data = JSON.parse(text.slice(jsonStart));
315
- const payloads = data.payloads || [];
316
- if (payloads.length > 0) {
317
- resolve(payloads.filter(p => p.text).map(p => p.text).join('\n\n'));
318
- } else {
319
- resolve('');
321
+
322
+ // OpenClaw --json outputs a JSON blob with {"payloads":[...]} structure.
323
+ // With --log-level trace, stderr also contains diagnostic lines.
324
+ // Find the JSON by looking for '{"payloads"' or the last complete JSON object.
325
+ let jsonStr = null;
326
+
327
+ // Strategy 1: find {"payloads" directly
328
+ const payloadsIdx = text.indexOf('{"payloads"');
329
+ if (payloadsIdx >= 0) {
330
+ // Find the matching closing brace by counting braces
331
+ let depth = 0;
332
+ for (let i = payloadsIdx; i < text.length; i++) {
333
+ if (text[i] === '{') depth++;
334
+ else if (text[i] === '}') { depth--; if (depth === 0) { jsonStr = text.slice(payloadsIdx, i + 1); break; } }
320
335
  }
321
- } catch {
322
- resolve(text);
323
336
  }
337
+
338
+ // Strategy 2: find last '{' that starts a valid JSON with "payloads"
339
+ if (!jsonStr) {
340
+ for (let i = text.length - 1; i >= 0; i--) {
341
+ if (text[i] === '{') {
342
+ const candidate = text.slice(i);
343
+ try {
344
+ const d = JSON.parse(candidate);
345
+ if (d.payloads) { jsonStr = candidate; break; }
346
+ } catch {}
347
+ }
348
+ }
349
+ }
350
+
351
+ // Strategy 3: try each line that starts with '{'
352
+ if (!jsonStr) {
353
+ for (const line of text.split('\n')) {
354
+ const trimmed = line.trim();
355
+ if (trimmed.startsWith('{')) {
356
+ try {
357
+ const d = JSON.parse(trimmed);
358
+ if (d.payloads) { jsonStr = trimmed; break; }
359
+ } catch {}
360
+ }
361
+ }
362
+ }
363
+
364
+ if (jsonStr) {
365
+ try {
366
+ const data = JSON.parse(jsonStr);
367
+ const payloads = data.payloads || [];
368
+ if (payloads.length > 0) {
369
+ resolve(payloads.filter(p => p.text).map(p => p.text).join('\n\n'));
370
+ return;
371
+ }
372
+ } catch {}
373
+ }
374
+
375
+ // Fallback: return non-diagnostic text
376
+ const cleanLines = text.split('\n').filter(l =>
377
+ !l.includes('[diagnostic]') && !l.includes('[agent/embedded]') && !l.includes('Registered plugin')
378
+ ).map(l => l.trim()).filter(Boolean);
379
+ resolve(cleanLines.join('\n') || '');
324
380
  }
325
381
  // ------------------------------------------------------------------
326
382
  // Static: configure OpenClaw's native auth from LLM env vars