codex-plusplus-tweak-system

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Codex++ Tweak System

Codex++ Tweak 系统

Skill by ara.so — Codex Skills collection.
Codex++ is a tweak system for the Codex desktop app that lets you inject custom features, fix UI bugs, and manage extensions without rebuilding the app. It patches the local Codex installation to load a runtime that discovers and executes small ESM modules (tweaks) with full access to the Electron renderer process.
ara.so 开发的Skill — Codex Skills 合集。
Codex++ 是 Codex 桌面应用的tweak系统,无需重新构建应用,即可注入自定义功能、修复UI漏洞并管理扩展。它会修补本地Codex安装包,加载一个运行时环境,用于发现并执行小型ESM模块(tweaks),这些模块拥有Electron渲染进程的完整访问权限。

Installation

安装

macOS/Linux (Homebrew)

macOS/Linux(Homebrew)

bash
brew install b-nnett/codex-plusplus/codexplusplus
codexplusplus install
bash
brew install b-nnett/codex-plusplus/codexplusplus
codexplusplus install

macOS/Linux (Source Bootstrap)

macOS/Linux(源码引导)

bash
curl -fsSL https://raw.githubusercontent.com/b-nnett/codex-plusplus/main/install.sh | bash
bash
curl -fsSL https://raw.githubusercontent.com/b-nnett/codex-plusplus/main/install.sh | bash

Windows (PowerShell)

Windows(PowerShell)

powershell
irm https://raw.githubusercontent.com/b-nnett/codex-plusplus/main/install.ps1 | iex
powershell
irm https://raw.githubusercontent.com/b-nnett/codex-plusplus/main/install.ps1 | iex

Using Bun

使用 Bun

bash
bun install -g github:b-nnett/codex-plusplus
codexplusplus install
What the installer does:
  • Backs up Codex.app to
    ~/.codex-plusplus/backup/
  • Patches
    app.asar
    to load the Codex++ runtime
  • Re-signs the app with a local signing identity (macOS)
  • Installs a watcher that auto-repairs on Codex updates
  • Installs default tweaks from GitHub releases
Installation flags:
  • --no-default-tweaks
    — Skip installing default tweaks
  • --local
    — Use stable local signing identity (macOS)
bash
bun install -g github:b-nnett/codex-plusplus
codexplusplus install
安装器执行的操作:
  • 将 Codex.app 备份至
    ~/.codex-plusplus/backup/
  • 修补
    app.asar
    以加载 Codex++ 运行时
  • 使用本地签名身份重新签名应用(macOS)
  • 安装监控程序,在Codex更新时自动修复
  • 从GitHub版本库安装默认tweaks
安装参数:
  • --no-default-tweaks
    — 跳过安装默认tweaks
  • --local
    — 使用稳定的本地签名身份(macOS)

Key Commands

核心命令

bash
undefined
bash
undefined

Check installation status

检查安装状态

codexplusplus status
codexplusplus status

Validate and repair installation

验证并修复安装

codexplusplus doctor codexplusplus repair
codexplusplus doctor codexplusplus repair

Update Codex++ to latest release

将Codex++更新至最新版本

codexplusplus update
codexplusplus update

Update Codex++ from development branch (advanced)

从开发分支更新Codex++(高级功能)

codexplusplus update --ref main
codexplusplus update --ref main

Update Codex app itself (macOS - required for patched apps)

更新Codex应用本身(macOS - 修补后的应用需要执行此操作)

codexplusplus update-codex
codexplusplus update-codex

Create a new tweak from template

从模板创建新tweak

codexplusplus create-tweak my-tweak
codexplusplus create-tweak my-tweak

Validate tweak manifest and structure

验证tweak的清单文件与结构

codexplusplus validate-tweak ~/path/to/tweak
codexplusplus validate-tweak ~/path/to/tweak

Enter safe mode (disable all tweaks)

进入安全模式(禁用所有tweaks)

codexplusplus safe-mode codexplusplus safe-mode --off
codexplusplus safe-mode codexplusplus safe-mode --off

Development mode (watch and reload)

开发模式(监控文件变化并自动重载)

codexplusplus dev
codexplusplus dev

Uninstall Codex++ completely

完全卸载Codex++

codexplusplus uninstall
undefined
codexplusplus uninstall
undefined

User Data Directories

用户数据目录

OSLocation
macOS
~/Library/Application Support/codex-plusplus/
Linux
~/.local/share/codex-plusplus/
Windows
%APPDATA%/codex-plusplus/
Directory structure:
codex-plusplus/
├── runtime/          # Codex++ runtime code
├── tweaks/           # Installed tweaks
│   ├── my-tweak/
│   │   ├── manifest.json
│   │   └── index.js
├── config.json       # Runtime configuration
└── backup/           # Codex.app backup
操作系统路径
macOS
~/Library/Application Support/codex-plusplus/
Linux
~/.local/share/codex-plusplus/
Windows
%APPDATA%/codex-plusplus/
目录结构:
codex-plusplus/
├── runtime/          # Codex++ 运行时代码
├── tweaks/           # 已安装的tweaks
│   ├── my-tweak/
│   │   ├── manifest.json
│   │   └── index.js
├── config.json       # 运行时配置
└── backup/           # Codex.app 备份

Creating a Tweak

创建Tweak

Minimal Tweak Structure

最简Tweak结构

my-tweak/
├── manifest.json
└── index.js
my-tweak/
├── manifest.json
└── index.js

manifest.json

manifest.json

json
{
  "id": "com.example.my-tweak",
  "name": "My Tweak",
  "version": "1.0.0",
  "githubRepo": "username/my-tweak",
  "author": "Your Name",
  "description": "Adds custom functionality to Codex",
  "minRuntime": "0.1.0"
}
Required fields:
  • id
    — Reverse-DNS unique identifier
  • name
    — Display name
  • version
    — Semver version
  • githubRepo
    owner/repo
    for update checks
  • minRuntime
    — Minimum Codex++ runtime version
json
{
  "id": "com.example.my-tweak",
  "name": "My Tweak",
  "version": "1.0.0",
  "githubRepo": "username/my-tweak",
  "author": "Your Name",
  "description": "Adds custom functionality to Codex",
  "minRuntime": "0.1.0"
}
必填字段:
  • id
    — 反向DNS格式的唯一标识符
  • name
    — 显示名称
  • version
    — Semver版本号
  • githubRepo
    — 用于更新检查的
    owner/repo
    格式
  • minRuntime
    — 所需的最低Codex++运行时版本

Basic Tweak (JavaScript)

基础Tweak(JavaScript)

javascript
// index.js
export default {
  start(api) {
    api.log.info('Tweak started');
    
    // Add settings panel
    api.settings.register({
      id: 'my-tweak',
      title: 'My Tweak Settings',
      render: (root) => {
        root.innerHTML = `
          <div>
            <h3>Custom Settings</h3>
            <button id="test-btn">Click me</button>
          </div>
        `;
        
        root.querySelector('#test-btn').addEventListener('click', () => {
          api.log.info('Button clicked!');
        });
      }
    });
  },
  
  stop() {
    // Cleanup resources
  }
};
javascript
// index.js
export default {
  start(api) {
    api.log.info('Tweak started');
    
    // 添加设置面板
    api.settings.register({
      id: 'my-tweak',
      title: 'My Tweak Settings',
      render: (root) => {
        root.innerHTML = `
          <div>
            <h3>Custom Settings</h3>
            <button id="test-btn">Click me</button>
          </div>
        `;
        
        root.querySelector('#test-btn').addEventListener('click', () => {
          api.log.info('Button clicked!');
        });
      }
    });
  },
  
  stop() {
    // 清理资源
  }
};

TypeScript Tweak with Full API

完整API的TypeScript Tweak

typescript
// index.ts
import type { Tweak, CodexPlusPlusAPI } from "@codex-plusplus/sdk";

interface MyTweakConfig {
  enabled: boolean;
  customColor: string;
}

export default {
  start(api: CodexPlusPlusAPI) {
    // Access configuration
    const config = api.config.get<MyTweakConfig>('my-tweak', {
      enabled: true,
      customColor: '#ff0000'
    });
    
    // Logging
    api.log.info('Starting tweak with config:', config);
    api.log.warn('This is a warning');
    api.log.error('This is an error');
    
    // DOM manipulation
    const observer = new MutationObserver(() => {
      const chatInput = document.querySelector('[contenteditable="true"]');
      if (chatInput && config.enabled) {
        chatInput.style.borderColor = config.customColor;
      }
    });
    
    observer.observe(document.body, {
      childList: true,
      subtree: true
    });
    
    // Settings panel with persistence
    api.settings.register({
      id: 'my-tweak',
      title: 'My Tweak',
      render: (root) => {
        root.innerHTML = `
          <div class="tweak-settings">
            <label>
              <input type="checkbox" id="enabled" ${config.enabled ? 'checked' : ''}>
              Enable custom styling
            </label>
            <label>
              Custom color:
              <input type="color" id="color" value="${config.customColor}">
            </label>
            <button id="save">Save</button>
          </div>
        `;
        
        root.querySelector('#save')?.addEventListener('click', () => {
          const enabled = (root.querySelector('#enabled') as HTMLInputElement).checked;
          const customColor = (root.querySelector('#color') as HTMLInputElement).value;
          
          api.config.set('my-tweak', { enabled, customColor });
          api.log.info('Settings saved');
          
          // Reload to apply changes
          location.reload();
        });
      }
    });
    
    // Store observer for cleanup
    (api as any)._observer = observer;
  },
  
  stop() {
    const observer = (this as any)._observer;
    if (observer) {
      observer.disconnect();
    }
  }
} satisfies Tweak;
typescript
// index.ts
import type { Tweak, CodexPlusPlusAPI } from "@codex-plusplus/sdk";

interface MyTweakConfig {
  enabled: boolean;
  customColor: string;
}

export default {
  start(api: CodexPlusPlusAPI) {
    // 获取配置
    const config = api.config.get<MyTweakConfig>('my-tweak', {
      enabled: true,
      customColor: '#ff0000'
    });
    
    // 日志功能
    api.log.info('Starting tweak with config:', config);
    api.log.warn('This is a warning');
    api.log.error('This is an error');
    
    // DOM操作
    const observer = new MutationObserver(() => {
      const chatInput = document.querySelector('[contenteditable="true"]');
      if (chatInput && config.enabled) {
        chatInput.style.borderColor = config.customColor;
      }
    });
    
    observer.observe(document.body, {
      childList: true,
      subtree: true
    });
    
    // 带持久化的设置面板
    api.settings.register({
      id: 'my-tweak',
      title: 'My Tweak',
      render: (root) => {
        root.innerHTML = `
          <div class="tweak-settings">
            <label>
              <input type="checkbox" id="enabled" ${config.enabled ? 'checked' : ''}>
              Enable custom styling
            </label>
            <label>
              Custom color:
              <input type="color" id="color" value="${config.customColor}">
            </label>
            <button id="save">Save</button>
          </div>
        `;
        
        root.querySelector('#save')?.addEventListener('click', () => {
          const enabled = (root.querySelector('#enabled') as HTMLInputElement).checked;
          const customColor = (root.querySelector('#color') as HTMLInputElement).value;
          
          api.config.set('my-tweak', { enabled, customColor });
          api.log.info('Settings saved');
          
          // 重载以应用更改
          location.reload();
        });
      }
    });
    
    // 存储观察者用于清理
    (api as any)._observer = observer;
  },
  
  stop() {
    const observer = (this as any)._observer;
    if (observer) {
      observer.disconnect();
    }
  }
} satisfies Tweak;

Advanced: Injecting Custom UI

进阶:注入自定义UI

typescript
export default {
  start(api) {
    // Wait for Codex UI to be ready
    const injectCustomButton = () => {
      const toolbar = document.querySelector('.chat-toolbar');
      if (!toolbar) return;
      
      const btn = document.createElement('button');
      btn.textContent = '✨ Custom Action';
      btn.className = 'toolbar-button';
      btn.onclick = () => {
        api.log.info('Custom action triggered');
        // Your custom logic
      };
      
      toolbar.appendChild(btn);
    };
    
    // Observe for toolbar appearance
    const observer = new MutationObserver(() => {
      injectCustomButton();
    });
    
    observer.observe(document.body, {
      childList: true,
      subtree: true
    });
    
    injectCustomButton(); // Try immediately
  },
  
  stop() {}
};
typescript
export default {
  start(api) {
    // 等待Codex UI加载完成
    const injectCustomButton = () => {
      const toolbar = document.querySelector('.chat-toolbar');
      if (!toolbar) return;
      
      const btn = document.createElement('button');
      btn.textContent = '✨ Custom Action';
      btn.className = 'toolbar-button';
      btn.onclick = () => {
        api.log.info('Custom action triggered');
        // 自定义逻辑
      };
      
      toolbar.appendChild(btn);
    };
    
    // 监控工具栏出现
    const observer = new MutationObserver(() => {
      injectCustomButton();
    });
    
    observer.observe(document.body, {
      childList: true,
      subtree: true
    });
    
    injectCustomButton(); // 立即尝试注入
  },
  
  stop() {}
};

Keyboard Shortcuts Tweak

键盘快捷键Tweak

typescript
export default {
  start(api) {
    const handleKeydown = (e: KeyboardEvent) => {
      // Cmd/Ctrl + Shift + K
      if ((e.metaKey || e.ctrlKey) && e.shiftKey && e.key === 'k') {
        e.preventDefault();
        api.log.info('Custom shortcut triggered');
        // Your action here
      }
    };
    
    document.addEventListener('keydown', handleKeydown);
    
    // Store for cleanup
    (api as any)._keyHandler = handleKeydown;
  },
  
  stop() {
    const handler = (this as any)._keyHandler;
    if (handler) {
      document.removeEventListener('keydown', handler);
    }
  }
};
typescript
export default {
  start(api) {
    const handleKeydown = (e: KeyboardEvent) => {
      // Cmd/Ctrl + Shift + K
      if ((e.metaKey || e.ctrlKey) && e.shiftKey && e.key === 'k') {
        e.preventDefault();
        api.log.info('Custom shortcut triggered');
        // 执行操作
      }
    };
    
    document.addEventListener('keydown', handleKeydown);
    
    // 存储处理器用于清理
    (api as any)._keyHandler = handleKeydown;
  },
  
  stop() {
    const handler = (this as any)._keyHandler;
    if (handler) {
      document.removeEventListener('keydown', handler);
    }
  }
};

Configuration

配置

Runtime Config

运行时配置

Located at
<user-data-dir>/config.json
:
json
{
  "enabledTweaks": [
    "com.example.my-tweak",
    "co.bennett.custom-keyboard-shortcuts"
  ],
  "autoUpdate": true,
  "safeMode": false,
  "logLevel": "info"
}
位于
<user-data-dir>/config.json
json
{
  "enabledTweaks": [
    "com.example.my-tweak",
    "co.bennett.custom-keyboard-shortcuts"
  ],
  "autoUpdate": true,
  "safeMode": false,
  "logLevel": "info"
}

Per-Tweak Config

单个Tweak配置

Tweaks can store configuration using the API:
typescript
// Get config with defaults
const config = api.config.get('my-tweak', { theme: 'dark' });

// Update config
api.config.set('my-tweak', { theme: 'light' });

// Config is persisted automatically
Tweaks可通过API存储配置:
typescript
// 获取配置并设置默认值
const config = api.config.get('my-tweak', { theme: 'dark' });

// 更新配置
api.config.set('my-tweak', { theme: 'light' });

// 配置会自动持久化

Tweak Distribution & Updates

Tweak分发与更新

Publishing a Tweak

发布Tweak

  1. Create a GitHub repository for your tweak
  2. Add tweak files (manifest.json, index.js/ts)
  3. Create a GitHub Release with a semver tag (e.g.,
    v1.0.0
    )
  4. Attach a
    .zip
    of the tweak folder to the release
Release structure:
my-tweak-v1.0.0.zip
└── my-tweak/
    ├── manifest.json
    └── index.js
  1. 为你的tweak创建GitHub仓库
  2. 添加tweak文件(manifest.json、index.js/ts)
  3. 创建带有Semver标签的GitHub Release(例如
    v1.0.0
  4. 将tweak文件夹的
    .zip
    包附加到Release中
Release结构:
my-tweak-v1.0.0.zip
└── my-tweak/
    ├── manifest.json
    └── index.js

Installing Tweaks

安装Tweaks

Users copy tweak folders to
<user-data-dir>/tweaks/
and enable them in Settings → Tweaks.
用户将tweak文件夹复制到
<user-data-dir>/tweaks/
,然后在设置 → Tweaks中启用。

Update Checking

更新检查

Codex++ checks
githubRepo
in manifest.json for newer releases once per day. Users review release notes and manually update.
Codex++ 每天检查manifest.json中的
githubRepo
是否有新版本。用户查看发布说明后手动更新。

Common Patterns

常见模式

Persistent State

持久化状态

typescript
let myState = api.config.get('my-tweak', { count: 0 });

function incrementCounter() {
  myState.count++;
  api.config.set('my-tweak', myState);
}
typescript
let myState = api.config.get('my-tweak', { count: 0 });

function incrementCounter() {
  myState.count++;
  api.config.set('my-tweak', myState);
}

React to Codex Events

响应Codex事件

typescript
// Watch for new messages
const observer = new MutationObserver((mutations) => {
  mutations.forEach((mutation) => {
    mutation.addedNodes.forEach((node) => {
      if (node instanceof HTMLElement && node.matches('.message')) {
        api.log.info('New message detected');
      }
    });
  });
});

observer.observe(document.querySelector('#chat-container'), {
  childList: true,
  subtree: true
});
typescript
// 监控新消息
const observer = new MutationObserver((mutations) => {
  mutations.forEach((mutation) => {
    mutation.addedNodes.forEach((node) => {
      if (node instanceof HTMLElement && node.matches('.message')) {
        api.log.info('New message detected');
      }
    });
  });
});

observer.observe(document.querySelector('#chat-container'), {
  childList: true,
  subtree: true
});

CSS Injection

CSS注入

typescript
const style = document.createElement('style');
style.textContent = `
  .custom-theme {
    --primary-color: #00ff00;
  }
  
  .chat-message {
    border-left: 3px solid var(--primary-color);
  }
`;
document.head.appendChild(style);

// Store for cleanup
(api as any)._styleElement = style;
typescript
const style = document.createElement('style');
style.textContent = `
  .custom-theme {
    --primary-color: #00ff00;
  }
  
  .chat-message {
    border-left: 3px solid var(--primary-color);
  }
`;
document.head.appendChild(style);

// 存储用于清理
(api as any)._styleElement = style;

Troubleshooting

故障排除

Codex won't launch after install

安装后Codex无法启动

bash
undefined
bash
undefined

Check status

检查状态

codexplusplus status
codexplusplus status

Repair installation

修复安装

codexplusplus repair
codexplusplus repair

If repair fails, uninstall and reinstall

如果修复失败,卸载后重新安装

codexplusplus uninstall codexplusplus install
undefined
codexplusplus uninstall codexplusplus install
undefined

Tweak not loading

Tweak未加载

bash
undefined
bash
undefined

Validate tweak structure

验证tweak结构

codexplusplus validate-tweak ~/Library/Application\ Support/codex-plusplus/tweaks/my-tweak
codexplusplus validate-tweak ~/Library/Application\ Support/codex-plusplus/tweaks/my-tweak

Check runtime logs (look for errors)

查看运行时日志(查找错误)

tail -f ~/Library/Logs/codex-plusplus/runtime.log
undefined
tail -f ~/Library/Logs/codex-plusplus/runtime.log
undefined

Safe mode (disable all tweaks)

安全模式(禁用所有tweaks)

bash
codexplusplus safe-mode
bash
codexplusplus safe-mode

Launch Codex, fix issues, then:

启动Codex,修复问题后执行:

codexplusplus safe-mode --off
undefined
codexplusplus safe-mode --off
undefined

macOS Gatekeeper issues

macOS Gatekeeper问题

After first launch of re-signed Codex:
  1. System Preferences → Privacy & Security
  2. Click "Open Anyway" for Codex.app
  3. Or:
    xattr -cr /Applications/Codex.app
首次启动重新签名的Codex后:
  1. 系统偏好设置 → 隐私与安全性
  2. 点击Codex.app旁的“仍要打开”
  3. 或者执行:
    xattr -cr /Applications/Codex.app

Codex update breaks Codex++

Codex更新导致Codex++失效

bash
undefined
bash
undefined

macOS: Use official updater

macOS:使用官方更新器

codexplusplus update-codex
codexplusplus update-codex

After Codex updates, watcher auto-repairs

Codex更新后,监控程序会自动修复

Or manually:

或者手动执行:

codexplusplus repair
undefined
codexplusplus repair
undefined

Windows: Wrong app launches

Windows:启动错误的应用

Launch Codex++ from Start Menu/Desktop, not the Microsoft Store Codex shortcut. The Store version is unpatched.
从开始菜单/桌面启动Codex++,而非Microsoft Store的Codex快捷方式。商店版本未被修补。

Development workflow

开发工作流

bash
undefined
bash
undefined

Watch for changes and auto-reload

监控文件变化并自动重载

codexplusplus dev
codexplusplus dev

Edit tweak files in:

在以下路径编辑tweak文件:

macOS: ~/Library/Application Support/codex-plusplus/tweaks/my-tweak/

macOS: ~/Library/Application Support/codex-plusplus/tweaks/my-tweak/

Reload Codex (Cmd+R / Ctrl+R) to see changes

重载Codex(Cmd+R / Ctrl+R)查看更改

undefined
undefined

Clear all config

清除所有配置

bash
undefined
bash
undefined

Remove config but keep tweaks

删除配置但保留tweaks

rm ~/Library/Application\ Support/codex-plusplus/config.json
rm ~/Library/Application\ Support/codex-plusplus/config.json

Full reset

完全重置

rm -rf ~/Library/Application\ Support/codex-plusplus/ codexplusplus install
undefined
rm -rf ~/Library/Application\ Support/codex-plusplus/ codexplusplus install
undefined

Security Notes

安全说明

  • Tweaks run with full Electron renderer privileges
  • Only install tweaks from trusted sources
  • Review tweak code before installing
  • githubRepo
    in manifest enables update notifications but doesn't auto-update
  • Codex++ never executes code without user consent
  • Tweaks拥有Electron渲染进程的完整权限
  • 仅从可信来源安装tweaks
  • 安装前查看tweak代码
  • manifest中的
    githubRepo
    仅启用更新通知,不会自动更新
  • Codex++绝不会在未获得用户许可的情况下执行代码

Example: Complete UI Tweak

示例:完整UI Tweak

typescript
// Dark mode toggle tweak
import type { Tweak } from "@codex-plusplus/sdk";

export default {
  start(api) {
    const config = api.config.get('dark-mode', { enabled: false });
    
    const applyTheme = (dark: boolean) => {
      document.body.classList.toggle('dark-theme', dark);
    };
    
    applyTheme(config.enabled);
    
    api.settings.register({
      id: 'dark-mode',
      title: 'Dark Mode',
      render: (root) => {
        root.innerHTML = `
          <label>
            <input type="checkbox" id="toggle" ${config.enabled ? 'checked' : ''}>
            Enable dark mode
          </label>
        `;
        
        root.querySelector('#toggle')?.addEventListener('change', (e) => {
          const enabled = (e.target as HTMLInputElement).checked;
          api.config.set('dark-mode', { enabled });
          applyTheme(enabled);
        });
      }
    });
    
    // Inject CSS
    const style = document.createElement('style');
    style.textContent = `
      .dark-theme {
        background: #1a1a1a;
        color: #ffffff;
      }
    `;
    document.head.appendChild(style);
    (api as any)._style = style;
  },
  
  stop() {
    document.body.classList.remove('dark-theme');
    const style = (this as any)._style;
    if (style) style.remove();
  }
} satisfies Tweak;
typescript
// 深色模式切换tweak
import type { Tweak } from "@codex-plusplus/sdk";

export default {
  start(api) {
    const config = api.config.get('dark-mode', { enabled: false });
    
    const applyTheme = (dark: boolean) => {
      document.body.classList.toggle('dark-theme', dark);
    };
    
    applyTheme(config.enabled);
    
    api.settings.register({
      id: 'dark-mode',
      title: 'Dark Mode',
      render: (root) => {
        root.innerHTML = `
          <label>
            <input type="checkbox" id="toggle" ${config.enabled ? 'checked' : ''}>
            Enable dark mode
          </label>
        `;
        
        root.querySelector('#toggle')?.addEventListener('change', (e) => {
          const enabled = (e.target as HTMLInputElement).checked;
          api.config.set('dark-mode', { enabled });
          applyTheme(enabled);
        });
      }
    });
    
    // 注入CSS
    const style = document.createElement('style');
    style.textContent = `
      .dark-theme {
        background: #1a1a1a;
        color: #ffffff;
      }
    `;
    document.head.appendChild(style);
    (api as any)._style = style;
  },
  
  stop() {
    document.body.classList.remove('dark-theme');
    const style = (this as any)._style;
    if (style) style.remove();
  }
} satisfies Tweak;