Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
d146087
feat(desktop): notch silhouette shape with independently animatable c…
katipally Jul 21, 2026
5708a9b
feat(desktop): notch geometry metrics, springs, and pure closed-size …
katipally Jul 21, 2026
a7f51f5
feat(desktop): presentation ladder - one value drives both size and c…
katipally Jul 21, 2026
35bf734
feat(desktop): per-display notch view model with dynamic chat height
katipally Jul 21, 2026
25eb3ae
feat(desktop): notch panel window with gated keyboard capture
katipally Jul 21, 2026
9af0deb
refactor(desktop): extract the omi dot-ring mark for shared chrome
katipally Jul 21, 2026
0f6326d
feat(desktop): main-window reveal helper keyed off the window-key signal
katipally Jul 21, 2026
a7c9b81
feat(desktop): chat tab renders the shared timeline with measured height
katipally Jul 21, 2026
0903fe2
feat(desktop): floating capsule composer - attach, send, stop, live w…
katipally Jul 21, 2026
fc8b21b
feat(desktop): agents tab with drill-in over AgentPillsManager
katipally Jul 21, 2026
bad3a5c
feat(desktop): proactive notification card ported to the notch body
katipally Jul 21, 2026
a3dc0cf
feat(desktop): root notch view - stable island layer, two animation t…
katipally Jul 21, 2026
bd608e0
feat(desktop): per-display screen manager with menu-aim auto-close
katipally Jul 21, 2026
ecab275
feat(desktop): cut the manager over to the notch stack
katipally Jul 21, 2026
f1cbbd2
feat(desktop): live voice-turn mirror and notch hints
katipally Jul 21, 2026
3a10e30
test(desktop): adapt agent lifecycle tripwires to the notch architecture
katipally Jul 21, 2026
fc4b5aa
test(desktop): cover notch sources in the floating-bar functional flow
katipally Jul 21, 2026
d2e14e4
chore(desktop): changelog fragment for the notch rework
katipally Jul 21, 2026
8bfaca0
chore: ratchet floating-bar line-count baselines down for the rework
katipally Jul 21, 2026
b2533c9
fix(desktop): clear the sent chat draft synchronously so it can't res…
katipally Jul 21, 2026
bce426f
feat(desktop): empty the notch composer on send and add a mic stop co…
katipally Jul 21, 2026
a87187d
feat(desktop): show the live voice partial in the notch listening pill
katipally Jul 21, 2026
c442ca1
fix(desktop): make the whole agent spawn card open the agent
katipally Jul 21, 2026
4f44a22
test(desktop): add send_main_draft bridge action for the composer sen…
katipally Jul 21, 2026
b20aa36
fix(desktop): respect persisted floating-bar state when the notch lau…
katipally Jul 22, 2026
f76ebe5
fix(desktop): port Ask Omi close off the dead floating window and dro…
katipally Jul 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"files": {
"desktop/macos/Desktop/Sources/FloatingControlBar/AgentPill.swift": 2375,
"desktop/macos/Desktop/Sources/FloatingControlBar/FloatingControlBarView.swift": 2853,
"desktop/macos/Desktop/Sources/FloatingControlBar/FloatingControlBarWindow.swift": 4842,
"desktop/macos/Desktop/Sources/FloatingControlBar/FloatingControlBarView.swift": 2818,
"desktop/macos/Desktop/Sources/FloatingControlBar/FloatingControlBarWindow.swift": 4515,
"desktop/macos/Desktop/Sources/FloatingControlBar/PushToTalkManager.swift": 2423,
"desktop/macos/Desktop/Sources/FloatingControlBar/RealtimeHubSession.swift": 1621
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
"files": {
"desktop/macos/Desktop/Sources/MainWindow/Components/ChatBubble.swift": 1926,
"desktop/macos/Desktop/Sources/MainWindow/Components/ChatBubble.swift": 1930,
"desktop/macos/Desktop/Sources/MainWindow/Pages/AppsPage.swift": 3643,
"desktop/macos/Desktop/Sources/MainWindow/Pages/DashboardPage.swift": 4543,
"desktop/macos/Desktop/Sources/MainWindow/Pages/MemoriesPage.swift": 3298,
"desktop/macos/Desktop/Sources/MainWindow/Pages/TasksPage.swift": 5518,
"desktop/macos/Desktop/Sources/MainWindow/SidebarView.swift": 1570
},
"raise_justifications": {
"desktop/macos/Desktop/Sources/MainWindow/Components/ChatBubble.swift": "Keeps all chat tool groups compact and collapsed while streamed steps increment, with an explicit expansion policy, fixed collapsed height, and regression coverage.",
"desktop/macos/Desktop/Sources/MainWindow/Components/ChatBubble.swift": "The whole agent spawn card now opens the agent (card-level tap plus the corner affordance) so a delegated task is reachable from every surface that renders it; +4 lines.",
"desktop/macos/Desktop/Sources/MainWindow/Pages/AppsPage.swift": "Rebase reconciliation applies the pinned swift-format to the main-branch app-detail safety fixes; runtime behavior is unchanged.",
"desktop/macos/Desktop/Sources/MainWindow/Pages/DashboardPage.swift": "Home redesign: chat-as-home surface plus the 2nd-brain knows-list hub replace the wordmark/ribbon/WMN-card layout; a component split is tracked follow-up.",
"desktop/macos/Desktop/Sources/MainWindow/Pages/MemoriesPage.swift": "Bridge memory search now awaits the active initial or pagination projection before refreshing, preventing an immediate post-navigation marker search from using stale lifecycle capability state.",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"files": {
"desktop/macos/Desktop/Sources/Providers/ChatProvider.swift": 6214,
"desktop/macos/Desktop/Sources/Providers/ChatProvider.swift": 6218,
"desktop/macos/Desktop/Sources/Providers/ChatToolExecutor.swift": 2861
},
"raise_justifications": {
"desktop/macos/Desktop/Sources/Providers/ChatProvider.swift": "ChatTurnOwner reasoning-effort lane derivation",
"desktop/macos/Desktop/Sources/Providers/ChatProvider.swift": "sendMainDraft clears the sent draft up front and restores it only if the send never lands, so the notch composer can't retain or resurface the sent text; +4 lines.",
"desktop/macos/Desktop/Sources/Providers/ChatToolExecutor.swift": "Already-granted permissions no longer reopen System Settings: screen-recording and full-disk-access requests gate their Settings/drag-card opens behind the granted result."
},
"threshold": 1500
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
"files": {
"desktop/macos/Desktop/Sources/AuthService.swift": 3294,
"desktop/macos/Desktop/Sources/CloudConnectorFormAutomation.swift": 1678,
"desktop/macos/Desktop/Sources/DesktopAutomationBridge.swift": 4238,
"desktop/macos/Desktop/Sources/DesktopAutomationBridge.swift": 4264,
"desktop/macos/Desktop/Sources/MemoryExportService.swift": 1578,
"desktop/macos/Desktop/Sources/OmiApp.swift": 1638
},
"raise_justifications": {
"desktop/macos/Desktop/Sources/AuthService.swift": "Apple first-auth name capture signals observers (authNameDidUpdate) and persists the name to Firebase so it survives reinstalls.",
"desktop/macos/Desktop/Sources/DesktopAutomationBridge.swift": "Reach-error card gains a debug bridge action so the actionable failure surface is verifiable in-process.",
"desktop/macos/Desktop/Sources/DesktopAutomationBridge.swift": "Adds a non-prod send_main_draft action that drives the composer's sendMainDraft path so the draft clear/restore behavior is verifiable end to end; +26 lines.",
"desktop/macos/Desktop/Sources/MemoryExportService.swift": "Pinned swift-format normalizes line layout without changing this source's runtime behavior.",
"desktop/macos/Desktop/Sources/OmiApp.swift": "shared openMainAppWindow helper for menu bar + Open Omi shortcut"
},
Expand Down
26 changes: 26 additions & 0 deletions desktop/macos/Desktop/Sources/DesktopAutomationBridge.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1821,6 +1821,32 @@ final class DesktopAutomationActionRegistry {
]
}

register(
name: "send_main_draft",
summary: "Send the main composer via the draft path (sendMainDraft), exactly like the notch/main text composer",
params: ["text"],
category: "chat",
surfaces: ["main_chat", "ask_omi"],
safety: "local",
sideEffects: ["local_storage", "network"],
examples: ["./scripts/omi-ctl action send_main_draft text='what did I do today?'"]
) { params in
guard AppBuild.isNonProduction else {
return ["error": "send_main_draft is disabled on production bundles"]
}
let text = (params["text"] ?? "").trimmingCharacters(in: .whitespacesAndNewlines)
guard !text.isEmpty else { return ["error": "missing 'text'"] }
guard let provider = ChatProvider.mainInstance else {
return ["error": "main ChatProvider not yet initialized"]
}
provider.draftText = text
let tracer = QueryTracer(query: text, inputMode: .text)
await QueryTracerContext.$current.withValue(tracer) {
_ = await provider.sendMainDraft(text)
}
return ["sent": text, "draft_after": provider.draftText]
}

register(
name: "chat_drafts_snapshot",
summary: "Read current main and floating composer drafts (non-prod persistence harness)",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -265,20 +265,12 @@ class FloatingControlBarState: NSObject, ObservableObject {

func apply(_ projection: VoiceTurnUIProjection) {
guard let barState else { return }
let wasExpandedForVoice = barState.isVoiceListening
barState.applyVoiceProjection(projection)
let shouldExpandForVoice = barState.isVoiceListening

// Clear idle hover before the PTT resize so its animated surface cannot
// compete with the reducer-owned voice presentation.
// Clear idle hover so its animated surface cannot compete with the
// reducer-owned voice presentation. Notch PTT sizing is owned by the
// presentation ladder off applyVoiceProjection above.
barState.dismissNotchHoverForVoicePresentation()

if shouldExpandForVoice != wasExpandedForVoice,
!barState.showingAIConversation,
UserDefaults.standard.bool(forKey: .hasCompletedOnboarding)
{
FloatingControlBarManager.shared.resizeForPTT(expanded: shouldExpandForVoice)
}
}
}

Expand Down Expand Up @@ -381,10 +373,50 @@ class FloatingControlBarState: NSObject, ObservableObject {
/// True only when the notch-mode setting is enabled and the current display
/// exposes a real camera housing safe area. External displays keep old pill UI.
@Published var usesNotchIsland: Bool = false

/// Live voice-turn mirror for the notch chat. Hub voice turns journal the
/// exchange only at turn end, so mid-turn the provider timeline has nothing
/// to render; these carry the in-flight transcript and streaming assistant
/// text purely for display (never a second transcript store — the journaled
/// pair replaces them when it lands).
@Published var liveVoiceUserText: String = ""
@Published var liveVoiceAssistantText: String = ""

/// One-shot notch hint outside the voice projection (e.g. PTT blocked by
/// the usage limit). The notch's hint presentation falls back to this when
/// the projection-derived hint is empty.
@Published var transientHintText: String = ""
private var transientHintClearTask: Task<Void, Never>?

func flashHint(_ text: String, for seconds: TimeInterval = 3) {
transientHintText = text
transientHintClearTask?.cancel()
transientHintClearTask = Task { [weak self] in
try? await Task.sleep(for: .seconds(seconds))
guard !Task.isCancelled else { return }
self?.transientHintText = ""
}
}
@Published var notchRevealProgress: CGFloat = 1

private func applyVoiceProjection(_ projection: VoiceTurnUIProjection) {
// A new hold is a new turn: drop the previous turn's streamed reply so it
// can't flash under the fresh question.
if projection.isListening, !voiceProjection.isListening {
liveVoiceAssistantText = ""
liveVoiceUserText = ""
}
voiceProjection = projection
// Mirror the in-flight transcript for the notch chat's live strip; clear
// the whole mirror once the voice presentation fully ends (by then the
// journaled exchange has landed on the shared timeline).
if !projection.transcript.isEmpty {
liveVoiceUserText = projection.transcript
}
if !isVoicePresentationActive {
liveVoiceUserText = ""
liveVoiceAssistantText = ""
}
}

/// Whether the current query originated from voice (PTT). Used to decide
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1854,41 +1854,6 @@ private struct NotchResponseGlowView: View {
}
}

private struct NotchOmiMark: View {
var dotColors: [Color] = []

private static let dotCount = 8
private static let dotDiameterRatio: CGFloat = 0.18
private static let ringRadiusRatio: CGFloat = 0.33

var body: some View {
GeometryReader { geometry in
let size = min(geometry.size.width, geometry.size.height)
let center = CGPoint(
x: geometry.size.width / 2,
y: geometry.size.height / 2
)
let dotDiameter = size * Self.dotDiameterRatio
let ringRadius = size * Self.ringRadiusRatio

ZStack {
ForEach(0..<Self.dotCount, id: \.self) { index in
let angle = Double(index) / Double(Self.dotCount) * Double.pi * 2 - Double.pi
Circle()
.fill(dotColors.indices.contains(index) ? dotColors[index] : Color.white.opacity(0.96))
.frame(width: dotDiameter, height: dotDiameter)
.position(
x: center.x + CGFloat(cos(angle)) * ringRadius,
y: center.y + CGFloat(sin(angle)) * ringRadius
)
}
}
}
.drawingGroup(opaque: false, colorMode: .linear)
.accessibilityHidden(true)
}
}

/// The Omi mark rendered as a spinning "thinking" indicator. The ring's dots
/// carry a brightness trail (bright head → faint tail) so the continuous
/// rotation reads as a sweeping comet rather than a static ring of dots.
Expand Down
Loading