Skip to main content

Overview

SuperCmd uses compiled Swift binaries for macOS-specific features that require low-level system access. These native modules run as separate processes and communicate with the main Electron process via stdout/stdin or IPC.
All native modules live in src/native/ and are compiled to standalone executables during the build process. They are unpacked from the asar archive for execution.

Architecture

Native modules follow a consistent architecture:
1

Compilation

Swift source files are compiled to native binaries using swiftc
2

Distribution

Binaries are placed in dist/native/ and unpacked from app.asar
3

Execution

Main process spawns binaries as child processes
4

Communication

JSON messages are exchanged via stdout/stdin

Binary Resolution

SuperCmd resolves native binary paths with asar awareness:
function resolvePackagedUnpackedPath(candidatePath: string): string {
  if (!app.isPackaged) return candidatePath;
  if (!candidatePath.includes('app.asar')) return candidatePath;
  
  // Swap app.asar for app.asar.unpacked
  const unpackedPath = candidatePath.replace('app.asar', 'app.asar.unpacked');
  
  if (fs.existsSync(unpackedPath)) {
    return unpackedPath;
  }
  
  return candidatePath;
}

function getNativeBinaryPath(name: string): string {
  const base = path.join(__dirname, '..', 'native', name);
  return resolvePackagedUnpackedPath(base);
}

Snippet Expander

Purpose

Monitors keyboard input and detects snippet keywords in real-time.

Implementation

// snippet-expander.swift
import Foundation
import AppKit
import ApplicationServices

struct EventPayload: Encodable {
  let keyword: String
  let delimiter: String
}

// Parse keywords from JSON argument
let keywords = Set(parsed.map { $0.lowercased() })
let sortedKeywords = keywords.sorted { $0.count > $1.count }
let maxKeywordLength = max(sortedKeywords.first?.count ?? 1, 1)

var currentToken = ""

// Create keyboard event tap
let eventTap = CGEvent.tapCreate(
  tap: .cgSessionEventTap,
  place: .headInsertEventTap,
  options: .defaultTap,
  eventsOfInterest: (1 << CGEventType.keyDown.rawValue),
  callback: { proxy, type, event, _ in
    let chars = extractTypedCharacters(from: event)
    
    for char in chars {
      processCharacter(char)
    }
    
    return Unmanaged.passRetained(event)
  },
  userInfo: nil
)

// Emit JSON when keyword detected
func emit(keyword: String, delimiter: String) {
  let payload = EventPayload(keyword: keyword, delimiter: delimiter)
  let encoded = try! JSONEncoder().encode(payload)
  let line = String(data: encoded, encoding: .utf8)!
  print(line)
  fflush(stdout)
}

RunLoop.main.run()

Features

  • Tracks a sliding window of typed characters
  • Matches longest keywords first
  • Supports custom delimiter characters
  • Ignores modifier key combinations (Cmd, Ctrl, Alt)
var allowedChars = CharacterSet.alphanumerics
  .union(CharacterSet(charactersIn: "-_"))

var delimiters = CharacterSet.whitespacesAndNewlines
  .union(CharacterSet(charactersIn: ".,!?;:()[]{}<>/\\|@#$%^&*+=`~\"'"))

// Allow any symbol characters in configured keywords
for keyword in keywords {
  for scalar in keyword.unicodeScalars {
    allowedChars.insert(scalar)
    delimiters.remove(scalar)
  }
}

Hotkey Hold Monitor

Purpose

Monitors a specific key combination and emits events when pressed and released.

Implementation

// hotkey-hold-monitor.swift
import Foundation
import CoreGraphics

final class MonitorState {
  let targetKeyCode: CGKeyCode
  let needCmd: Bool
  let needCtrl: Bool
  let needAlt: Bool
  let needShift: Bool
  let needFn: Bool
  var isPressed: Bool
  
  init(targetKeyCode: CGKeyCode, needCmd: Bool, needCtrl: Bool, 
       needAlt: Bool, needShift: Bool, needFn: Bool) {
    self.targetKeyCode = targetKeyCode
    self.needCmd = needCmd
    self.needCtrl = needCtrl
    self.needAlt = needAlt
    self.needShift = needShift
    self.needFn = needFn
    self.isPressed = false
  }
}

func modifiersSatisfied(flags: CGEventFlags, state: MonitorState) -> Bool {
  let cmd = flags.contains(.maskCommand)
  let ctrl = flags.contains(.maskControl)
  let alt = flags.contains(.maskAlternate)
  let shift = flags.contains(.maskShift)
  let fn = flags.contains(.maskSecondaryFn)
  
  return cmd == state.needCmd && ctrl == state.needCtrl &&
         alt == state.needAlt && shift == state.needShift &&
         fn == state.needFn
}

let callback: CGEventTapCallBack = { _, type, event, userInfo in
  let state = Unmanaged<MonitorState>
    .fromOpaque(userInfo!)
    .takeUnretainedValue()
  
  let flags = event.flags
  let keyCode = CGKeyCode(event.getIntegerValueField(.keyboardEventKeycode))
  
  if !state.isPressed {
    if keyCode == state.targetKeyCode && 
       modifiersSatisfied(flags: flags, state: state) {
      state.isPressed = true
      emit(["pressed": true])
    }
    return Unmanaged.passUnretained(event)
  }
  
  if type == .keyUp && keyCode == state.targetKeyCode {
    emit(["released": true, "reason": "key-up"])
    exit(0)
  }
  
  if !modifiersSatisfied(flags: flags, state: state) {
    emit(["released": true, "reason": "modifier-up"])
    exit(0)
  }
  
  return Unmanaged.passUnretained(event)
}

Features

Precise Modifier Detection

Tracks exact modifier key states (Cmd, Ctrl, Alt, Shift, Fn)

Release Reasons

Distinguishes between key-up, modifier-up, and flags-changed events

Low Latency

Direct event tap at kernel level for minimal delay

Process Termination

Exits automatically when key is released

Speech Recognizer

Purpose

Real-time speech-to-text using Apple’s Speech framework.

Implementation

// speech-recognizer.swift
import Foundation
import Speech

class SpeechRecognizerDelegate: NSObject, SFSpeechRecognizerDelegate {
  func speechRecognizer(
    _ speechRecognizer: SFSpeechRecognizer,
    availabilityDidChange available: Bool
  ) {
    emit(["available": available])
  }
}

let recognizer = SFSpeechRecognizer(locale: Locale(identifier: "en-US"))
let audioEngine = AVAudioEngine()

// Request microphone access
AVAudioSession.sharedInstance().requestRecordPermission { granted in
  if !granted {
    emit(["error": "Microphone access denied"])
    exit(1)
  }
}

// Start recognition
let recognitionRequest = SFSpeechAudioBufferRecognitionRequest()
recognitionRequest.shouldReportPartialResults = true

let recognitionTask = recognizer.recognitionTask(
  with: recognitionRequest
) { result, error in
  if let result = result {
    emit([
      "text": result.bestTranscription.formattedString,
      "isFinal": result.isFinal
    ])
    
    if result.isFinal {
      audioEngine.stop()
      audioEngine.inputNode.removeTap(onBus: 0)
      exit(0)
    }
  }
  
  if let error = error {
    emit(["error": error.localizedDescription])
    exit(1)
  }
}

// Capture audio
let inputNode = audioEngine.inputNode
let recordingFormat = inputNode.outputFormat(forBus: 0)

inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) {
  buffer, _ in
  recognitionRequest.append(buffer)
}

audioEngine.prepare()
try audioEngine.start()

emit(["status": "recording"])
RunLoop.main.run()

Integration

function startWhisperRecognition(): Promise<string> {
  return new Promise((resolve, reject) => {
    const binaryPath = getNativeBinaryPath('speech-recognizer');
    const proc = spawn(binaryPath, [], {
      stdio: ['ignore', 'pipe', 'pipe'],
    });
    
    let partialText = '';
    let buffer = '';
    
    proc.stdout.on('data', (chunk) => {
      buffer += chunk.toString();
      const lines = buffer.split('\n');
      buffer = lines.pop() || '';
      
      for (const line of lines) {
        const event = JSON.parse(line);
        
        if (event.status === 'recording') {
          console.log('Whisper: Recording started');
        }
        
        if (event.text) {
          partialText = event.text;
          
          // Send to renderer for live preview
          mainWindow?.webContents.send('whisper-partial', {
            text: partialText,
          });
          
          if (event.isFinal) {
            resolve(partialText);
          }
        }
        
        if (event.error) {
          reject(new Error(event.error));
        }
      }
    });
    
    proc.on('exit', (code) => {
      if (code !== 0 && !partialText) {
        reject(new Error('Speech recognition failed'));
      }
    });
  });
}

Window Management

Window Adjustment

Native Swift module for precise window positioning:
// window-adjust.swift
import Cocoa

func setWindowBounds(windowId: Int, x: Int, y: Int, width: Int, height: Int) {
  let options = CGWindowListOption(arrayLiteral: .excludeDesktopElements)
  let windowList = CGWindowListCopyWindowInfo(options, kCGNullWindowID) 
    as! [[String: Any]]
  
  for info in windowList {
    guard let pid = info[kCGWindowOwnerPID as String] as? Int,
          let id = info[kCGWindowNumber as String] as? Int,
          id == windowId else { continue }
    
    let app = NSRunningApplication(processIdentifier: pid_t(pid))
    guard let app = app else { continue }
    
    let axApp = AXUIElementCreateApplication(pid_t(pid))
    var windowRef: AnyObject?
    
    AXUIElementCopyAttributeValue(
      axApp,
      kAXWindowsAttribute as CFString,
      &windowRef
    )
    
    guard let windows = windowRef as? [AXUIElement] else { continue }
    
    for window in windows {
      // Set position
      var position = CGPoint(x: x, y: y)
      let positionValue = AXValueCreate(.cgPoint, &position)
      AXUIElementSetAttributeValue(
        window,
        kAXPositionAttribute as CFString,
        positionValue!
      )
      
      // Set size
      var size = CGSize(width: width, height: height)
      let sizeValue = AXValueCreate(.cgSize, &size)
      AXUIElementSetAttributeValue(
        window,
        kAXSizeAttribute as CFString,
        sizeValue!
      )
      
      emit(["success": true])
      return
    }
  }
  
  emit(["error": "Window not found"])
}

Color Picker

Native color picker using NSColorPanel:
// color-picker.swift
import Cocoa

class ColorPickerDelegate: NSObject, NSWindowDelegate {
  func windowWillClose(_ notification: Notification) {
    let colorPanel = NSColorPanel.shared
    let color = colorPanel.color
    
    emit([
      "hex": color.hexString,
      "rgb": [
        "r": Int(color.redComponent * 255),
        "g": Int(color.greenComponent * 255),
        "b": Int(color.blueComponent * 255),
      ],
    ])
    
    exit(0)
  }
}

let delegate = ColorPickerDelegate()
let colorPanel = NSColorPanel.shared
colorPanel.delegate = delegate
colorPanel.isContinuous = false
colorPanel.showsAlpha = true
colorPanel.makeKeyAndOrderFront(nil)

RunLoop.main.run()

Permissions Management

Native modules require various macOS permissions:
import ApplicationServices

let options: CFDictionary = [
  kAXTrustedCheckOptionPrompt.takeRetainedValue() as String: true
] as CFDictionary

let trusted = AXIsProcessTrustedWithOptions(options)

if !trusted {
  emit(["error": "Accessibility access required"])
  exit(1)
}

Building Native Modules

Native modules are compiled during the build process:
# Compile Swift source to binary
swiftc -O -o dist/native/snippet-expander src/native/snippet-expander.swift

# Make executable
chmod +x dist/native/snippet-expander

Build Configuration

In package.json:
{
  "build": {
    "asarUnpack": [
      "dist/native/**/*"
    ],
    "files": [
      "dist/**/*",
      "!dist/native/**/*"
    ]
  }
}

Error Handling

Native modules use consistent error reporting:
function handleNativeModuleOutput(line: string, moduleName: string) {
  try {
    const event = JSON.parse(line);
    
    if (event.error) {
      console.error(`[${moduleName}] Error:`, event.error);
      
      // Show user-friendly error
      if (event.error.includes('permission')) {
        showToast({
          style: Toast.Style.Failure,
          title: 'Permission Required',
          message: `${moduleName} needs system permissions`,
        });
      }
      
      return;
    }
    
    // Process success event
    handleModuleEvent(moduleName, event);
  } catch (error) {
    console.error(`[${moduleName}] Invalid JSON:`, line);
  }
}

Best Practices

  • Always clean up child processes on app quit
  • Implement restart logic for crashed processes
  • Use stdout buffering for reliable message parsing
  • Set appropriate timeouts for long-running operations
  • Request permissions gracefully with user prompts
  • Provide clear error messages when permissions are denied
  • Check permission status before spawning processes
  • Guide users to System Settings when needed
  • Spawn processes only when needed
  • Reuse long-running processes when possible
  • Use event taps at appropriate levels (HID vs Session)
  • Minimize JSON parsing overhead

See Also

Extension Runtime

Learn about extension execution

Electron Architecture

Understand the main/renderer process model

Raycast API

API compatibility reference

Build docs developers (and LLMs) love