fix: latest task entry shows ~2 lines of command, not full or 1-line

Past entries stay compact (36 chars). The latest/active entry shows up
to 70 chars (~2 Telegram lines) of the command with result on a
separate indented line, giving enough context without excessive height.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
dj-oyu 2026-02-22 03:22:50 +09:00
parent ff8cd2a75e
commit 91b8df5844
2 changed files with 43 additions and 14 deletions

View file

@ -1041,22 +1041,25 @@ func buildRichStatus(task *activeTask, isBackground bool, workspace string) stri
sb.WriteString(formatCompactEntry(entry))
sb.WriteString("\n")
} else {
// Latest entry: reserved area for detail
sb.WriteString(formatCompactEntry(entry))
sb.WriteString("\n")
// Latest entry: show command up to ~2 lines worth, then result on next line
const maxLatestWidth = 70
prefix := entry.Name
if entry.ArgsSnip != "" {
prefix += " " + entry.ArgsSnip
}
if runes := []rune(prefix); len(runes) > maxLatestWidth {
prefix = string(runes[:maxLatestWidth-1]) + "\u2026"
}
fmt.Fprintf(&sb, "%s\n", prefix)
fmt.Fprintf(&sb, " %s\n", entry.Result)
if isErr && entry.ErrDetail != "" {
// Error block in code-fence style
sb.WriteString("```\n")
for _, line := range strings.Split(entry.ErrDetail, "\n") {
sb.WriteString(line)
sb.WriteString("\n")
}
sb.WriteString("```\n")
} else {
// Reserve height: blank line so bubble doesn't shrink
// when the next update adds error detail
sb.WriteString("\n")
}
}
}

View file

@ -1576,6 +1576,34 @@ func TestBuildRichStatus_ShowsLast5(t *testing.T) {
}
}
func TestBuildRichStatus_LastEntryShowsMoreCommand(t *testing.T) {
longCmd := "uv run pytest tests/hot/test_state_backend_integration.py -v --timeout=60"
task := &activeTask{
Iteration: 2,
MaxIter: 10,
toolLog: []toolLogEntry{
{Name: "exec", ArgsSnip: "ls -la", Result: "✓ 0.5s"},
{Name: "exec", ArgsSnip: longCmd, Result: "⏳"},
},
}
got := buildRichStatus(task, false, "/ws/my-project")
// Last entry: shows more than compact (36) but truncated at ~70
// "exec " + longCmd = 79 chars → should be truncated
if strings.Contains(got, "--timeout=60") {
t.Errorf("last entry should be truncated at ~70 chars, got:\n%s", got)
}
// But shows more than the compact 36
if !strings.Contains(got, "test_state_backend") {
t.Errorf("last entry should show more than compact format, got:\n%s", got)
}
// Result on separate indented line
if !strings.Contains(got, " ⏳") {
t.Errorf("last entry result should be on indented line, got:\n%s", got)
}
}
func TestBuildRichStatus_ErrorAsLastEntry(t *testing.T) {
task := &activeTask{
Iteration: 2,
@ -1593,12 +1621,10 @@ func TestBuildRichStatus_ErrorAsLastEntry(t *testing.T) {
got := buildRichStatus(task, false, "/ws/my-project")
// First entry (past): compact one-liner, result marker present
if !strings.Contains(got, "✓ 0.5s") {
t.Errorf("expected success marker in past entry, got:\n%s", got)
// Last entry: full command + error with code fence detail
if !strings.Contains(got, "pytest tests/test_auth.py") {
t.Errorf("expected full command in last entry, got:\n%s", got)
}
// Last entry: error with code fence detail
if !strings.Contains(got, "✗ 3.2s") {
t.Errorf("expected error marker, got:\n%s", got)
}
@ -1608,7 +1634,7 @@ func TestBuildRichStatus_ErrorAsLastEntry(t *testing.T) {
}
func TestBuildRichStatus_ErrorNotLastEntry(t *testing.T) {
// When error is a past entry (not the last), it should be 1 line
// When error is a past entry (not the last), it should be 1 compact line
task := &activeTask{
Iteration: 3,
MaxIter: 10,