Skip to content

fix: launcher UI and AI suggestion improvements#240

Merged
yonaries merged 21 commits intomainfrom
fix/launcher
Mar 15, 2026
Merged

fix: launcher UI and AI suggestion improvements#240
yonaries merged 21 commits intomainfrom
fix/launcher

Conversation

@yonaries
Copy link
Copy Markdown
Contributor

Summary

  • Improve AI query detection with proper heuristics (question words, imperative phrases, word count) replacing broken regex patterns
  • Hide duplicate URL display in launcher suggestions when title already shows the URL
  • Use ConditionallyConcentricRectangle for macOS 26+ concentric corner support
  • Remove input/suggestions divider, darken dark mode background, bump corner radii
  • Reduce home view watermark opacity

yonaries and others added 21 commits March 15, 2026 00:26
Move LauncherMain.Match → LauncherMatch, LauncherSuggestionType/LauncherSuggestion
into dedicated model files. Extract search/suggestion business logic into
LauncherViewModel, making LauncherMain a pure view (~114 lines). Consolidate
MoveDirection and LauncherMouseHasMovedKey into LauncherEnvironment.swift.
Remove duplicate SearchEngineService, unused toolbarManager EnvironmentObject,
dead SuggestionFocus enum, and commented-out code. No behavior changes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Recognize localhost as a valid host in isValidURL
- Use http:// scheme for localhost in constructURL (devs typically use HTTP)
- Require both scheme and host in appendOpenURLSuggestionIfNeeded so
  localhost:3000 (parsed as scheme=localhost, host=nil) falls through to
  constructURL instead of being used as-is
- Fix 192.168.1.1:8080 which URL(string:) returns nil for, now falls
  through to isValidURL → constructURL correctly

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…eSite

self.url is non-optional, so failedURL ?? self.url always produces URL.
Use let instead of guard let to fix the build error.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The SVG is the referenced asset; the PNG was orphaned and causing
an Xcode "unassigned child" warning.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Same pattern as the launcher fix — track first mouse movement with
NSEvent monitor so keyboard-driven focus isn't hijacked by the
cursor's resting position when the switcher appears.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add SSL bypass support in BrowserPage with per-host tracking
- Handle URLAuthenticationChallenge to accept bypassed hosts
- Add onContinueAnyway callback to StatusPageView for security errors
- Add labelColorOverride to OraButton for muted ghost button styling
- Wire continueToInsecureSite through BrowserWebContentView

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace broken regex patterns (checked via .contains instead of regex
evaluation) with proper heuristic layers: question prefixes, question
marks, imperative phrases, action keywords, and a word count threshold.
Add negative signals to skip single words and valid URLs.
Skip showing the em-dash URL suffix when the suggestion title is
already the URL itself. History items with distinct page titles
still display their URL.
Replace RoundedRectangle and .cornerRadius with
ConditionallyConcentricRectangle and .clipShape for concentric
corner support on macOS 26+. Bump radii slightly (container 16→20,
badges 6→8, suggestion rows 8→10).
@yonaries yonaries requested a review from kenenisa as a code owner March 15, 2026 19:58
@tembo tembo bot added bug Something isn't working enhancement improvements labels Mar 15, 2026
@greptile-apps
Copy link
Copy Markdown

greptile-apps bot commented Mar 15, 2026

Greptile Summary

This PR delivers a significant refactor of the launcher UI alongside several functional improvements. The launcher's business logic is extracted from views into a dedicated LauncherViewModel, models are split into their own files (LauncherMatch, LauncherSuggestion), and the AI query detection heuristic is rewritten with proper word/phrase matching replacing broken regex patterns. UI polish includes concentric corner support via ConditionallyConcentricRectangle, capsule logo assets for all search engines, duplicate URL hiding in suggestions, mouse-movement gating to prevent hover from stealing keyboard focus, and various opacity/radius tweaks. A new SSL bypass feature adds a "Continue Anyway" button on security error pages, along with localhost URL support in the utility layer.

  • Launcher refactor: Logic moved from LauncherMain into LauncherViewModel; models extracted into separate files; force-unwraps replaced with safe optional binding
  • AI query detection rewrite: New heuristic checks question prefixes, question marks, imperative phrases, action keywords, and word count — but substring matching on action keywords can produce false positives (e.g., "history" matching "story")
  • SSL bypass: BrowserPage now maintains a sslBypassedHosts set and a "Continue Anyway" button appears on security errors — however the bypass persists for the page's lifetime with no cleanup
  • UI polish: ConditionallyConcentricRectangle adoption, capsule logo assets for search engines, mouse-movement tracking to prevent hover interference, increased corner radii, reduced watermark opacity
  • Localhost support: isValidURL and constructURL now recognize localhost and default to http:// scheme

Confidence Score: 3/5

  • The PR is mostly safe but the SSL bypass mechanism needs attention before merging due to security implications.
  • The launcher refactor and UI changes are clean and well-structured. However, two issues lower confidence: (1) the SSL bypass via sslBypassedHosts persists indefinitely per BrowserPage with no cleanup mechanism, meaning a single user click silently disables SSL validation for a host for all future navigations on that page, and (2) the AI query detection uses substring matching that will produce false positives on common search terms.
  • ora/Core/BrowserEngine/BrowserPage.swift (persistent SSL bypass), ora/Features/Launcher/State/LauncherViewModel.swift (AI query false positives), ora/Features/Tabs/Models/Tab.swift (SSL bypass entry point)

Important Files Changed

Filename Overview
ora/Core/BrowserEngine/BrowserPage.swift Adds SSL bypass mechanism (sslBypassedHosts) that persists for the lifetime of BrowserPage with no cleanup, posing a security concern.
ora/Features/Launcher/State/LauncherViewModel.swift New ViewModel extracts launcher logic from views. AI query detection uses substring matching with contains() which causes false positives on common words.
ora/Features/Tabs/Models/Tab.swift Adds continueToInsecureSite() that bypasses SSL for the host and reloads; works with the new SSL bypass in BrowserPage.
ora/Features/Browser/Views/StatusPageView.swift Adds "Continue Anyway" button for security errors, correctly gated behind errorType == .security check.
ora/Features/Browser/Views/BrowserWebContentView.swift Passes onContinueAnyway closure unconditionally to StatusPageView for all error types, though only used for security errors.
ora/Core/Utilities/Utils.swift Adds localhost support with correct http:// scheme defaulting; clean and correct implementation.
ora/Features/Launcher/LauncherView.swift Refactored to use LauncherViewModel, adds mouse movement tracking to prevent hover from stealing keyboard focus on launch.
ora/Features/Launcher/Main/LauncherMain.swift Major cleanup extracting logic to LauncherViewModel and models; force-unwrap replaced with safe optional binding.
ora/Features/Launcher/Suggestions/LauncherSuggestionItem.swift Simplified styling, added URL deduplication logic, uses mouseHasMoved environment to prevent accidental hover selection.
ora/Features/Search/Services/SearchEngineService.swift Added capsule logo icon references for all built-in search engines; updated method signature to use LauncherMatch.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[User types in Launcher] --> B{Input empty?}
    B -->|Yes| C[Show default suggestions]
    B -->|No| D[LauncherViewModel.searchHandler]
    D --> E[Search open tabs]
    D --> F[Check if valid URL]
    D --> G[Append default engine suggestion]
    D --> H[Request auto-suggestions via debouncer]
    D --> I[Search history]
    D --> J{isAISuitableQuery?}
    J -->|Yes| K[Append AI chat suggestions]
    J -->|No| L[Skip AI suggestions]
    
    M[Navigation Error] --> N{Error type?}
    N -->|Security| O[Show Continue Anyway button]
    N -->|Other| P[Show Retry / Go Back]
    O --> Q[Tab.continueToInsecureSite]
    Q --> R[BrowserPage.bypassSSL for host]
    R --> S[Host added to sslBypassedHosts permanently]
    S --> T[Reload page with SSL bypass]
Loading

Last reviewed commit: 0f576e6

@yonaries yonaries merged commit d900b10 into main Mar 15, 2026
3 checks passed
@yonaries yonaries deleted the fix/launcher branch March 15, 2026 20:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working enhancement improvements

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant