Welcome to the OpenClip technical documentation hub. OpenClip is a lightweight, high-performance macOS floating popup utility written in Swift (macOS 14.0+). It intercepts selected text across any application, presents contextual text manipulation actions (copy, cut, paste, definition lookups, web searches, custom scripts, and extensions), and executes platform side-effects seamlessly.
- macOS 14.0 (Sonoma) or later
- Xcode 15.0+ (for building from source)
- xcodegen (
brew install xcodegen)
- Clone the Repository:
git clone https://github.com/openclip/openclip.git
cd openclip- Generate Xcode Project:
Note: Run
xcodegen generatewhenever adding or removing.swiftfiles.
xcodegen generate- Build the Application:
xcodebuild -project OpenClip.xcodeproj -scheme OpenClip -destination 'platform=macOS' build | tail -n 10- Run Unit Tests:
xcodebuild -project OpenClip.xcodeproj -scheme OpenClipTests -destination 'platform=macOS' test | grep -E "Test Suite|passed|failed|SUCCEEDED"- Grant Accessibility Permissions: OpenClip relies on macOS Accessibility APIs to detect text selections without modifying system clipboard contents during monitoring. Grant permission in System Settings > Privacy & Security > Accessibility.
- Architecture Overview — Module target split (
CorevsOpenClipApp) and the Core Architectural Subsystems. - Known Debt & Current-State Realities —
UserDefaults→SettingsStoremigration, singleton wiring, latent issues. - Directory Structure — Annotated per-file source tree.
- Action Coordinator & Registry — Central wiring, callback mechanics, and ordering policy.
- Text Selection Subsystem — Selection detection, the gate/resolver/strategy retrieval model, and non-destructive selection handling.
- Popup Panel & Positioning Math —
PopupPanel, static layout math inPopupPositioner, and window 4E35 lifecycle management. - Logging — the single
Logsurface, category table, and per-subsystem filtering workflow.
- AGENTS.md — Authoring & Packaging Extensions — Start here. Self-contained guide: manifest schema, all action kinds, options, requirements, groups, and the result surface.
- Extending OpenClip Overview — Extension architecture and custom action integration.
- Extension Package Format —
.openclipextbundle structure,manifest.jsonschema, and options definitions. - Standalone Snippet Parsing — Pure header parsing via
OpenClipSnippetParser.
- AppleScript Runtime —
AppleScriptActionexecution, variable injection, and output handling. - JavaScript Runtime —
JavaScriptActionunder JavaScriptCore, theopenclipbridge, and option keys viaSettingKey. - URL Templates Engine — Parameterized search links using
URLTemplateActionandTextPlaceholderEngine. - Shell & Executable Scripts — Process execution, environment variables (
OPENCLIP_TEXT,OPENCLIP_MATCHED,OPENCLIP_ACTION_ID), and JSON/text stdout parsing.
- Installation & Onboarding — Installing OpenClip, Accessibility permissions setup, and first-launch workflow.
- Preferences & Customization — Customizing action titles, table icons, ordering, and AI provider setup.
- Managing Extensions & Custom Actions — Installing remote and local extensions and script snippet actions.
- App-Specific Policy Rules — Configuring application-level overrides via
AppRuleandrules.json.
The app follows the macOS system language. English is the source locale; Simplified Chinese is bundled in Sources/OpenClip/Resources/Localizable.xcstrings.
OpenClip enforces a strict single-responsibility architecture divided across Core Architectural Subsystems:
- Settings Subsystem —
SettingsStore(TypedSettingKeyaccess; a few legacyUserDefaults.standardsites remain in the App target). - Action Presentation —
ActionCustomizationManager(Surface-tailored icon and title resolution). - Action Chrome Policy —
ActionChrome(UI policy metadata without type checking). - Action Factory —
DefaultActionFactory(Action creation from manifests/snippets). - Action Result Handler —
ActionResultHandler(Platform side-effects, pasteboard, and key events). - Action Coordinator & Composition —
ActionCoordinator(Composition root; wires managers to the registry viaonRegister/onUnregistercallbacks).