or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

app-lifecycle.mddevelopment.mdindex.mdipc.mdmenu-system.mdnetwork-protocols.mdplatform-features.mdsecurity.mdsystem-integration.mdwindow-management.md
tile.json

platform-features.mddocs/

Platform-Specific Features

Platform-specific APIs for macOS, Windows, and Linux, including auto-updater, system preferences, and native integrations.

Capabilities

System Preferences

Access and monitor system preferences and theme information.

/**
 * Get system preferences
 */
interface SystemPreferences extends EventEmitter {
  /** Returns true if DarkAqua/DarkMode theme is active */
  isDarkMode(): boolean;
  
  /** Returns true if an inverted color scheme (high contrast with light text and dark backgrounds) is active */
  isInvertedColorScheme(): boolean;
  
  /** Returns true if a high contrast theme is active */
  isHighContrastColorScheme(): boolean;
  
  /** Returns the system color setting in hex format (#ABCDEF) */
  getAccentColor(): string;
  
  /** Returns the system color for the given color key */
  getSystemColor(color: SystemColor): string;
  
  /** Returns true if the Caps Lock key is currently on */
  isAeroGlassEnabled(): boolean;
  
  /** Returns the standard system color formatted as #RRGGBBAA for the given color */
  getColor(color: string): string;
  
  /** Returns true if the current process is a trusted accessibility client */
  isTrustedAccessibilityClient(prompt: boolean): boolean;
  
  /** Retrieves a macOS system preference value by key */
  getUserDefault(key: string, type: 'string' | 'boolean' | 'integer' | 'float' | 'double' | 'url' | 'array' | 'dictionary'): any;
  
  /** Set a macOS system preference value by key */
  setUserDefault(key: string, type: string, value: string): void;
  
  /** Removes the key in macOS system preferences */
  removeUserDefault(key: string): void;
  
  /** Returns true if the macOS system's Reduce Motion accessibility preference is enabled */
  isSwipeTrackingFromScrollEventsEnabled(): boolean;
  
  /** Posts event to macOS accessibility API */
  postNotification(event: string, userInfo: Record<string, any>, deliverImmediately?: boolean): void;
  
  /** Posts a local notification event to macOS accessibility API */
  postLocalNotification(event: string, userInfo: Record<string, any>): void;
  
  /** Posts a workspace notification event to macOS accessibility API */
  postWorkspaceNotification(event: string, userInfo: Record<string, any>): void;
  
  /** Subscribes to native macOS notifications */
  subscribeNotification(event: string, callback: (event: string, userInfo: Record<string, any>, object: string) => void): number;
  
  /** Same as subscribeNotification, but uses NSNotificationCenter's addObserverForName:object:queue:usingBlock: for local notifications */
  subscribeLocalNotification(event: string, callback: (event: string, userInfo: Record<string, any>, object: string) => void): number;
  
  /** Same as subscribeNotification, but uses NSWorkspace.sharedWorkspace.notificationCenter */
  subscribeWorkspaceNotification(event: string, callback: (event: string, userInfo: Record<string, any>, object: string) => void): number;
  
  /** Removes the subscriber with id */
  unsubscribeNotification(id: number): void;
  
  /** Same as unsubscribeNotification, but removes the subscriber from NSNotificationCenter */
  unsubscribeLocalNotification(id: number): void;
  
  /** Same as unsubscribeNotification, but removes the subscriber from NSWorkspace.sharedWorkspace.notificationCenter */
  unsubscribeWorkspaceNotification(id: number): void;
  
  /** Returns an object with system animation settings */
  getAnimationSettings(): AnimationSettings;
  
  /** A string property that can be dark, light or unknown */
  readonly effectiveAppearance: string;
  
  /** A string property that can be dark, light or unknown */
  readonly appLevelAppearance: string;
}

declare const systemPreferences: SystemPreferences;

Usage Examples:

const { systemPreferences, nativeTheme } = require('electron');

// Monitor system theme changes
function setupThemeMonitoring() {
  // Check current theme
  const isDark = systemPreferences.isDarkMode();
  console.log('System is in dark mode:', isDark);
  
  // Listen for theme changes
  systemPreferences.on('accent-color-changed', (event, newColor) => {
    console.log('Accent color changed:', newColor);
    updateAppTheme(newColor);
  });
  
  systemPreferences.on('color-changed', (event) => {
    console.log('System colors changed');
    updateAppColors();
  });
  
  systemPreferences.on('inverted-color-scheme-changed', (event, invertedColorScheme) => {
    console.log('Inverted color scheme:', invertedColorScheme);
    updateAppForAccessibility(invertedColorScheme);
  });
  
  systemPreferences.on('high-contrast-color-scheme-changed', (event, highContrastColorScheme) => {
    console.log('High contrast mode:', highContrastColorScheme);
    updateAppForHighContrast(highContrastColorScheme);
  });
}

// Get system colors
function getSystemColors() {
  const colors = {
    accent: systemPreferences.getAccentColor(),
    windowBackground: systemPreferences.getSystemColor('window'),
    text: systemPreferences.getSystemColor('windowText'),
    highlight: systemPreferences.getSystemColor('highlight'),
    secondaryText: systemPreferences.getSystemColor('secondaryLabelColor')
  };
  
  console.log('System colors:', colors);
  return colors;
}

// macOS specific features
function setupMacOSFeatures() {
  if (process.platform !== 'darwin') return;
  
  // Check accessibility permissions
  const isTrusted = systemPreferences.isTrustedAccessibilityClient(false);
  if (!isTrusted) {
    console.log('App needs accessibility permissions');
    // Prompt user for permissions
    systemPreferences.isTrustedAccessibilityClient(true);
  }
  
  // Subscribe to workspace notifications
  const workspaceId = systemPreferences.subscribeWorkspaceNotification(
    'NSWorkspaceDidWakeNotification',
    (event, userInfo) => {
      console.log('System woke from sleep');
      handleSystemWake();
    }
  );
  
  // Subscribe to application notifications
  const appId = systemPreferences.subscribeNotification(
    'AppleInterfaceThemeChangedNotification',
    (event, userInfo) => {
      console.log('Interface theme changed');
      updateAppTheme();
    }
  );
  
  // Get/set user defaults
  const launchAtLogin = systemPreferences.getUserDefault('LSUIElement', 'boolean');
  console.log('Launch at login:', launchAtLogin);
  
  // Set a custom preference
  systemPreferences.setUserDefault('MyAppPreference', 'string', 'customValue');
  
  return { workspaceId, appId };
}

Auto Updater

Automatic application updates using platform-specific update mechanisms.

/**
 * Enable apps to automatically update themselves
 */
interface AutoUpdater extends EventEmitter {
  /** Sets the url and initialize the auto updater */
  setFeedURL(options: FeedURLOptions): void;
  
  /** Returns the current update feed URL */
  getFeedURL(): string;
  
  /** Asks the server whether there is an update */
  checkForUpdates(): void;
  
  /** Asks the server whether there is an update, returns a boolean */
  checkForUpdatesAndNotify(): Promise<UpdateCheckResult | null>;
  
  /** Restarts the app and installs the update after it has been downloaded */
  quitAndInstall(): void;
  
  /** Returns the current application version */
  getSupportedDirectoryTypes(): string[];
}

declare const autoUpdater: AutoUpdater;

Usage Examples:

const { autoUpdater, app, dialog } = require('electron');

// Setup auto-updater
function setupAutoUpdater() {
  // Configure update feed
  autoUpdater.setFeedURL({
    url: 'https://updates.myapp.com/releases',
    headers: {
      'User-Agent': `MyApp/${app.getVersion()}`
    }
  });
  
  // Handle update events
  autoUpdater.on('checking-for-update', () => {
    console.log('Checking for updates...');
    showUpdateStatus('Checking for updates...');
  });
  
  autoUpdater.on('update-available', (info) => {
    console.log('Update available:', info);
    showUpdateStatus('Update available - downloading...');
  });
  
  autoUpdater.on('update-not-available', (info) => {
    console.log('Update not available:', info);
    showUpdateStatus('App is up to date');
  });
  
  autoUpdater.on('error', (err) => {
    console.error('Update error:', err);
    dialog.showErrorBox('Update Error', err.message);
  });
  
  autoUpdater.on('download-progress', (progressObj) => {
    const { bytesPerSecond, percent, transferred, total } = progressObj;
    console.log(`Download progress: ${percent.toFixed(2)}%`);
    showUpdateProgress(percent);
  });
  
  autoUpdater.on('update-downloaded', (info) => {
    console.log('Update downloaded:', info);
    showUpdateReadyDialog();
  });
  
  // Check for updates on startup
  setTimeout(() => {
    autoUpdater.checkForUpdates();
  }, 3000);
  
  // Check for updates every hour
  setInterval(() => {
    autoUpdater.checkForUpdates();
  }, 60 * 60 * 1000);
}

// Show update ready dialog
function showUpdateReadyDialog() {
  const response = dialog.showMessageBoxSync(null, {
    type: 'info',
    title: 'Update Ready',
    message: 'A new version has been downloaded.',
    detail: 'The application will restart to apply the update.',
    buttons: ['Restart Now', 'Later'],
    defaultId: 0,
    cancelId: 1
  });
  
  if (response === 0) {
    autoUpdater.quitAndInstall();
  }
}

// Manual update check
async function checkForUpdatesManually() {
  try {
    const result = await autoUpdater.checkForUpdatesAndNotify();
    if (result) {
      console.log('Update check result:', result);
    } else {
      dialog.showMessageBox(null, {
        type: 'info',
        title: 'No Updates',
        message: 'You are running the latest version.'
      });
    }
  } catch (error) {
    console.error('Manual update check failed:', error);
    dialog.showErrorBox('Update Check Failed', error.message);
  }
}

Power Monitor

Monitor system power state and prevent system sleep.

/**
 * Monitor power state changes
 */
interface PowerMonitor extends EventEmitter {
  /** Returns the system's current idle state */
  getSystemIdleState(idleThreshold: number): 'active' | 'idle' | 'locked' | 'unknown';
  
  /** Returns the number of seconds the system has been idle */
  getSystemIdleTime(): number;
  
  /** Returns the system's current thermal state */
  getCurrentThermalState(): 'unknown' | 'nominal' | 'fair' | 'serious' | 'critical';
  
  /** Returns true if the system is on battery power */
  isOnBatteryPower(): boolean;
}

declare const powerMonitor: PowerMonitor;

/**
 * Block the system from entering low-power (sleep) mode
 */
interface PowerSaveBlocker {
  /** Starts preventing the system from entering lower-power mode */
  start(type: 'prevent-app-suspension' | 'prevent-display-sleep'): number;
  
  /** Stops the specified power save blocker */
  stop(id: number): void;
  
  /** Returns whether the corresponding powerSaveBlocker has started */
  isStarted(id: number): boolean;
}

declare const powerSaveBlocker: PowerSaveBlocker;

Usage Examples:

const { powerMonitor, powerSaveBlocker, app } = require('electron');

// Setup power monitoring
function setupPowerMonitoring() {
  // Monitor power events
  powerMonitor.on('suspend', () => {
    console.log('System is going to sleep');
    handleSystemSuspend();
  });
  
  powerMonitor.on('resume', () => {
    console.log('System is resuming');
    handleSystemResume();
  });
  
  powerMonitor.on('on-ac', () => {
    console.log('System is on AC power');
    handleACPower();
  });
  
  powerMonitor.on('on-battery', () => {
    console.log('System is on battery power');
    handleBatteryPower();
  });
  
  powerMonitor.on('shutdown', () => {
    console.log('System is shutting down');
    handleSystemShutdown();
  });
  
  powerMonitor.on('lock-screen', () => {
    console.log('System is locking');
    handleScreenLock();
  });
  
  powerMonitor.on('unlock-screen', () => {
    console.log('System is unlocking');
    handleScreenUnlock();
  });
  
  powerMonitor.on('user-did-become-active', () => {
    console.log('User became active');
    handleUserActive();
  });
  
  powerMonitor.on('user-did-resign-active', () => {
    console.log('User resigned active');
    handleUserInactive();
  });
  
  // Check initial power state
  const isOnBattery = powerMonitor.isOnBatteryPower();
  console.log('On battery:', isOnBattery);
  
  const thermalState = powerMonitor.getCurrentThermalState();
  console.log('Thermal state:', thermalState);
}

// Power save blocking
let displayBlockerId = null;
let systemBlockerId = null;

function preventSystemSleep() {
  if (!systemBlockerId) {
    systemBlockerId = powerSaveBlocker.start('prevent-app-suspension');
    console.log('Preventing system sleep, ID:', systemBlockerId);
  }
}

function allowSystemSleep() {
  if (systemBlockerId) {
    powerSaveBlocker.stop(systemBlockerId);
    console.log('Allowing system sleep');
    systemBlockerId = null;
  }
}

function preventDisplaySleep() {
  if (!displayBlockerId) {
    displayBlockerId = powerSaveBlocker.start('prevent-display-sleep');
    console.log('Preventing display sleep, ID:', displayBlockerId);
  }
}

function allowDisplaySleep() {
  if (displayBlockerId) {
    powerSaveBlocker.stop(displayBlockerId);
    console.log('Allowing display sleep');
    displayBlockerId = null;
  }
}

// Monitor user activity
function monitorUserActivity() {
  setInterval(() => {
    const idleTime = powerMonitor.getSystemIdleTime();
    const idleState = powerMonitor.getSystemIdleState(60); // 60 seconds threshold
    
    console.log(`Idle time: ${idleTime}s, State: ${idleState}`);
    
    if (idleState === 'idle' && idleTime > 300) { // 5 minutes
      console.log('User has been idle for 5+ minutes');
      handleUserIdle();
    }
  }, 30000); // Check every 30 seconds
}

// Handle thermal state changes
function handleThermalState() {
  powerMonitor.on('thermal-state-change', (state) => {
    console.log('Thermal state changed:', state);
    
    switch (state) {
      case 'critical':
        console.warn('System is critically hot!');
        // Reduce app performance
        reducePerformance();
        break;
      case 'serious':
        console.warn('System is getting hot');
        // Moderate performance reduction
        moderatePerformance();
        break;
      case 'nominal':
        console.log('System temperature is normal');
        // Restore full performance
        restorePerformance();
        break;
    }
  });
}

In-App Purchase (macOS/Windows)

Handle in-app purchases on supported platforms.

/**
 * In-app purchases on Mac App Store and Microsoft Store
 */
interface InAppPurchase extends EventEmitter {
  /** Returns true if the system allows purchases */
  canMakePayments(): boolean;
  
  /** Retrieves the product descriptions */
  getProducts(productIDs: string[]): Promise<Product[]>;
  
  /** Purchase the product */
  purchaseProduct(productID: string, quantity?: number): Promise<boolean>;
  
  /** Retrieves and consumes all unconsumed transactions */
  getReceiptURL(): string;
  
  /** Finishes all pending transactions */
  finishAllTransactions(): void;
  
  /** Finishes the pending transactions corresponding to the date */
  finishTransactionByDate(date: string): void;
}

declare const inAppPurchase: InAppPurchase;

Usage Examples:

const { inAppPurchase } = require('electron');

// Setup in-app purchases
function setupInAppPurchases() {
  if (!inAppPurchase.canMakePayments()) {
    console.log('In-app purchases not available');
    return;
  }
  
  // Handle transaction updates
  inAppPurchase.on('transactions-updated', (event, transactions) => {
    transactions.forEach((transaction) => {
      console.log('Transaction:', transaction);
      
      switch (transaction.transactionState) {
        case 'purchasing':
          console.log('Purchase in progress...');
          break;
        case 'purchased':
          console.log('Purchase successful!');
          handleSuccessfulPurchase(transaction);
          break;
        case 'failed':
          console.log('Purchase failed:', transaction.errorMessage);
          handleFailedPurchase(transaction);
          break;
        case 'restored':
          console.log('Purchase restored');
          handleRestoredPurchase(transaction);
          break;
        case 'deferred':
          console.log('Purchase deferred');
          break;
      }
    });
  });
}

// Get available products
async function loadProducts() {
  try {
    const productIds = ['com.myapp.premium', 'com.myapp.addon1', 'com.myapp.addon2'];
    const products = await inAppPurchase.getProducts(productIds);
    
    console.log('Available products:', products);
    return products;
  } catch (error) {
    console.error('Failed to load products:', error);
    return [];
  }
}

// Purchase a product
async function purchaseProduct(productId) {
  try {
    const success = await inAppPurchase.purchaseProduct(productId);
    
    if (success) {
      console.log('Purchase initiated successfully');
    } else {
      console.log('Purchase failed to initiate');
    }
  } catch (error) {
    console.error('Purchase error:', error);
  }
}

Types

type SystemColor = 
  | 'blue'
  | 'brown'
  | 'gray'
  | 'green'
  | 'orange'
  | 'pink'
  | 'purple'
  | 'red'
  | 'yellow'
  | 'window'
  | 'windowText'
  | 'controlBackground'
  | 'control'
  | 'controlText'
  | 'disabledControlText'
  | 'selectedControlText'
  | 'selectedControlBackground'
  | 'windowBackground'
  | 'underPageBackground'
  | 'label'
  | 'secondaryLabelColor'
  | 'tertiaryLabelColor'
  | 'quaternaryLabelColor'
  | 'textColor'
  | 'placeholderTextColor'
  | 'selectedTextColor'
  | 'selectedTextBackgroundColor'
  | 'keyboardFocusIndicatorColor'
  | 'unemphasizedSelectedTextColor'
  | 'unemphasizedSelectedTextBackgroundColor'
  | 'linkColor'
  | 'separatorColor'
  | 'selectedContentBackgroundColor'
  | 'unemphasizedSelectedContentBackgroundColor'
  | 'selectedMenuItemTextColor'
  | 'gridColor'
  | 'headerTextColor'
  | 'alternatingContentBackgroundColors'
  | 'controlAccentColor'
  | 'controlAlternatingRowBackgroundColors';

interface AnimationSettings {
  shouldRenderRichAnimation: boolean;
  scrollAnimationsEnabledBySystem: boolean;
  prefersReducedFrameRate: boolean;
}

interface FeedURLOptions {
  url: string;
  headers?: Record<string, string>;
  serverType?: 'json' | 'default';
}

interface UpdateCheckResult {
  updateInfo: UpdateInfo;
  downloadPromise?: Promise<any>;
  cancellationToken?: CancellationToken;
  versionInfo?: VersionInfo;
}

interface UpdateInfo {
  version: string;
  files: Array<{
    url: string;
    sha512: string;
    size: number;
  }>;
  releaseName?: string;
  releaseNotes?: string;
  releaseDate: string;
  stagingPercentage?: number;
}

interface Product {
  productIdentifier: string;
  localizedDescription: string;
  localizedTitle: string;
  contentVersion: string;
  contentLengths: number[];
  price: number;
  formattedPrice: string;
  currencyCode: string;
  downloadContentLengths: number[];
  downloadContentVersion: string;
}

interface Transaction {
  transactionIdentifier: string;
  transactionDate: string;
  originalTransactionIdentifier: string;
  transactionState: 'purchasing' | 'purchased' | 'failed' | 'restored' | 'deferred';
  errorCode: number;
  errorMessage: string;
  productIdentifier: string;
  quantity: number;
}