From dfc1a3171c81e504a26d87b7014fd15d894e0b4f Mon Sep 17 00:00:00 2001 From: Kaede Akino Date: Sat, 17 Oct 2026 23:10:02 +0800 Subject: [PATCH] fix(assistant): align SSH status label typography --- .../AgentToolDetailPreview.swift | 2 +- .../AssistantToolDetails.swift | 22 ++++++++++--------- .../SSHExecToolPresentation.swift | 9 ++++---- TFM/Features/AI/TranscriptNativeRows.swift | 1 + 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/Frameworks/TermindPresentation/AgentToolDetailPreview.swift b/Frameworks/TermindPresentation/AgentToolDetailPreview.swift index d0ac4159..470662cd 100644 --- a/Frameworks/TermindPresentation/AgentToolDetailPreview.swift +++ b/Frameworks/TermindPresentation/AgentToolDetailPreview.swift @@ -22,7 +22,7 @@ nonisolated public struct AgentToolDetailPreview: Equatable, Sendable { private static func text(_ items: [AgentToolDetail.Item]) -> String { items.map { item in switch item { - case .field(let field): return field.label + ": " + field.value + case .field(let field): return field.value.isEmpty ? field.label : field.label + ": " + field.value case .message(let value, _): return value case .text(let block): return [block.title, block.text].compactMap { $0 }.joined(separator: "\n") case .list(let list): diff --git a/Frameworks/TermindPresentation/AssistantToolDetails.swift b/Frameworks/TermindPresentation/AssistantToolDetails.swift index c6a93318..13dc1a59 100644 --- a/Frameworks/TermindPresentation/AssistantToolDetails.swift +++ b/Frameworks/TermindPresentation/AssistantToolDetails.swift @@ -45,16 +45,18 @@ public struct AssistantToolDetails: View { case .field(let field): HStack(alignment: .firstTextBaseline, spacing: 8) { Text(field.label).font(.caption.weight(.medium)).foregroundStyle(.secondary) - if let navigation = field.navigation, let navigate { - Button(field.value) { navigate(navigation) } - .font(field.isMonospaced ? .caption.monospaced() : .caption) - .buttonStyle(.plain) - .foregroundStyle(.tint) - } else if let url = linkURL(field.url) { - Link(field.value, destination: url).font(.caption) - } else { - Text(field.value).font(field.isMonospaced ? .caption.monospaced() : .caption) - .foregroundStyle(isError ? Color.red : .primary) + if !field.value.isEmpty { + if let navigation = field.navigation, let navigate { + Button(field.value) { navigate(navigation) } + .font(field.isMonospaced ? .caption.monospaced() : .caption) + .buttonStyle(.plain) + .foregroundStyle(.tint) + } else if let url = linkURL(field.url) { + Link(field.value, destination: url).font(.caption) + } else { + Text(field.value).font(field.isMonospaced ? .caption.monospaced() : .caption) + .foregroundStyle(isError ? Color.red : .primary) + } } } case .message(let text, let tint): Text(text).foregroundStyle(color(tint)) diff --git a/Frameworks/TermindPresentation/SSHExecToolPresentation.swift b/Frameworks/TermindPresentation/SSHExecToolPresentation.swift index 8ddf2b4f..f1baf6a6 100644 --- a/Frameworks/TermindPresentation/SSHExecToolPresentation.swift +++ b/Frameworks/TermindPresentation/SSHExecToolPresentation.swift @@ -22,7 +22,7 @@ nonisolated enum SSHExecToolPresentation { } typealias S = AppStrings.SSHExec func text(_ resource: LocalizedStringResource) -> String { AppLocalization.resolve(resource, locale: locale) } - func field(_ title: LocalizedStringResource, _ value: String, mono: Bool = false) -> AgentToolDetail.Item { + func field(_ title: LocalizedStringResource, _ value: String = "", mono: Bool = false) -> AgentToolDetail.Item { .field(.init(label: text(title), value: value, isMonospaced: mono)) } func block(_ title: LocalizedStringResource, _ value: String) -> AgentToolDetail.Item { @@ -49,8 +49,7 @@ nonisolated enum SSHExecToolPresentation { var items: [AgentToolDetail.Item] = [] if let command = args["command"]?.stringValue { items.append(block(S.command, command)) } if card.descriptor.name == "ssh_exec_run" { - items.append( - .message(text(args["run_in_background"]?.boolValue == true ? S.background : S.foreground), .secondary)) + items.append(field(args["run_in_background"]?.boolValue == true ? S.background : S.foreground)) } if let handle = object["handle"]?.stringValue ?? args["handle"]?.stringValue { items.append(field(S.handle, handle, mono: true)) @@ -64,7 +63,7 @@ nonisolated enum SSHExecToolPresentation { } if let count = object["bytes_written"]?.integerValue { items.append(field(S.bytes, String(count), mono: true)) } if let closed = object["stdin_closed"]?.boolValue { - items.append(.message(text(closed ? S.stdinClosed : S.stdinOpen), .secondary)) + items.append(field(closed ? S.stdinClosed : S.stdinOpen)) } if let error = object["error"]?.stringValue { items.append(.message(error, .failure)) } if object["remote_termination_confirmed"]?.boolValue == false { @@ -77,7 +76,7 @@ nonisolated enum SSHExecToolPresentation { if ["ssh_exec", "ssh_wait", "ssh_exec_run", "ssh_exec_output"].contains(card.descriptor.name), stdout.isEmpty, stderr.isEmpty { - items.append(.message(text(card.result == nil ? S.pending : S.noOutput), .secondary)) + items.append(card.result == nil ? .message(text(S.pending), .secondary) : field(S.noOutput)) } if let note = object["note"]?.stringValue { items.append(.message(note, .warning)) } return .init(items: items) diff --git a/TFM/Features/AI/TranscriptNativeRows.swift b/TFM/Features/AI/TranscriptNativeRows.swift index f46c10a8..6f912bcf 100644 --- a/TFM/Features/AI/TranscriptNativeRows.swift +++ b/TFM/Features/AI/TranscriptNativeRows.swift @@ -1410,6 +1410,7 @@ private enum NativeTranscriptFactory { font: .systemFont(ofSize: NSFont.smallSystemFontSize, weight: .medium), color: .secondaryLabelColor ) + if field.value.isEmpty { return key } key.widthAnchor.constraint(greaterThanOrEqualToConstant: 76).isActive = true row.addArrangedSubview(key) let font: NSFont =