RepoPilotOpen in app →

runjuu/InputSourcePro

Switch and track your input sources with ease ✨

Mixed

Mixed signals — read the receipts

worst of 4 axes
Use as dependencyConcerns

copyleft license (GPL-3.0) — review compatibility; no tests detected

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 1d ago
  • 8 active contributors
  • GPL-3.0 licensed
Show 4 more →
  • CI configured
  • Concentrated ownership — top contributor handles 74% of recent commits
  • GPL-3.0 is copyleft — check downstream compatibility
  • No test directory detected
What would change the summary?
  • Use as dependency ConcernsMixed if: relicense under MIT/Apache-2.0 (rare for established libs)

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Forkable" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Forkable
[![RepoPilot: Forkable](https://repopilot.app/api/badge/runjuu/inputsourcepro?axis=fork)](https://repopilot.app/r/runjuu/inputsourcepro)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/runjuu/inputsourcepro on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: runjuu/InputSourcePro

Generated by RepoPilot · 2026-05-10 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/runjuu/InputSourcePro shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

WAIT — Mixed signals — read the receipts

  • Last commit 1d ago
  • 8 active contributors
  • GPL-3.0 licensed
  • CI configured
  • ⚠ Concentrated ownership — top contributor handles 74% of recent commits
  • ⚠ GPL-3.0 is copyleft — check downstream compatibility
  • ⚠ No test directory detected

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live runjuu/InputSourcePro repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/runjuu/InputSourcePro.

What it runs against: a local clone of runjuu/InputSourcePro — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in runjuu/InputSourcePro | Confirms the artifact applies here, not a fork | | 2 | License is still GPL-3.0 | Catches relicense before you depend on it | | 3 | Default branch main exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 31 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>runjuu/InputSourcePro</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of runjuu/InputSourcePro. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/runjuu/InputSourcePro.git
#   cd InputSourcePro
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of runjuu/InputSourcePro and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "runjuu/InputSourcePro(\\.git)?\\b" \\
  && ok "origin remote is runjuu/InputSourcePro" \\
  || miss "origin remote is not runjuu/InputSourcePro (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(GPL-3\\.0)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"GPL-3\\.0\"" package.json 2>/dev/null) \\
  && ok "license is GPL-3.0" \\
  || miss "license drift — was GPL-3.0 at generation time"

# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
  && ok "default branch main exists" \\
  || miss "default branch main no longer exists"

# 4. Critical files exist
test -f "Input Source Pro/Models/ApplicationVM.swift" \\
  && ok "Input Source Pro/Models/ApplicationVM.swift" \\
  || miss "missing critical file: Input Source Pro/Models/ApplicationVM.swift"
test -f "Input Source Pro/Models/InputSourceVM.swift" \\
  && ok "Input Source Pro/Models/InputSourceVM.swift" \\
  || miss "missing critical file: Input Source Pro/Models/InputSourceVM.swift"
test -f "Input Source Pro/Controllers/StatusItemController.swift" \\
  && ok "Input Source Pro/Controllers/StatusItemController.swift" \\
  || miss "missing critical file: Input Source Pro/Controllers/StatusItemController.swift"
test -f "Input Source Pro/Persistence/MainStorage.swift" \\
  && ok "Input Source Pro/Persistence/MainStorage.swift" \\
  || miss "missing critical file: Input Source Pro/Persistence/MainStorage.swift"
test -f "Input Source Pro/Models/PreferencesVM.swift" \\
  && ok "Input Source Pro/Models/PreferencesVM.swift" \\
  || miss "missing critical file: Input Source Pro/Models/PreferencesVM.swift"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 31 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~1d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/runjuu/InputSourcePro"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

Input Source Pro is a native macOS utility written in Swift that automates keyboard/input source switching based on the active application or website being browsed. It solves the friction for multilingual users by letting them define rules per-app (e.g., always use Chinese IME in WeChat) or per-website (e.g., use English when on GitHub), plus features like automatic function key mode switching and app-aware punctuation enforcement. Model-View-Controller architecture split into Input Source Pro/Controllers (IndicatorWindowController, StatusItemController, PreferencesWindowController), Input Source Pro/Models (separate files per concern: ApplicationVM, IndicatorVM, PreferencesVM with focused extensions like PreferencesVM+HotKeyGroup), and Input Source Pro/Persistence (CoreData models in Main.xcdatamodeld, MainStorage wrapper, and entity files like AppRule, BrowserRule, KeyboardConfig). SwiftUI integration inferred from ViewController naming and XCWorkspace usage.

👥Who it's for

Multilingual macOS users who frequently switch between input sources (Chinese, Japanese, Korean, etc.) and want automation based on context; developers and power users who need seamless IME switching without manual intervention; contributors interested in macOS accessibility APIs and SwiftUI development.

🌱Maturity & risk

Actively maintained with a clean single-file Swift codebase (440KB), proper CI/CD via GitHub Actions (see .github/workflows/build.yml), and structured architecture with ViewModels, Controllers, and Persistence layers. The presence of CONTRIBUTING.md, CODE_OF_CONDUCT.md, and a public website (inputsource.pro) indicate this is production-ready. Exact maturity depends on GitHub star count and issue backlog, which are not visible in the provided data, but the organized structure and active maintenance pattern suggest stable, daily-use quality.

Single-maintainer repo (runjuu) creates sustainability risk; no visible test suite in the file list (no Tests/ folder), which means changes to core input switching logic lack automated verification. The app depends heavily on macOS accessibility APIs (note ApplicationVM+AXNotification.swift), which are fragile across OS versions and can break silently. No visible dependency management (no Podfile, Package.swift, or SPM declarations in the snippet), so external lib risks are unclear.

Active areas of work

No specific PR or recent commit data is visible in the provided file list. The presence of a well-structured changelog link (inputsource.pro/changelog) and organized directory layout suggest active maintenance, but exact current work priorities are not evident. The organized file structure (separate VM+Extension files, persistence abstractions) hints at ongoing refactoring toward modularity.

🚀Get running

Clone the repo: git clone https://github.com/runjuu/InputSourcePro.git && cd InputSourcePro. Open the Xcode project: open 'Input Source Pro.xcodeproj'. Build and run via Xcode (⌘R) or: xcodebuild -scheme 'Input Source Pro' -configuration Debug. No additional package installation needed if using Xcode's integrated SPM.

Daily commands: Open Xcode: open 'Input Source Pro.xcodeproj'. Select 'Input Source Pro' scheme (top-left). Press ⌘R or Product > Run. App launches as a menu bar utility (status item) with a preferences window accessible via StatusItemController.

🗺️Map of the codebase

  • Input Source Pro/Models/ApplicationVM.swift — Core view model managing active application tracking and Accessibility framework integration; essential for understanding how the app monitors input source changes.
  • Input Source Pro/Models/InputSourceVM.swift — Manages input source state and switching logic; the heart of the app's input source switching functionality.
  • Input Source Pro/Controllers/StatusItemController.swift — Menu bar status item controller; primary UI entry point and user interaction hub for the app.
  • Input Source Pro/Persistence/MainStorage.swift — Core Data persistence layer handling all configuration storage; critical for understanding data model and caching strategy.
  • Input Source Pro/Models/PreferencesVM.swift — Central preferences management view model orchestrating app-wide settings, keyboard configs, and rules.
  • Input Source Pro/Models/IndicatorVM.swift — Manages the visual indicator display logic and positioning; key to understanding UI state management.
  • Input Source Pro/Persistence/Main.xcdatamodeld/Main.xcdatamodel/contents — Core Data schema defining all persistent entities (AppRule, BrowserRule, HotKeyGroup, KeyboardConfig); contract between app and storage.

🛠️How to make changes

Add a new input source switching rule for an application

  1. Define the rule entity in the Core Data model by editing Main.xcdatamodeld (Input Source Pro/Persistence/Main.xcdatamodeld/Main.xcdatamodel/contents)
  2. Create a new NSManagedObject subclass (if not already AppRule) in Persistence directory following the pattern of AppRule.swift (Input Source Pro/Persistence/AppRule.swift)
  3. Add rule persistence logic to PreferencesVM by extending the appropriate helper file (Input Source Pro/Models/PreferencesVM+HotKeyGroup.swift)
  4. Extend ApplicationVM to check the new rule type when application changes (Input Source Pro/Models/ApplicationVM+AXNotification.swift)
  5. Call InputSourceVM.switchInputSource() when rule matches (Input Source Pro/Models/InputSourceVM.swift)

Add a new indicator position mode

  1. Add position enum case to PreferencesVM indicator position helper (Input Source Pro/Models/PreferencesVM+IndicatorPosition.swift)
  2. Implement position calculation logic in IndicatorVM+Triggers (Input Source Pro/Models/IndicatorVM+Triggers.swift)
  3. Update IndicatorWindowController to apply the new frame geometry (Input Source Pro/Controllers/IndicatorWindowController+Indicator.swift)
  4. Add UI controls in PreferencesWindowController for selecting the new mode (Input Source Pro/Controllers/PreferencesWindowController.swift)

Add support for detecting a new input source type

  1. Extend InputSourceVM to query and identify the new input source type via TIS framework (Input Source Pro/Models/InputSourceVM.swift)
  2. Add display name and icon mapping in IndicatorVM for the new source (Input Source Pro/Models/IndicatorVM.swift)
  3. Update KeyboardConfig data model if additional properties are needed (Input Source Pro/Persistence/KeyboardConfig.swift)
  4. Test switching logic via InputSourceVM.switchInputSource() (Input Source Pro/Models/InputSourceVM.swift)

Add a new browser-specific rule (e.g., Gmail always uses English)

  1. Create or extend BrowserRule entity in Core Data model (Input Source Pro/Persistence/Main.xcdatamodeld/Main.xcdatamodel/contents)
  2. Add rule creation and storage in PreferencesVM browser rule helper (Input Source Pro/Models/PreferencesVM+BrowserRule.swift)
  3. Extend ApplicationVM to monitor browser URL changes via AXNotification (Input Source Pro/Models/ApplicationVM+AXNotification.swift)
  4. Match URL patterns and trigger InputSourceVM.switchInputSource() (Input Source Pro/Models/InputSourceVM.swift)

🔧Why these technologies

  • SwiftUI + AppKit hybrid — SwiftUI for modern preferences UI, AppKit for menu bar integration and window management (NSStatusBar, NSWindow) which SwiftUI cannot fully support on macOS yet
  • Core Data (NSManagedObject) — Persistent storage of rules, keyboard configs, and hot keys with minimal boilerplate; supports querying and relationships between AppRule/BrowserRule entities
  • Text Input Services (TIS) Framework — macOS-specific framework for querying available input sources, detecting current input source, and switching sources programmatically
  • Accessibility Framework (AX) — Required for monitoring active application changes and browser tab URL detection; powers ApplicationVM event subscriptions
  • MVVM with ObservableObject — SwiftUI reactive state management; decouples business logic (ViewModels) from UI rendering and allows easy testing

⚖️Trade-offs already made

  • Hybrid SwiftUI + AppKit architecture

    • Why: SwiftUI lacks native menu bar and window positioning primitives; AppKit provides mature, reliable APIs
    • Consequence: Increased codebase complexity with dual UI frameworks; requires careful lifecycle management between UIKit-style controllers and SwiftUI views
  • Core Data instead of lightweight SQLite wrapper

    • Why: Entity relationships (AppRule → KeyboardConfig) are natural in Core Data; schema migrations handled by Xcode
    • Consequence: Higher memory footprint; NSManagedObject thread-safety requires careful context management
  • Polling active app via AXNotification rather than event-driven system service

    • Why: AX framework is the official macOS API; provides battery life and security boundaries
    • Consequence: May miss rapid app switches; requires Accessibility permissions grant (user-facing dialog)
  • Indicator positioned relative to cursor or fixed screen corner

    • Why: Avoids blocking user input; cursor-relative is less intrusive than fixed-position
    • Consequence: Indicator coordinate calculation must handle multi-monitor layouts and screen rotation edge cases

🚫Non-goals (don't propose these)

  • Real-time typing prediction or AI-based input source auto-detection
  • Cross-platform support (Windows, Linux) — macOS-only utility
  • Network-based rule synchronization or cloud backup
  • Custom input source creation or modification of system input source behavior
  • Integration with non-macOS system input sources (e.g., smart cards, external IME daemons)

🪤Traps & gotchas

macOS Accessibility Permissions: App requires 'Accessibility' permission (Privacy & Security > Accessibility) to work; without it, AXNotification listeners fail silently. CoreData threading: Accessing MainStorage must happen on the correct thread; no visible explicit dispatch management in file list, risk of crashes in concurrent access. Browser detection: BrowserRule matching likely relies on parsing browser URLs/DOM; this is fragile across browser updates and may require periodic maintenance (see PreferencesVM+BrowserRule.swift). Input source enumeration: Relies on Carbon/Cocoa APIs that differ between Intel and Apple Silicon; no visible arch-specific branching, potential compatibility issues.

🏗️Architecture

💡Concepts to learn

  • Accessibility API (AXNotification) — Input Source Pro's core detection mechanism relies on macOS Accessibility notifications to observe app switches; understanding AXUIElement and notification patterns is essential for debugging and extending app-aware rules
  • CoreData Object Relational Mapping — User rules (AppRule, BrowserRule, KeyboardConfig) are persisted via CoreData entities; contributors must understand relationships, migrations, and threading to safely modify the data model
  • Input Method Editor (IME) / Input Source — The entire app's purpose is managing IMEs; understanding macOS input source architecture (Carbon Services, TIS), enumeration APIs, and switching mechanisms is fundamental to the domain
  • MVVM (Model-View-ViewModel) Pattern — Codebase uses MVVM heavily (ApplicationVM, IndicatorVM, PreferencesVM); understanding separation of concerns via ViewModels is critical for navigating and extending the architecture
  • SwiftUI @Published/@ObservedObject Reactive Binding — UI updates are driven by published properties in ViewModels; understanding reactive data flow is necessary to modify preferences UI or indicator displays without causing state inconsistencies
  • Menu Bar / Status Item Applications — Input Source Pro runs as a background menu bar utility (via StatusItemController), not a traditional windowed app; understanding NSStatusItem lifecycle and event handling differs from standard macOS app patterns
  • Browser URL/DOM Parsing for Rule Matching — BrowserRule logic must parse website URLs or DOM to match rules per-browser; this involves browser-specific APIs (JavaScript bridge in Safari, accessibility queries in Chrome) that are fragile across browser versions
  • Karabiner-Elements/Karabiner-Elements — Alternative macOS keyboard utility that also manipulates input sources and automations; similar accessibility API usage patterns
  • squirrel-ime/Squirrel — Chinese IME for macOS that works alongside input source switching; many Input Source Pro users also use Squirrel, creating a companion ecosystem
  • xcodebuild/awesome-swift-macos — Reference for SwiftUI + AppKit patterns and macOS API best practices; Input Source Pro exemplifies modern Swift macOS app architecture
  • apple/swift — Swift language and standard library; Input Source Pro is pure Swift and serves as a real-world example of native macOS app development
  • rxswiftcommunity/RxSwift — Reactive programming framework; Input Source Pro uses similar @Published/@ObservedObject patterns (built-in Combine) that RxSwift users would recognize

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add unit tests for PreferencesVM and its extensions

The PreferencesVM.swift file and its 6 extensions (AppCustomization, AppKeyboardCache, BrowserAddress, BrowserRule, HotKeyGroup, IndicatorPosition, KeyboardConfig, ShortcutTrigger) handle critical user preferences and persistence logic but have no visible test coverage. Adding tests would ensure configuration changes, keyboard caching, browser rules, and hot key group management work correctly across updates. This is particularly important given the complexity of the data model in Persistence/Main.xcdatamodeld.

  • [ ] Create Input Source Pro/Tests/PreferencesVMTests.swift with test targets for each extension
  • [ ] Add tests for keyboard config persistence using MainStorage.swift
  • [ ] Test browser rule matching logic in PreferencesVM+BrowserRule.swift
  • [ ] Test hot key group storage and retrieval in PreferencesVM+HotKeyGroup.swift
  • [ ] Test app-specific keyboard caching in PreferencesVM+AppKeyboardCache.swift

Add UI tests for IndicatorViewModel trigger logic

IndicatorVM.swift and IndicatorVM+Triggers.swift manage visual indicator display based on input source changes and user interactions, but no UI tests validate that the indicator displays correctly or responds to triggers. With 3 indicator demo videos in Resources/ showing expected behavior, formal UI tests should verify: trigger conditions, indicator positioning (IndicatorVM+Triggers, PreferencesVM+IndicatorPosition), and WindowController interactions (IndicatorWindowController, IndicatorWindowController+Indicator).

  • [ ] Create Input Source Pro/Tests/IndicatorUITests.swift with XCUITest targets
  • [ ] Test indicator visibility toggling based on IndicatorVM state changes
  • [ ] Test trigger conditions from IndicatorVM+Triggers.swift (keyboard, hotkey, manual triggers)
  • [ ] Verify indicator positioning matches PreferencesVM+IndicatorPosition.swift settings
  • [ ] Test IndicatorWindowController+Activation.swift window lifecycle

Add GitHub Actions workflow for macOS app binary code signing and notarization

The .github/workflows/build.yml exists but the file structure and build.yml mention is incomplete. For a macOS utility that requires Accessibility permissions (seen in PermissionsVM.swift), the binary must be signed and notarized for distribution. Adding a workflow that builds, code-signs, and notarizes the app artifact would streamline releases and improve security. This is especially critical given the app handles input source control, requiring elevated permissions.

  • [ ] Extend .github/workflows/build.yml to include code signing steps using developer certificates
  • [ ] Add notarization step to fulfill Apple's gatekeeper requirements for unsigned apps
  • [ ] Store signing credentials securely in GitHub Secrets (developer certificate, notarization credentials)
  • [ ] Generate and upload a signed .dmg or .zip artifact after successful build
  • [ ] Document signing setup in CONTRIBUTING.md for local development instructions

🌿Good first issues

  • Add unit tests for InputSourceVM.swift input source switching logic; currently no Tests/ folder exists, so core IME enumeration and switching have no automated verification — start by creating Tests/ and writing XCTestCase for input source detection
  • Document the CoreData schema (Main.xcdatamodeld contents) with inline comments in the .xcdatamodel/contents file explaining each entity (AppRule, BrowserRule, KeyboardConfig) and relationships; currently lacks schema documentation
  • Extend browser detection in PreferencesVM+BrowserRule.swift to support newer browsers (Arc, Zen, Dia mentioned in README but not visible in rule logic); add new browser identifiers and test with actual app bundles

Top contributors

Click to expand

📝Recent commits

Click to expand
  • c3a4528 — fix: prevent modifier shortcut freeze during rapid CJKV switching (Sergey Nosenko)
  • 2314f09 — fix: preserve input mode identifiers for app-specific keyboard switching (spinachomes)
  • e888d3d — chore: release 2.9.1 (runjuu)
  • c94915b — feat: update InputSourceSwitcher logic (runjuu)
  • 662b5d7 — chore: release 2.9.1-beta2 (runjuu)
  • 62a525a — feat(InputSourceSwitcher): tweak delays (runjuu)
  • f73bdf3 — chore: release 2.9.1-beta (runjuu)
  • 110675b — feat(InputSourceSwitcher): optimize switching logic for CJKV fix (runjuu)
  • d02d9e6 — docs: update README (runjuu)
  • 60df318 — chore: release 2.9.0 (runjuu)

🔒Security observations

Input Source Pro is a macOS utility with moderate security posture. The primary concerns are around the extensive accessibility permissions required for core functionality and the lack of encryption for persistent user data (browser rules, keyboard preferences). The application appears to be properly code-signed and notarized (typical for macOS apps). No hardcoded secrets, SQL injection, or XSS risks were detected. Recommendations focus on encrypting sensitive persistent data, clarifying permission usage to users, and implementing HTTPS certificate pinning for any network communication. The application's core functionality (accessibility monitoring) is inherently privileged and requires careful security consideration.

  • Medium · Potential Accessibility Framework Abuse — Input Source Pro/Models/ApplicationVM+AXNotification.swift, Input Source Pro/Controllers/IndicatorWindowController+Activation.swift. The codebase heavily relies on macOS Accessibility features (AX Notifications, ApplicationVM+AXNotification.swift) to monitor and control input sources. This requires extensive system permissions that could be abused if the application is compromised. The app monitors active applications and websites, which involves tracking user activity. Fix: Implement strict permission request dialogs, document the necessity of accessibility permissions clearly, implement activity logging, and consider code signing and notarization to prevent tampering.
  • Medium · Browser Rule Storage Without Encryption — Input Source Pro/Persistence/BrowserRule.swift, Input Source Pro/Models/PreferencesVM+BrowserRule.swift, Input Source Pro/Persistence/Main.xcdatamodeld. BrowserRule.swift and PreferencesVM+BrowserRule.swift handle browser-specific rules (including website tracking patterns). These rules are persisted in CoreData (Main.xcdatamodeld) without apparent encryption, which could expose user browsing patterns and preferences. Fix: Implement Core Data encryption using NSFileProtectionComplete attribute, or encrypt sensitive BrowserRule data at rest using CryptoKit.
  • Low · Keyboard Configuration Persistence — Input Source Pro/Persistence/KeyboardConfig.swift, Input Source Pro/Models/PreferencesVM+KeyboardConfig.swift. KeyboardConfig.swift and related persistence files store keyboard configuration data including hotkey groups and shortcuts without explicit security consideration. While not directly sensitive, keyboard customizations combined with accessibility monitoring could reveal user behavior patterns. Fix: Use Keychain storage for sensitive hotkey configurations and ensure all persistence uses FileProtection attributes.
  • Low · Missing Certificate Pinning — Input Source Pro/Models/FeedbackVM.swift, Input Source Pro/Controllers/StatusItemController.swift. No evidence of HTTPS certificate pinning for any network communication to inputsource.pro or external services that may exist (feedback functionality in FeedbackVM.swift). Fix: Implement certificate pinning using URLSession delegate methods or a security framework to prevent man-in-the-middle attacks.
  • Low · No Visible Security Headers in Build Configuration — Input Source Pro.xcodeproj/project.pbxproj. The Xcode project configuration files (.pbxproj) don't show explicit security build settings like -fstack-protector-strong, -fPIE, or FORTIFY_SOURCE, which could enable additional protection against stack-based attacks. Fix: Enable security build flags in Build Settings: CLANG_ENABLE_OBJC_ARC, GCC_STRICT_ALIASING, and other hardening options.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Mixed signals · runjuu/InputSourcePro — RepoPilot