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
20 changes: 1 addition & 19 deletions .githooks/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,9 @@ echo "Setting up git hooks..."
# Configure git to use the shared hooks directory
git config core.hooksPath .githooks

# Create Secrets.xcconfig from sample if it doesn't exist
SECRETS_FILE="macos/OnitQuickEdit/Secrets.xcconfig"
SECRETS_SAMPLE="macos/OnitQuickEdit/Secrets.xcconfig.sample"

if [ ! -f "$SECRETS_FILE" ] && [ -f "$SECRETS_SAMPLE" ]; then
cp "$SECRETS_SAMPLE" "$SECRETS_FILE"
echo "✓ Created Secrets.xcconfig from sample"
echo " → Please edit $SECRETS_FILE with your API keys"
fi

# Create backup if Secrets exists but backup doesn't
SECRETS_BACKUP="macos/OnitQuickEdit/Secrets.xcconfig.backup"
if [ -f "$SECRETS_FILE" ] && [ ! -f "$SECRETS_BACKUP" ]; then
cp "$SECRETS_FILE" "$SECRETS_BACKUP"
echo "✓ Created Secrets.xcconfig.backup"
fi

echo ""
echo "✓ Git hooks installed successfully!"
echo ""
echo "What this does:"
echo " • post-checkout: Restores Secrets.xcconfig + updates submodules + cleans SPM cache"
echo " • post-checkout: Updates submodules + cleans SPM cache"
echo " • post-merge: Updates submodules after pull + cleans SPM cache"
echo " • pre-commit: Prevents accidentally committing secrets"
15 changes: 0 additions & 15 deletions .githooks/post-checkout
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,6 @@
# Created by Kévin Naudin on 2026-01-23.
#

SECRETS_FILE="macos/OnitQuickEdit/Secrets.xcconfig"
SECRETS_BACKUP="macos/OnitQuickEdit/Secrets.xcconfig.backup"
SECRETS_SAMPLE="macos/OnitQuickEdit/Secrets.xcconfig.sample"

# If Secrets.xcconfig was deleted during checkout, restore it
if [ ! -f "$SECRETS_FILE" ]; then
if [ -f "$SECRETS_BACKUP" ]; then
cp "$SECRETS_BACKUP" "$SECRETS_FILE"
echo "✓ Secrets.xcconfig restored from backup"
elif [ -f "$SECRETS_SAMPLE" ]; then
cp "$SECRETS_SAMPLE" "$SECRETS_FILE"
echo "⚠ Secrets.xcconfig created from sample - please fill in your values"
fi
fi

# Update submodules after checkout
# --init: Initialize any submodules not yet initialized
# --recursive: Also update nested submodules
Expand Down
15 changes: 0 additions & 15 deletions .githooks/pre-commit

This file was deleted.

3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -250,9 +250,6 @@ dist
__pycache__/
.venv/

# Secrets and sensitive configuration
macos/OnitQuickEdit/Secrets.xcconfig
macos/OnitQuickEdit/Secrets.xcconfig.backup
.gstack/

# Former submodules / private tooling kept on disk only (quickedit-only)
Expand Down
9 changes: 1 addition & 8 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,11 @@ is the QuickEdit-only strip of onit-beacon, headed to its own private repo
**After creating a new worktree or switching to a new branch, always run:**

```bash
# 1. Copy Secrets.xcconfig from the main onit-beacon repo (not tracked in git;
# the main repo still keeps it under macos/Onit/)
cp /Users/kevinnaudin/SynthInc/onit-beacon/macos/Onit/Secrets.xcconfig macos/OnitQuickEdit/Secrets.xcconfig

# 2. Install git hooks (cleans SPM cache)
# Install git hooks (cleans SPM cache)
./.githooks/install.sh
```

## File Locations

### Configuration
- `macos/OnitQuickEdit/Secrets.xcconfig` - API keys (base64 encoded)

### Documentation
- `macos/OnitQuickEdit/PERMISSIONS.md` - Permissions model (Accessibility, Screen Recording)
11 changes: 1 addition & 10 deletions macos/OnitQuickEdit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,6 @@
inputFileListPaths = (
);
inputPaths = (
"$(SRCROOT)/Onit/Secrets.xcconfig",
);
name = "Environment Checks";
outputFileListPaths = (
Expand All @@ -279,7 +278,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "set -e\n\n# ============================================\n# Git Hooks Check\n# ============================================\necho \"🔧 Checking git hooks configuration...\"\n\nREPO_ROOT=$(cd \"${SRCROOT}/..\" && git rev-parse --show-toplevel 2>/dev/null || echo \"\")\n\nif [ -n \"$REPO_ROOT\" ]; then\n HOOKS_PATH=$(cd \"$REPO_ROOT\" && git config core.hooksPath 2>/dev/null || echo \"\")\n \n if [ \"$HOOKS_PATH\" != \".githooks\" ]; then\n echo \"error: \"\n echo \"error: ════════════════════════════════════════════════════════════\"\n echo \"error: 👋 Welcome to the Onit team!\"\n echo \"error: ════════════════════════════════════════════════════════════\"\n echo \"error: \"\n echo \"error: One last step before you can build:\"\n echo \"error: \"\n echo \"error: Run this command from the repository root:\"\n echo \"error: \"\n echo \"error: ./.githooks/install.sh\"\n echo \"error: \"\n echo \"error: This configures git hooks for the team workflow.\"\n echo \"error: \"\n echo \"error: ════════════════════════════════════════════════════════════\"\n echo \"error: \"\n exit 1\n else\n echo \"✓ Git hooks configured\"\n fi\nelse\n echo \"error: ❌ Not in a git repository\"\n exit 1\nfi\n\n# ============================================\n# Secrets Check\n# ============================================\necho \"🔐 Checking secrets configuration...\"\n\n# Check if GH_READONLY_TOKEN is available in build settings\nif [ -z \"$GH_READONLY_TOKEN\" ]; then\n echo \"error: ❌ GH_READONLY_TOKEN not found in build settings\"\n echo \"error: 📝 Make sure Secrets.xcconfig is:\"\n echo \"error: 1. Created at ${SRCROOT}/Onit/Secrets.xcconfig\"\n echo \"error: 2. Contains: GH_READONLY_TOKEN = <your_plain_text_token>\"\n echo \"error: 3. Assigned in Project Settings → Info → Configurations\"\n exit 1\nfi\n\necho \"✓ GH_READONLY_TOKEN is configured\"\n\n# Check if GITHUB_REPO is available in build settings\nif [ -z \"$GITHUB_REPO\" ]; then\n echo \"error: ❌ GITHUB_REPO not found in build settings\"\n echo \"error: 📝 Make sure Secrets.xcconfig contains:\"\n echo \"error: GITHUB_REPO = synth-inc/onit-brain\"\n exit 1\nfi\n\necho \"✓ GITHUB_REPO is configured: $GITHUB_REPO\"\n\n# Verify that Secrets.xcconfig file exists\nSECRETS_FILE=\"${SRCROOT}/Onit/Secrets.xcconfig\"\nif [ ! -f \"$SECRETS_FILE\" ]; then\n echo \"warning: ⚠️ Secrets.xcconfig file not found at expected location\"\n echo \"warning: 💡 But build settings are configured, so build will proceed\"\nfi\n\necho \"✅ All environment checks passed!\"\n";
shellScript = "set -e\n\n# ============================================\n# Git Hooks Check\n# ============================================\necho \"🔧 Checking git hooks configuration...\"\n\nREPO_ROOT=$(cd \"${SRCROOT}/..\" && git rev-parse --show-toplevel 2>/dev/null || echo \"\")\n\nif [ -n \"$REPO_ROOT\" ]; then\n HOOKS_PATH=$(cd \"$REPO_ROOT\" && git config core.hooksPath 2>/dev/null || echo \"\")\n \n if [ \"$HOOKS_PATH\" != \".githooks\" ]; then\n echo \"error: \"\n echo \"error: ════════════════════════════════════════════════════════════\"\n echo \"error: 👋 Welcome to the Onit team!\"\n echo \"error: ════════════════════════════════════════════════════════════\"\n echo \"error: \"\n echo \"error: One last step before you can build:\"\n echo \"error: \"\n echo \"error: Run this command from the repository root:\"\n echo \"error: \"\n echo \"error: ./.githooks/install.sh\"\n echo \"error: \"\n echo \"error: This configures git hooks for the team workflow.\"\n echo \"error: \"\n echo \"error: ════════════════════════════════════════════════════════════\"\n echo \"error: \"\n exit 1\n else\n echo \"✓ Git hooks configured\"\n fi\nelse\n echo \"error: ❌ Not in a git repository\"\n exit 1\nfi\n\necho \"✅ All environment checks passed!\"\n";
};
864FE87F2E97AD56004BFC07 /* Download and Copy ripgrep Binary */ = {
isa = PBXShellScriptBuildPhase;
Expand Down Expand Up @@ -354,8 +353,6 @@
/* Begin XCBuildConfiguration section */
2883E4C02CA5ECBC00F79A48 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReferenceAnchor = 2883E4B52CA5ECBB00F79A48 /* Onit */;
baseConfigurationReferenceRelativePath = Secrets.xcconfig;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
Expand Down Expand Up @@ -421,8 +418,6 @@
};
2883E4C12CA5ECBC00F79A48 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReferenceAnchor = 2883E4B52CA5ECBB00F79A48 /* Onit */;
baseConfigurationReferenceRelativePath = Secrets.xcconfig;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
Expand Down Expand Up @@ -481,8 +476,6 @@
};
2883E4C32CA5ECBC00F79A48 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReferenceAnchor = 2883E4B52CA5ECBB00F79A48 /* Onit */;
baseConfigurationReferenceRelativePath = Secrets.xcconfig;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
Expand Down Expand Up @@ -535,8 +528,6 @@
};
2883E4C42CA5ECBC00F79A48 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReferenceAnchor = 2883E4B52CA5ECBB00F79A48 /* Onit */;
baseConfigurationReferenceRelativePath = Secrets.xcconfig;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
Expand Down
3 changes: 0 additions & 3 deletions macos/OnitQuickEdit/Data/Persistence/Defaults.swift
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,6 @@ extension Defaults.Keys {
static let stopModeUserConfigured = Key<Bool>("stopModeUserConfigured", default: false)

// QuickEdit
#if DEBUG || ONIT_BETA
static let hideBugReportEmoji = Key<Bool>("hideBugReportEmoji", default: false)
#endif
static let quickEditConfig = Key<QuickEditConfig>("quickEditConfig", default: .default)
static let quickEditMode = Key<InferenceMode>("quickEditMode", default: .remote)
static let quickEditRemoteModel = Key<AIModel?>("quickEditRemoteModel", default: nil)
Expand Down
55 changes: 0 additions & 55 deletions macos/OnitQuickEdit/Helpers/SecretsManager.swift

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,6 @@ import Defaults
import Foundation
import UniformTypeIdentifiers

// MARK: - Debug Capture (DEBUG only)

#if DEBUG || ONIT_BETA
struct NonAXTriggerDebugCapture {
let beforeImage: CGImage
let afterImage: CGImage
let changedRegions: [CGRect]
let mouseLocation: CGPoint
let timestamp: Date
}
#endif

// MARK: - Configuration

struct NonAccessibilityTriggerConfig {
Expand Down Expand Up @@ -84,10 +72,6 @@ final class QuickEditNonAccessibilityTriggerService: NSObject {

static let shared = QuickEditNonAccessibilityTriggerService()

#if DEBUG || ONIT_BETA
static var latestDebugCapture: NonAXTriggerDebugCapture?
#endif

// MARK: - Properties

weak var delegate: QuickEditTriggerServiceDelegate?
Expand All @@ -108,7 +92,6 @@ final class QuickEditNonAccessibilityTriggerService: NSObject {
private var beforeScreenshotWindowFrame: CGRect?
private var captureTask: Task<Void, Never>?


// Cleanup task for screenshots that aren't used (e.g., simple click with no follow-up action)
private var screenshotCleanupTask: Task<Void, Never>?

Expand Down Expand Up @@ -458,13 +441,6 @@ final class QuickEditNonAccessibilityTriggerService: NSObject {
}

guard let validRegions = analysis.validRegions else {
#if DEBUG || ONIT_BETA
showFalseNegativeReportButton(
beforeImage: beforeImage,
afterImage: afterImage,
groupedRegions: analysis.groupedRegions
)
#endif
return
}

Expand All @@ -476,17 +452,6 @@ final class QuickEditNonAccessibilityTriggerService: NSObject {
let aspectRatio = selectedRegion.width / selectedRegion.height
print("[NonAccessibilityTrigger] Selected region: \(Int(selectedRegion.width))x\(Int(selectedRegion.height)) | aspect: \(String(format: "%.2f", aspectRatio)) (closest to mouse at \(mouseLocation))")

// Store debug capture for labeling UI (DEBUG only)
#if DEBUG || ONIT_BETA
QuickEditNonAccessibilityTriggerService.latestDebugCapture = NonAXTriggerDebugCapture(
beforeImage: beforeImage,
afterImage: afterImage,
changedRegions: analysis.groupedRegions,
mouseLocation: mouseLocation,
timestamp: Date()
)
#endif

// Step 5: Convert to screen coordinates and trigger QuickEdit
await triggerQuickEdit(with: selectedRegion, appName: appName, reason: reason, checkpoint: checkpoint)
checkpoint("Hint displayed ✅")
Expand Down Expand Up @@ -568,28 +533,6 @@ final class QuickEditNonAccessibilityTriggerService: NSObject {
}
}

// MARK: - Debug False Negative Reporting

#if DEBUG || ONIT_BETA
/// Shows the scream emoji button near mouse when detection rejects regions.
/// User can click it to save a false negative test case.
private func showFalseNegativeReportButton(
beforeImage: CGImage,
afterImage: CGImage,
groupedRegions: [CGRect]
) {
let mouseLocation = NSEvent.mouseLocation
let capture = NonAXTriggerDebugCapture(
beforeImage: beforeImage,
afterImage: afterImage,
changedRegions: groupedRegions,
mouseLocation: mouseLocation,
timestamp: Date()
)
FalseNegativeReportButtonPresenter.shared.show(near: mouseLocation, capture: capture)
}
#endif

// MARK: - Debug Screenshot Saving

private func saveDebugScreenshots(before: CGImage, after: CGImage, reason: String) {
Expand Down Expand Up @@ -880,9 +823,6 @@ final class QuickEditNonAccessibilityTriggerService: NSObject {
// Track shift key state
if modifiers.shift && !isShiftDown {
isShiftDown = true
#if DEBUG || ONIT_BETA
FalseNegativeReportButtonPresenter.shared.dismiss()
#endif
captureBeforeScreenshotIfNeeded(reason: "Shift down")
} else if !modifiers.shift && isShiftDown {
isShiftDown = false
Expand All @@ -891,9 +831,6 @@ final class QuickEditNonAccessibilityTriggerService: NSObject {
// Track command key state
if modifiers.command && !isCommandDown {
isCommandDown = true
#if DEBUG || ONIT_BETA
FalseNegativeReportButtonPresenter.shared.dismiss()
#endif
captureBeforeScreenshotIfNeeded(reason: "Cmd down")
} else if !modifiers.command && isCommandDown {
isCommandDown = false
Expand All @@ -905,10 +842,6 @@ final class QuickEditNonAccessibilityTriggerService: NSObject {
if modifiers.command && !modifiers.shift && !modifiers.control && !modifiers.option {
let character = event.event.charactersIgnoringModifiers?.lowercased()
if character == "a" && isKeyDown {
// Dismiss the false negative report button on new selection
#if DEBUG || ONIT_BETA
FalseNegativeReportButtonPresenter.shared.dismiss()
#endif
// Before screenshot already captured on Cmd down
// Use 300ms additional delay for instant selection to render
scheduleTrigger(reason: "Cmd+A (Select All)", afterDelay: 300)
Expand Down Expand Up @@ -1005,10 +938,6 @@ extension QuickEditNonAccessibilityTriggerService: MouseNotificationDelegate {
}

func mouseNotificationManager(_ manager: MouseNotificationManager, didReceiveSingleClick event: NSEvent) {
// Dismiss the false negative report button if click is outside it
#if DEBUG || ONIT_BETA
FalseNegativeReportButtonPresenter.shared.dismissIfClickOutside(at: NSEvent.mouseLocation)
#endif

let isShiftClick = event.modifierFlags.contains(.shift)

Expand Down
23 changes: 0 additions & 23 deletions macos/OnitQuickEdit/QuickEdit/UI/Hint/QuickEditHintView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -182,12 +182,6 @@ struct QuickEditHintView: View {
ActionButton(action: action)
}
}

#if DEBUG || ONIT_BETA
if !Defaults[.hideBugReportEmoji] {
debugLabelingButton
}
#endif
}
.padding(.leading, 5)
.padding([.vertical, .trailing], 3)
Expand Down Expand Up @@ -312,21 +306,4 @@ struct QuickEditHintView: View {
}
}
}

#if DEBUG || ONIT_BETA
private var debugLabelingButton: some View {
Button {
if let capture = QuickEditNonAccessibilityTriggerService.latestDebugCapture {
NonAXTriggerLabelingWindowController.shared.show(capture: capture)
}
} label: {
Text("😱")
.font(.system(size: 14))
}
.buttonStyle(.plain)
.padding(.horizontal, 4)
.opacity(QuickEditNonAccessibilityTriggerService.latestDebugCapture != nil ? 1 : 0.3)
.disabled(QuickEditNonAccessibilityTriggerService.latestDebugCapture == nil)
}
#endif
}
Loading
Loading