Modular Design of the Feature Installation System in Vorssaint-utils

Vorssaint-utils implements a modular feature installation system that isolates capability definitions, runtime lifecycle management, and UI metadata through a pipeline of AppFeature, FeatureCatalog, and FeatureRuntime, enabling safe addition and removal of user-facing tools without coupling to the host application.

The open-source Vorssaint-utils repository organizes every user-visible capability—such as Homebrew integration, screen recording, or clipboard management—as a discrete feature managed through a centralized pipeline. This modular design of the feature installation system keeps installation logic isolated from UI code, provides a unified discovery hub, and ensures that adding new capabilities requires only minimal extensions to the core catalog.

Core Architecture: The Feature Pipeline

The system implements a three-layer architecture that separates declaration, metadata, and execution. This pipeline ensures that the host application never depends directly on feature-specific implementations.

AppFeature Enum: The Single Source of Truth

At the foundation of the system lies the AppFeature enum, defined in FeatureCatalog.swift. This String-backed enum conforms to CaseIterable and serves as the canonical registry of every available capability.

import Foundation

enum AppFeature: String, CaseIterable {
    case homebrew
    case screenRecorder
    case clipboardManager
    case diskImageInstaller
    
    // New features are added here as enum cases
}

Each case provides the raw string identifier used for persistence in UserDefaults and for mapping to UI assets. By centralizing feature identity in a single enum, the system eliminates string-typing errors and establishes a compile-time check for feature availability.

FeatureCatalog: Static Metadata Registry

The FeatureCatalog class transforms raw enum values into rich metadata objects. It supplies static information—titles, SF Symbols icons, default enabled states, and settings destinations—through the info(for:) method.

struct FeatureInfo {
    let title: String
    let icon: String
    let defaultEnabled: Bool
    let settingsDestination: FeatureSettingsDestination
}

extension FeatureCatalog {
    static func info(for feature: AppFeature) -> FeatureInfo {
        switch feature {
        case .screenRecorder:
            return FeatureInfo(
                title: FeatureStrings.ScreenRecorder.title,
                icon: "record.circle",
                defaultEnabled: false,
                settingsDestination: .init(.features, sectionAnchor: .screenRecorder)
            )
        case .homebrew:
            return FeatureInfo(
                title: FeatureStrings.Homebrew.title,
                icon: "mug.fill",
                defaultEnabled: true,
                settingsDestination: .init(.features, sectionAnchor: .homebrew)
            )
        // Additional cases...
        }
    }
}

This design keeps UI-specific metadata decoupled from runtime behavior, allowing interface adjustments without touching feature implementation code.

FeatureRuntime: Lifecycle Management

Concrete feature behavior is encapsulated in FeatureRuntime.swift. This component owns the full lifecycle of feature runtime objects—including hot-key handlers, menu bar extras, and file system observers—without requiring knowledge of specific implementation details.

When a user enables a feature, FeatureRuntime invokes a registered closure that instantiates the concrete implementation. It manages four distinct phases:

  1. Creation – Allocates feature-specific objects (e.g., ScreenRecorder())
  2. Start – Activates observers and registers hot keys
  3. Stop – Deactivates observers while preserving state
  4. Teardown – Releases resources when the feature is disabled or the app terminates
// Simplified registration pattern used by FeatureRuntime
FeatureRuntime.shared.register(.screenRecorder) {
    return ScreenRecorder() // Returns an object conforming to FeatureProtocol
}

Because each feature registers its own runtime closure through the catalog, the core runtime remains agnostic about which specific capabilities are active, satisfying the inversion-of-control principle.

Supporting Infrastructure for Discovery and Localization

FeatureSettingsDestination and Deep Linking

The FeatureSettingsDestination struct, referenced within FeatureInfo, describes where a feature's settings UI resides within the application's preferences window. This enables deep linking from the Features hub directly to a specific configuration pane.

struct FeatureSettingsDestination {
    let pane: SettingsPane
    let sectionAnchor: SettingsSectionAnchor?
}

When a user clicks a feature tile in the catalog view, the system uses this destination to navigate precisely to the correct settings page, eliminating manual navigation hunting.

SettingsSearchSupport: Unified Discovery

To ensure features remain discoverable, SettingsSearchSupport.swift generates searchable index entries. It performs a merge operation that combines feature pages (e.g., "Features") with individual feature entries (e.g., "Screen Recorder"), guaranteeing that users can locate capabilities either by category or by specific name.

This merging prevents search fragmentation—users find the Screen Recorder whether they search for "record" or browse the "Features" section.

FeatureStrings: Centralized Localization

All user-facing text resides in FeatureStrings.swift, organized by feature namespace. This centralization reduces duplication across UI components and keeps the feature definition layer language-agnostic.

enum FeatureStrings {
    enum ScreenRecorder {
        static let title = NSLocalizedString("feature.screenRecorder.title", comment: "")
        static let tooltip = NSLocalizedString("feature.screenRecorder.tooltip", comment: "")
    }
}

Safe Removal and Uninstallation

The modular design extends to feature removal through UninstallerSupport.swift and its UI counterpart UninstallerView.swift.

Bundle Verification and Exclusive Ownership

Before deleting any files, UninstallerSupport performs bundle-ID verification and exclusive-ownership checks:

  • Bundle-ID verification confirms that the target bundle matches the feature's registered identifier, preventing accidental deletion of unrelated packages.
  • Exclusive-ownership checks ensure that no other active feature depends on the resource being removed.
// Conceptual implementation based on UninstallerSupport logic
func uninstall(feature: AppFeature) throws {
    let bundleID = FeatureCatalog.bundleIdentifier(for: feature)
    guard Bundle.validate(identifier: bundleID) else {
        throw UninstallerError.invalidBundle
    }
    
    let resources = FeatureCatalog.resources(for: feature)
    for resource in resources {
        guard !isShared(resource) else { continue }
        try FileManager.default.removeItem(at: resource)
    }
}

This safety mechanism preserves user data when appropriate and prevents "orphaned" dependencies that could destabilize remaining features.

Extending the System: Adding a New Feature

The modular architecture minimizes boilerplate when introducing new capabilities. To add a feature called myNewTool:

  1. Extend the enum in FeatureCatalog.swift:
enum AppFeature: String, CaseIterable {
    // Existing cases...
    case myNewTool
}
  1. Provide metadata in the catalog extension:
case .myNewTool:
    return FeatureInfo(
        title: FeatureStrings.MyNewTool.title,
        icon: "wrench.and.screwdriver",
        defaultEnabled: false,
        settingsDestination: .init(.features, sectionAnchor: .myNewTool)
    )
  1. Register the runtime in your feature module:
// In MyNewTool.swift
FeatureRuntime.shared.register(.myNewTool) {
    return MyNewToolController()
}
  1. Add localization to FeatureStrings.swift.

No changes are required to the search system, uninstaller, or settings infrastructure—the pipeline automatically incorporates the new feature through the existing contract.

Summary

The Vorssaint-utils feature installation system demonstrates a clean separation of concerns through its modular pipeline:

  • Single source of truth: The AppFeature enum centralizes identifiers and prevents string-typing errors.
  • Metadata isolation: FeatureCatalog decouples UI descriptions from runtime behavior, allowing interface changes without touching feature logic.
  • Lifecycle inversion: FeatureRuntime manages activation and teardown via registered closures, keeping the core application agnostic of implementation details.
  • Unified discovery: SettingsSearchSupport merges feature pages and individual entries, ensuring consistent searchability.
  • Safe removal: UninstallerSupport verifies bundle ownership and checks for shared dependencies before deletion.

Together, these components form an extensible architecture where features are plugins rather than integrated code branches, reducing maintenance overhead and installation risk.

Frequently Asked Questions

How does FeatureRuntime manage feature lifecycles without knowing implementation details?

FeatureRuntime relies on dependency injection via registration closures. Each feature module registers a factory closure with FeatureRuntime.shared.register(_:factory:) that returns an object conforming to a FeatureProtocol. The runtime stores these factories in a dictionary keyed by AppFeature, invoking them only when the user toggles a feature on. This allows the runtime to start, stop, and tear down live objects without importing the concrete types, maintaining strict modularity.

What prevents accidental deletion of shared resources during uninstallation?

The UninstallerSupport class implements exclusive-ownership checks before removing any file. It queries FeatureCatalog.resources(for:) to obtain a feature's resource list, then filters against a registry of shared system components. If a resource is marked as shared (used by multiple features or the host OS), the uninstaller skips that item and logs the preservation. Additionally, bundle-ID verification ensures that only packages explicitly registered to the feature are targeted, preventing cross-contamination with unrelated applications.

How do I add a new feature to the Vorssaint-utils installation system?

Adding a feature requires three steps: (1) Append a case to the AppFeature enum in FeatureCatalog.swift; (2) Supply metadata (title, icon, default state) in the FeatureCatalog.info(for:) switch statement; (3) Register a runtime factory in your feature-specific module using FeatureRuntime.shared.register(). The existing infrastructure for search, settings navigation, and uninstallation automatically picks up the new capability through the AppFeature identifier.

Where is feature localization handled in the codebase?

All localized strings reside in FeatureStrings.swift within nested enums organized by feature name (e.g., FeatureStrings.ScreenRecorder). This centralization ensures that translators work within a single file per language, and that UI components reference constants rather than hard-coded strings. The FeatureCatalog accesses these strings when constructing FeatureInfo objects, keeping the metadata layer locale-aware without polluting feature implementation code.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →