Add Markdown Formatting

Nucleic-Session: 23936B4B-52E9-43F5-908B-C7919A5BD6DD
Co-authored-by: Nucleic <[email protected]>
This commit is contained in:
2026-06-27 20:18:30 -07:00
co-authored by Nucleic
parent 4f3945dd9c
commit 57a8cc698e
@@ -106,14 +106,72 @@ struct HostCommandBreakdown: View {
if let dir = summary.workingDirectory {
detailRow(icon: "folder", lines: ["in \(dir)"])
}
ForEach(Array(summary.invocations.enumerated()), id: \.element.id) { index, inv in
if index > 0 { Divider().overlay(Color.primary.opacity(0.08)) }
invocationView(inv)
}
steps
}
.frame(maxWidth: .infinity, alignment: .leading)
}
/// At most this many steps render in the compact chain list before the rest fold into a
/// "+N more" tail — so a long `cmd1 && cmd2 && …` pipeline can't grow the card unbounded
/// (the exact command shown alongside is always the complete source of truth).
private static let maxVisibleSteps = 7
/// The invocations, rendered to fit the chain length: a lone command gets the full block
/// (program + actions + every env/flag/operand spelled out); a *chain* collapses to one
/// compact line per command so a long pipeline stays short, not a tall stack of blocks.
@ViewBuilder private var steps: some View {
if summary.invocations.count <= 1 {
if let only = summary.invocations.first { invocationView(only) }
} else {
VStack(alignment: .leading, spacing: 6) {
ForEach(Array(summary.invocations.prefix(Self.maxVisibleSteps))) { inv in
stepRow(inv)
}
let hidden = summary.invocations.count - Self.maxVisibleSteps
if hidden > 0 {
Text("+\(hidden) more step\(hidden == 1 ? "" : "s")")
.font(.caption2).foregroundStyle(.tertiary)
.padding(.leading, 22)
}
}
}
}
/// One command in a chain, compacted to a single line: a step glyph, the program + actions
/// emphasized, then a truncated tail of its env/flags/operands. A destructive/elevated step is
/// tinted and glyphed in the danger color so it still stands out.
private func stepRow(_ inv: HostCommandSummary.Invocation) -> some View {
let risky = inv.destructive || inv.elevated
let tail = stepTail(inv)
return HStack(alignment: .firstTextBaseline, spacing: 8) {
Image(systemName: stepGlyph(inv))
.font(.caption2).foregroundStyle(risky ? Palette.danger : accent).frame(width: 14)
(Text(inv.headline)
.font(.caption.monospaced().weight(.semibold))
.foregroundColor(.primary)
+ Text(tail.isEmpty ? "" : " " + tail)
.font(.caption.monospaced())
.foregroundColor(.secondary))
.lineLimit(1).truncationMode(.middle)
.textSelection(.enabled)
Spacer(minLength: 0)
}
}
/// The trailing detail of a compacted step — its env, flags, and operands joined on one line,
/// truncated by the row. The literal command carries the untruncated form.
private func stepTail(_ inv: HostCommandSummary.Invocation) -> String {
(inv.env.map(\.display) + inv.flags.map(\.display) + inv.arguments).joined(separator: " ")
}
/// The leading glyph for a compacted step: a delete/elevation marker takes priority so the
/// risky step is unmistakable; otherwise a plain terminal glyph.
private func stepGlyph(_ inv: HostCommandSummary.Invocation) -> String {
if inv.destructive { return "trash" }
if inv.elevated { return "lock.shield" }
return "terminal"
}
/// The deterministic, command-derived purpose — labeled so the user knows it's *Nucleic's*
/// reading of the command, not the agent's claim about it.
private var purposeRow: some View {