Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 0 additions & 4 deletions Cotabby.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,6 @@
AB9C9C001F97F9D14F8B192A /* TerminalAppDetector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F4C4A7EAF886E0CC945BFEF /* TerminalAppDetector.swift */; };
AECC7289DA796B071B4FE3C0 /* MenuBarStatusLabelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD42C7E2852F59BEF7972663 /* MenuBarStatusLabelView.swift */; };
B00FDD3DEE0B73FF5136C91C /* FocusTracker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C9FDF029F7828CAF3FE8850 /* FocusTracker.swift */; };
B0828FF0D7EE110C0B23DB94 /* TagsInputView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58C0F017699EE44C81C095CA /* TagsInputView.swift */; };
B0B115C6EBAC37FF6115B4BE /* SuggestionCoordinator+Lifecycle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78E280F4F39A9D86840800D2 /* SuggestionCoordinator+Lifecycle.swift */; };
B2F7589B8D32ACF97BB642AB /* HuggingFaceModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = A520809E71697E3BB9A8139C /* HuggingFaceModels.swift */; };
B6652D81162C64248AA4CF0B /* EmojiPickerPanelController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 764659D09C3F0E8FBD267102 /* EmojiPickerPanelController.swift */; };
Expand Down Expand Up @@ -344,7 +343,6 @@
54EF3C7F5D9D6F3FA50FD51C /* ContextBuffer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContextBuffer.swift; sourceTree = "<group>"; };
5664E34B23FBDF69292FEF43 /* FoundationModelSuggestionEngine.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FoundationModelSuggestionEngine.swift; sourceTree = "<group>"; };
5807E8508D9355D0271A00C5 /* LaunchAtLoginStateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LaunchAtLoginStateTests.swift; sourceTree = "<group>"; };
58C0F017699EE44C81C095CA /* TagsInputView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TagsInputView.swift; sourceTree = "<group>"; };
5976600F428C1265121D4C0C /* SystemSettingsWindowLocator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SystemSettingsWindowLocator.swift; sourceTree = "<group>"; };
59E299BE2E9D42A33D5D2F5D /* ScreenTextExtractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenTextExtractor.swift; sourceTree = "<group>"; };
5A03E565A11581FD2150B142 /* CompletionRenderMode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompletionRenderMode.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -830,7 +828,6 @@
656F58E56FE9BC087B6F1D33 /* PermissionReminderView.swift */,
5484C8A04B9C00CF79D589EB /* ScreenFrameReader.swift */,
FB317C82CE2CBC69056BA4B8 /* TagChip.swift */,
58C0F017699EE44C81C095CA /* TagsInputView.swift */,
67586807ACE8EB13C9014535 /* TickMarkSlider.swift */,
D5D6C2318E405AA717D1C256 /* WelcomePermissionStepView.swift */,
A9199B9CEAB320982CA333B8 /* WelcomeTemplateStepView.swift */,
Expand Down Expand Up @@ -1224,7 +1221,6 @@
E313639E71AE1374D2B9A956 /* SuggestionWorkController.swift in Sources */,
258EAFB0292290C88520E915 /* SystemSettingsWindowLocator.swift in Sources */,
90CD3F7238E223DEBA2B4D92 /* TagChip.swift in Sources */,
B0828FF0D7EE110C0B23DB94 /* TagsInputView.swift in Sources */,
AB9C9C001F97F9D14F8B192A /* TerminalAppDetector.swift in Sources */,
96782E57CA26A16409368B69 /* TextDirectionDetector.swift in Sources */,
6014B31E2570EFFE45557E33 /* TickMarkSlider.swift in Sources */,
Expand Down
26 changes: 0 additions & 26 deletions Cotabby/Models/FocusModels.swift
Original file line number Diff line number Diff line change
Expand Up @@ -103,26 +103,6 @@ struct FocusInspectionSnapshot: Equatable {
let resolvedRole: String?
let resolvedSubrole: String?
let missingCapabilities: [FocusCapabilityRequirement]

var focusedRoleSummary: String {
"\(focusedRole) / \(focusedSubrole ?? "n/a")"
}

var resolvedRoleSummary: String {
guard let resolvedRole else {
return "Unavailable"
}

return "\(resolvedRole) / \(resolvedSubrole ?? "n/a")"
}

var missingCapabilitySummary: String {
guard !missingCapabilities.isEmpty else {
return "None"
}

return missingCapabilities.map(\.summary).joined(separator: ", ")
}
}

/// This snapshot is the future handoff point into suggestion generation.
Expand Down Expand Up @@ -221,12 +201,6 @@ struct FocusedInputSnapshot: Equatable {
isSecure ? "secure" : "plain"
].joined(separator: "::")
}

var textPreview: String {
let prefix = String(precedingText.suffix(32))
let suffix = String(trailingText.prefix(32))
return "\(prefix)|\(suffix)"
}
}

/// Top-level focus state that the menu can render directly.
Expand Down
16 changes: 0 additions & 16 deletions Cotabby/Models/FocusTrackingModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,22 +74,6 @@ final class FocusTrackingModel: ObservableObject {
tracker.updatePollInterval(TimeInterval(milliseconds) / 1000.0)
}

/// The menu bar needs a compact status string, not the full diagnostic reason.
var menuBarStatusText: String {
snapshot.capability.shortLabel
}

var menuBarSymbolName: String {
switch snapshot.capability {
case .supported:
return "checkmark.circle"
case .blocked:
return "hand.raised.circle"
case .unsupported:
return "xmark.circle"
}
}

private func updateLatestExternalApplication(from snapshot: FocusSnapshot) {
guard let application = snapshot.externalApplicationIdentity(
ignoredBundleIdentifier: ignoredBundleIdentifier
Expand Down
20 changes: 0 additions & 20 deletions Cotabby/Models/SuggestionSettingsModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -530,26 +530,6 @@ final class SuggestionSettingsModel: ObservableObject {
userDefaults.set(granularity.rawValue, forKey: Self.acceptanceGranularityDefaultsKey)
}

func setDebounceMilliseconds(_ value: Int) {
let clamped = max(10, min(500, value))
guard debounceMilliseconds != clamped else {
return
}

debounceMilliseconds = clamped
userDefaults.set(clamped, forKey: Self.debounceMillisecondsDefaultsKey)
}

func setFocusPollIntervalMilliseconds(_ value: Int) {
let clamped = max(10, min(500, value))
guard focusPollIntervalMilliseconds != clamped else {
return
}

focusPollIntervalMilliseconds = clamped
userDefaults.set(clamped, forKey: Self.focusPollIntervalMillisecondsDefaultsKey)
}

func setGloballyEnabled(_ enabled: Bool) {
guard isGloballyEnabled != enabled else {
return
Expand Down
4 changes: 0 additions & 4 deletions Cotabby/Services/Suggestion/SuggestionInteractionState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,6 @@ final class SuggestionInteractionState {
contextBuffer.materialize(from: snapshot)
}

func clearContext() {
contextBuffer.clear()
}

func clearSuggestion() {
activeSession = nil
pendingInsertionConsumedCount = nil
Expand Down
16 changes: 3 additions & 13 deletions Cotabby/Services/UI/OverlayController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,6 @@ final class OverlayController: SuggestionOverlayControlling {
/// instead of building one from live settings. Production code leaves this nil.
private let renderModePolicyOverride: CompletionRenderModePolicy?

/// Bundle identifier of the currently focused host app, supplied by the coordinator each time
/// a suggestion is presented. The policy uses this to look up per-app overrides. Nil in tests
/// or when the focus pipeline could not identify the host.
private var currentBundleIdentifier: String?

/// Built from the live `mirrorPreference` setting at call time rather than cached. The struct
/// is tiny (one enum + an empty dict in Phase 2) so per-show allocation cost is negligible,
/// and the read-through model means the user's Settings/menu-bar toggle takes effect on the
Expand Down Expand Up @@ -72,13 +67,6 @@ final class OverlayController: SuggestionOverlayControlling {
self.renderModePolicyOverride = renderModePolicyOverride
}

/// Coordinator hook that updates the bundle identifier used by per-app overrides. Phase 1
/// callers do not need this (policy is `.auto` with no overrides); Phase 2 will wire it through
/// the presenter so per-app settings take effect immediately when the focused app changes.
func setCurrentBundleIdentifier(_ bundleIdentifier: String?) {
currentBundleIdentifier = bundleIdentifier
}

private lazy var panel: OverlayPanel = {
let panel = OverlayPanel(
contentRect: CGRect(x: 0, y: 0, width: 10, height: 10),
Expand Down Expand Up @@ -111,9 +99,11 @@ final class OverlayController: SuggestionOverlayControlling {
return
}

// Per-app render-mode overrides are not wired yet, so the policy always resolves without a
// host bundle identifier; thread the focused app's id here when per-app overrides ship.
let mode = currentRenderModePolicy.mode(
for: geometry,
bundleIdentifier: currentBundleIdentifier
bundleIdentifier: nil
)

switch mode {
Expand Down
9 changes: 0 additions & 9 deletions Cotabby/Services/Utilities/ModelDownloadManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -191,15 +191,6 @@ final class ModelDownloadManager: ObservableObject {
task.cancel()
}

/// Cancels every in-flight model download before destructive app cleanup.
/// Uninstall should not race an active download that may still be writing into Cotabby's model
/// directory while the folder is being removed.
func cancelAllDownloads() {
for task in downloadTasks.values {
task.cancel()
}
}

func openModelsDirectory() {
do {
try ensureRuntimeDirectoryExists()
Expand Down
13 changes: 0 additions & 13 deletions Cotabby/Support/CompletionRenderModePolicy.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,6 @@ enum MirrorPreference: String, Codable, CaseIterable, Identifiable, Equatable, S
return "Popup"
}
}

/// One-sentence explanation suitable for `.help()` tooltips next to the picker. Read as a group
/// the three help strings teach the user when each option is the right pick.
var helpDescription: String {
switch self {
case .auto:
return "Inline ghost text when caret position is reliable; popup card when it isn't (some Electron and web editors)."
case .alwaysInline:
return "Always draw ghost text next to the caret, even when caret position may drift."
case .alwaysMirror:
return "Always show suggestions in a popup card anchored below the focused field."
}
}
}

/// Pure rule that translates "what kind of geometry do we have, and what does the user want?" into
Expand Down
7 changes: 0 additions & 7 deletions Cotabby/Support/FileLogHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,6 @@ final class FileLogWriter: @unchecked Sendable {
}
}

/// Test-only hook to force a rotation.
func wipeForTesting() {
lock.lock()
defer { lock.unlock() }
rotateLocked()
}

private func rotateLocked() {
guard let logFileURL else { return }
do {
Expand Down
21 changes: 0 additions & 21 deletions Cotabby/UI/MenuBarSections.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,6 @@ import SwiftUI
/// Small, focused components used by the menu-bar panel.
/// These stay purely presentational — all state derivation lives in `MenuBarView`.

/// Colored pill that communicates Cotabby's overall readiness at a glance.
/// Green = ready, orange = degraded/needs attention, red = broken, gray = transitional.
struct StatusPill: View {
let text: String
let color: Color

var body: some View {
HStack(spacing: 5) {
Circle()
.fill(color)
.frame(width: 7, height: 7)

Text(text)
.font(.subheadline.weight(.medium))
}
.padding(.horizontal, 10)
.padding(.vertical, 4)
.background(color.opacity(0.12), in: Capsule())
}
}

/// Compact labeled row for menu-bar pickers. Keeps label width consistent across
/// Engine / Model / Length rows without a heavy generic layout container.
struct MenuBarPickerRow<Content: View>: View {
Expand Down
11 changes: 0 additions & 11 deletions Cotabby/UI/Settings/Panes/AdvancedPaneView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -355,17 +355,6 @@ final class ExtendedContextPlaygroundModel: ObservableObject {
}
}

/// Cancels any in-flight generation and clears the spinner. Currently unused by the UI but
/// kept on the model so a cancel button (or window-dismiss handler) can call into it without
/// re-deriving the cancellation protocol. The generation-ID flip is the load-bearing piece —
/// it tells the in-flight task to silently exit instead of clearing state itself.
func cancelGeneration() {
generationTask?.cancel()
generationTask = nil
currentGenerationID = nil
isGenerating = false
}

/// Builds a `FocusedInputContext` from the user's test text. The values are intentionally
/// generic — the playground is a prompt-shape demo, not an attempt to mimic a specific host
/// app's accessibility surface.
Expand Down
7 changes: 0 additions & 7 deletions Cotabby/UI/Settings/Panes/GeneralPaneView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -278,13 +278,6 @@ struct GeneralPaneView: View {
)
}

private var emojiSkinToneBinding: Binding<EmojiSkinTone> {
Binding(
get: { suggestionSettings.preferredEmojiSkinTone },
set: { suggestionSettings.setPreferredEmojiSkinTone($0) }
)
}

private var autoAcceptTrailingPunctuationBinding: Binding<Bool> {
Binding(
get: { suggestionSettings.autoAcceptTrailingPunctuation },
Expand Down
Loading