fix: retain worker tool activity in narrow classic monitor

This commit is contained in:
Teknium
2026-09-07 23:42:56 -07:00
parent 8a23f14df3
commit a0fa236ed4
2 changed files with 31 additions and 4 deletions
+8 -4
View File
@@ -130,10 +130,14 @@ def build_monitor_application(monitor, **kwargs):
rows = []
for row in monitor.entries:
selected = row['subagent_id'] == monitor.selected_id
text = f"{'❯' if selected else ' '} {row['elapsed']}s · {row.get('status') or 'starting'} · {row.get('goal') or row['subagent_id']}"
if row.get('last_tool'):
text += f" · last: {row['last_tool']}"
rows.append(('class:subagent-dock.selected' if selected else '', _clip(text, size.columns) + '\n'))
prefix = f"{row['elapsed']}s · {row.get('status') or 'starting'} · "
activity = f" · last: {row['last_tool']}" if row.get('last_tool') else ''
goal_width = max(0, size.columns - 2 - get_cwidth(prefix + activity))
goal = _clip(row.get('goal') or row['subagent_id'], goal_width)
text = f"{'❯' if selected else ' '} " + _clip(prefix + goal + activity, max(0, size.columns - 2))
# Pad selection in terminal cells, not codepoints (task names may be wide).
text += ' ' * max(0, size.columns - get_cwidth(text))
rows.append(('class:subagent-dock.selected' if selected else '', text + '\n'))
return rows or [('', 'No live subagents. Results arrive in the conversation.')]
def cursor():
+23
View File
@@ -56,3 +56,26 @@ def test_passive_dock_fills_rows_but_keeps_input_live(monkeypatch, columns, rows
app.exit()
await task
asyncio.run(run())
def test_expanded_roster_reserves_activity_before_long_task_names():
from prompt_toolkit.data_structures import Size
from prompt_toolkit.input import create_pipe_input
from prompt_toolkit.output import DummyOutput
from prompt_toolkit.utils import get_cwidth
from hermes_cli.cli_subagent_monitor import SubagentMonitor, build_monitor_application
monitor = SubagentMonitor(SimpleNamespace())
monitor.entries = [dict(subagent_id=str(i), goal='Inspect 界 ' * 30,
elapsed=24, status='running', last_tool='terminal') for i in range(6)]
monitor.selected_id = '0'
output = DummyOutput()
with create_pipe_input() as pipe:
for columns, rows in [(100, 30), (80, 20)]:
output.get_size = lambda: Size(rows=rows, columns=columns)
app = build_monitor_application(monitor, input=pipe, output=output)
fragments = app.layout.current_control.text()
assert len(fragments) == len(monitor.entries)
for _, text in fragments:
assert '24s' in text and 'running' in text and 'last: terminal' in text
assert get_cwidth(text.rstrip('\n')) == columns