nvrsion: Add: Reconnect Icon Update, fix mesh iPhone discovery for new Macs, fix session order adjustment to pin sidebar sessions for remote projects, fix session status synchronization for remote viewer Macs, fix session order adjustment for iOS app session list, fix session status synchronization for remote sessions, fix iOS app live activity height by removing the “<n> files changed” line, fix Tool Call Card Mesh so AI bash summaries transit the mesh layer to other Macs, replace “Resolved by mac-ui” in transcripts with device ID, fix Chat: Print Wait Message, fix Chat: Reconnect Icon Update, fix Chat: Activity Theme Adjustment for “attention needed” live activity theme.

Nucleic-Promote: 1
Co-authored-by: Nucleic <[email protected]>
This commit is contained in:
2026-07-05 04:24:25 -07:00
co-authored by Nucleic
parent c9cffa55ca
commit 5168198656
9 changed files with 83 additions and 53 deletions
@@ -14,7 +14,11 @@ struct SessionLiveActivity: Widget {
ActivityConfiguration(for: NucleicSessionAttributes.self) { context in
LockScreenView(state: context.state, hostName: context.attributes.hostName)
.widgetURL(context.state.tapURL)
.activityBackgroundTint(Color.black.opacity(0.55))
// When something needs the user, wash the whole card in the attention tint;
// otherwise the calm dark background (see the border/header cues in LockScreenView).
.activityBackgroundTint(context.state.needsAttention
? ActivityPalette.attentionTint(context.state).opacity(0.28)
: Color.black.opacity(0.55))
.activitySystemActionForegroundColor(.white)
} dynamicIsland: { context in
let state = context.state
@@ -43,9 +47,6 @@ struct SessionLiveActivity: Widget {
ForEach(state.lines.prefix(2)) { line in
SessionRow(line: line)
}
if state.hasChurn {
ChurnLine(state: state).padding(.top, 1)
}
}
}
} compactLeading: {
@@ -77,12 +78,17 @@ private struct LockScreenView: View {
let hostName: String
var body: some View {
VStack(alignment: .leading, spacing: 8) {
// Header: brand + host, and the headline counts.
let attention = state.needsAttention
let tint = ActivityPalette.attentionTint(state)
return VStack(alignment: .leading, spacing: 8) {
// Header: brand + host, and the headline counts. When the user is needed the brand
// mark becomes the attention glyph in its tint, so the header itself reads "act now".
HStack(spacing: 8) {
Image(systemName: "hexagon.fill")
Image(systemName: attention
? ActivityPalette.glyph(state.approvalCount > 0 ? .approval : .needsInput)
: "hexagon.fill")
.font(.footnote)
.foregroundStyle(ActivityPalette.active)
.foregroundStyle(attention ? tint : ActivityPalette.active)
Text(hostName)
.font(.caption.weight(.semibold))
.lineLimit(1)
@@ -94,15 +100,23 @@ private struct LockScreenView: View {
ForEach(state.lines.prefix(3)) { line in
SessionRow(line: line)
}
// Aggregate churn footer — how much work is in flight right now.
if state.hasChurn {
Divider().overlay(Color.white.opacity(0.12))
ChurnLine(state: state)
}
}
.padding(14)
.foregroundStyle(.white)
// Attention theme: a soft tinted wash + a colored border around the whole glance, so a
// session waiting on the user is unmistakable at a glance even before reading the rows.
.background {
if attention {
RoundedRectangle(cornerRadius: 22, style: .continuous)
.fill(tint.opacity(0.12))
}
}
.overlay {
if attention {
RoundedRectangle(cornerRadius: 22, style: .continuous)
.strokeBorder(tint.opacity(0.9), lineWidth: 2)
}
}
}
}
@@ -182,28 +196,6 @@ private struct CountChips: View {
}
}
/// Aggregate worktree churn: "N files +A −R".
private struct ChurnLine: View {
let state: NucleicSessionAttributes.ContentState
var body: some View {
HStack(spacing: 6) {
Image(systemName: "chevron.left.forwardslash.chevron.right")
.font(.caption2)
.foregroundStyle(.secondary)
Text("\(state.filesChanged) file\(state.filesChanged == 1 ? "" : "s") changed")
.foregroundStyle(.secondary)
Text("+\(state.linesAdded)")
.foregroundStyle(ActivityPalette.added)
Text("−\(state.linesRemoved)")
.foregroundStyle(ActivityPalette.removed)
}
.font(.caption2.weight(.medium))
.monospacedDigit()
.lineLimit(1)
}
}
/// Dynamic Island expanded leading/trailing count badge.
private struct CountBadge: View {
let systemImage: String
@@ -231,6 +223,12 @@ private enum ActivityPalette {
static let added = Color(red: 0.30, green: 0.78, blue: 0.45)
static let removed = Color(red: 0.92, green: 0.34, blue: 0.34)
/// The color the "attention needed" theme paints with: approval amber is loudest, else the
/// needs-input teal. Only meaningful when `state.needsAttention` — callers gate on that.
static func attentionTint(_ state: NucleicSessionAttributes.ContentState) -> Color {
state.approvalCount > 0 ? attention : accent
}
static func glyph(_ kind: NucleicSessionAttributes.Kind) -> String {
switch kind {
case .running: "circle.lefthalf.filled"