@openagents-org/agent-launcher 0.2.82 → 0.2.83

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/tui.js +45 -27
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openagents-org/agent-launcher",
3
- "version": "0.2.82",
3
+ "version": "0.2.83",
4
4
  "description": "OpenAgents Launcher — install, configure, and run AI coding agents from your terminal",
5
5
  "main": "src/index.js",
6
6
  "bin": {
package/src/tui.js CHANGED
@@ -300,7 +300,7 @@ function createTUI() {
300
300
 
301
301
  // ── Footer rendering (context-aware, clickable) ──
302
302
  function updateFooter() {
303
- const agent = agentRows[agentList.selected];
303
+ const agent = selectedAgent();
304
304
  const items = [];
305
305
 
306
306
  items.push({ key: 'i', label: 'Install' });
@@ -357,25 +357,30 @@ function createTUI() {
357
357
 
358
358
  // ── Agent table refresh ──
359
359
  function refreshAgentTable() {
360
- const savedIdx = agentList.selected || 0;
360
+ const savedIdx = Math.floor((agentList.selected || 0) / 2);
361
361
  try { agentRows = loadAgentRows(connector); } catch { agentRows = []; }
362
362
 
363
363
  if (agentRows.length === 0) {
364
364
  agentList.setItems([' {gray-fg}No agents configured. Press {bold}i{/bold} to install, {bold}n{/bold} to create.{/gray-fg}']);
365
365
  } else {
366
- const items = agentRows.map(r => {
366
+ // Two rows per agent: main row + detail row (path + config status)
367
+ const items = [];
368
+ for (const r of agentRows) {
367
369
  const state = stateMarkup(r.state, !!r.workspace);
368
- const ws = r.workspace || '{gray-fg}-{/gray-fg}';
369
- const pathInfo = r.path ? `{gray-fg} ${r.path}{/gray-fg}` : '';
370
- const warning = r.notReadyMsg ? ` {yellow-fg}⚠ ${r.notReadyMsg}{/yellow-fg}` : '';
371
- return ` ${r.name.padEnd(22)} ${r.type.padEnd(14)} ${state.padEnd(30)} ${ws}${pathInfo}${warning}`;
372
- });
370
+ const ws = r.workspace || '';
371
+ items.push(` ${r.name.padEnd(22)} ${r.type.padEnd(14)} ${state.padEnd(30)} ${ws}`);
372
+ // Detail row: working dir + config warning
373
+ const details = [];
374
+ if (r.path) details.push(r.path);
375
+ if (r.notReadyMsg) details.push(`{yellow-fg}⚠ ${r.notReadyMsg}{/yellow-fg}`);
376
+ items.push(` {gray-fg} ${details.join(' · ') || ''}{/gray-fg}`);
377
+ }
373
378
  agentList.setItems(items);
374
379
  }
375
380
 
376
- // Restore cursor position
381
+ // Restore cursor position (2 rows per agent)
377
382
  if (agentRows.length > 0) {
378
- agentList.select(Math.min(savedIdx, agentRows.length - 1));
383
+ agentList.select(Math.min(savedIdx * 2, (agentRows.length - 1) * 2));
379
384
  }
380
385
 
381
386
  updateHeader();
@@ -404,13 +409,26 @@ function createTUI() {
404
409
  );
405
410
  }
406
411
 
407
- // Update footer when selection changes
408
- agentList.on('select item', () => updateFooter());
412
+ // Helper: get currently selected agent (2 rows per agent)
413
+ function selectedAgent() {
414
+ return agentRows[Math.floor((agentList.selected || 0) / 2)];
415
+ }
416
+
417
+ // Navigate by 2 to skip detail rows
418
+ agentList.on('select item', () => {
419
+ // Snap to even rows (main rows)
420
+ const idx = agentList.selected || 0;
421
+ if (idx % 2 !== 0 && agentRows.length > 0) {
422
+ agentList.select(idx - 1);
423
+ screen.render();
424
+ }
425
+ updateFooter();
426
+ });
409
427
 
410
428
  // ── Enter key → Context menu ──
411
429
  agentList.on('select', (_item, idx) => {
412
430
  if (currentView !== 'main') return;
413
- const agent = agentRows[idx];
431
+ const agent = agentRows[Math.floor(idx / 2)];
414
432
  if (!agent || !agent.configured) return;
415
433
  showAgentActionMenu(agent);
416
434
  });
@@ -1402,38 +1420,38 @@ function createTUI() {
1402
1420
  });
1403
1421
  },
1404
1422
  Start() {
1405
- if (currentView !== 'main' || !agentRows[agentList.selected]) return;
1406
- const a = agentRows[agentList.selected];
1423
+ if (currentView !== 'main' || !selectedAgent()) return;
1424
+ const a = selectedAgent();
1407
1425
  if (a.configured) doStart(a.name);
1408
1426
  },
1409
1427
  Stop() {
1410
- if (currentView !== 'main' || !agentRows[agentList.selected]) return;
1411
- const a = agentRows[agentList.selected];
1428
+ if (currentView !== 'main' || !selectedAgent()) return;
1429
+ const a = selectedAgent();
1412
1430
  if (a.configured) doStop(a.name);
1413
1431
  },
1414
1432
  Configure() {
1415
- if (currentView !== 'main' || !agentRows[agentList.selected]) return;
1416
- const a = agentRows[agentList.selected];
1433
+ if (currentView !== 'main' || !selectedAgent()) return;
1434
+ const a = selectedAgent();
1417
1435
  if (a.configured) showConfigureScreen(a);
1418
1436
  },
1419
1437
  Connect() {
1420
- if (currentView !== 'main' || !agentRows[agentList.selected]) return;
1421
- const a = agentRows[agentList.selected];
1438
+ if (currentView !== 'main' || !selectedAgent()) return;
1439
+ const a = selectedAgent();
1422
1440
  if (a.configured && !a.workspace) showConnectWorkspaceScreen(a.name);
1423
1441
  },
1424
1442
  Disconnect() {
1425
- if (currentView !== 'main' || !agentRows[agentList.selected]) return;
1426
- const a = agentRows[agentList.selected];
1443
+ if (currentView !== 'main' || !selectedAgent()) return;
1444
+ const a = selectedAgent();
1427
1445
  if (a.configured && a.workspace) doDisconnect(a.name);
1428
1446
  },
1429
1447
  Workspace() {
1430
- if (currentView !== 'main' || !agentRows[agentList.selected]) return;
1431
- const a = agentRows[agentList.selected];
1448
+ if (currentView !== 'main' || !selectedAgent()) return;
1449
+ const a = selectedAgent();
1432
1450
  if (a.configured && a.workspace) doOpenWorkspace(a);
1433
1451
  },
1434
1452
  Remove() {
1435
- if (currentView !== 'main' || !agentRows[agentList.selected]) return;
1436
- const a = agentRows[agentList.selected];
1453
+ if (currentView !== 'main' || !selectedAgent()) return;
1454
+ const a = selectedAgent();
1437
1455
  if (a.configured) doRemove(a.name);
1438
1456
  },
1439
1457
  Daemon() {