featured.svg

在 Linux 開發者的世界中,Arch Linux 憑藉其極簡原則(The Arch Way)、滾動更新(rolling release)機制以及龐大的 AUR(Arch User Repository)生態,一直是追求掌控感與最新技術者的首選。

然而,許多人在嘗試打造個人工作站時,往往發現「從零拼裝一個現代化、美觀且穩定的 Wayland 桌面環境」需要耗費數週時間挑選套件與調校設定檔,常常陷入「維護系統的時間遠多於真正寫程式的時間」的困境。

Omarchy Linux 便是為了解決這個痛點而生的現代化發行版。在深入體驗 Omarchy 之後,我發現它最吸引人的特質,可以精準歸結為三大核心支柱:

  1. ⌨️ Keyboard-Driven(全鍵盤驅動):手不離鍵盤即可掌控全域。系統內建完備的快捷鍵網、Quickshell 即時選單,並支援透過宣告式 Lua 靈活擴充個人化的按鍵流(例如我個人習慣配置的 Meh key 與語音聽寫)。
  2. 🪟 Tile-Preferred(平鋪視窗優先):基於 Hyprland 的動態平鋪佈局與 UWSM 工作階段管理,零重疊、零浪費螢幕空間,並具備毫秒級工作區調度能力。
  3. 🤖 AI-Native(AI 原生架構):非事後拼湊,而是系統層原生為 AI coding agent 設計——包含機器自省 CLI、內建 agent skills 規範、狀態列即時 AI 額度追蹤與安全自我修復機制。

本文將帶大家從 DHH 轉向 Linux 的背景出發,深入拆解 Omarchy 的底層技術架構、Quickshell 插件生態,以及如何透過 AI agent 進行深度客製。

1. 誕生背景:DHH 的 Linux Omakase 理念與 Omarchy 的起源

提到 Omarchy 的誕生,就不能不提 David Heinemeier Hansson(DHH)——Ruby on Rails 創始人兼 37signals CTO,同時也是近年推動「離開雲端(Leaving the Cloud)」與伺服器自託管運動的代表人物。

長年以來,許多開發者(包括 DHH 本人)儘管熱愛開源,但日常工作機仍多停留在 macOS,主要原因在於 macOS 提供了無可挑剔的字型渲染、精緻的 UI 美學與穩定的硬體整合;而 Linux 桌面長期以來雖然自由度極高,但往往需要使用者耗費數週時間自行挑選套件、縫合各家 dotfiles,容易陷入「配置時間遠多於開發時間」的泥淖。

從「離開雲端」到「離開 Apple」

在成功帶領 37signals 脫離 AWS 與公有雲、回歸自建機房並開源部署工具 Kamal 後,DHH 將他對「自主掌控權」的追求延伸到了個人操作系統——決定全面告別 Apple 與 macOS,踏上探索 Linux 桌面的旅程。

這趟旅程經歷了兩個重要的演進階段:

  1. 第一階段:Omakub(基於 Ubuntu) DHH 首先打造了 Omakub(取名自日式主廚料理「Omakase(お任せ,由主廚為你搭配平衡的組合)」+ Ubuntu)。他的核心理念是:「Linux 不該只有極簡拼裝一種途徑,它也可以像主廚配餐的 Omakase 一樣,提供一套由經驗豐富的工程師精挑細選、兼顧美學且開箱即用的開發環境。」
  2. 第二階段:邁向滾動發行庫 $\rightarrow$ Omarchy(基於 Arch Linux) 在實際日常使用後,DHH 與社群進一步發現,Arch Linux 的滾動更新(rolling release)、龐大活躍的 AUR(Arch User Repository)以及簡潔的底層架構,更適合現代開發者的工作需求。於是,Omarchy 應運而生——將 “Omakase” 的整合哲學融入 Arch Linux 的基礎之中。

Omarchy 並非只是一包 dotfiles,而是一套完整的現代化桌面系統:它採用了 Hyprland 動態平鋪合成器、以 Qt6/QML 打造的 Quickshell 狀態列、Btrfs 自動快照防護網,並原生融入了對現代 AI coding agent 的深度協同支援。

2. Omarchy 全域架構大圖(Big Picture)

Omarchy 採用分層解耦架構(Layered Architecture),將系統預設配置、桌面元件與使用者擴充層嚴格劃分:

flowchart TD L1["1. 使用者與 agent 擴充層
~/.config/omarchy/
自訂 hooks · 選單擴充 (JSONC)
插件克隆 · 客製色票"] L2["2. Omarchy 系統框架
/usr/share/omarchy/
統一主題引擎 (colors.toml)
更新管線 · agent skills"] L3["3. 現代化 Wayland 桌面生態
Hyprland (模組化 Lua 配置)
Quickshell (QML 狀態列) · UWSM session 管理"] L4["4. Arch Linux 基礎與底層系統
Pacman & AUR 滾動更新庫
Limine + Snapper (Btrfs 快照回滾)
PipeWire & Linux Kernel"] L1 ==>|安全配置覆寫 & 插件擴充| L2 L2 ==>|全域主題推播 & 桌面會話整合| L3 L3 ==>|構建於 Arch 滾動更新體系| L4 classDef userNode fill:#064e3b,stroke:#34d399,stroke-width:2px,color:#f0fdf4; classDef frameworkNode fill:#1e3a8a,stroke:#60a5fa,stroke-width:2px,color:#eff6ff; classDef desktopNode fill:#7c2d12,stroke:#fb923c,stroke-width:2px,color:#fff7ed; classDef archNode fill:#0f172a,stroke:#94a3b8,stroke-width:2px,color:#f8fafc; class L1 userNode; class L2 frameworkNode; class L3 desktopNode; class L4 archNode; linkStyle default stroke:#38bdf8,stroke-width:2.5px,fill:none;

3. 三大核心支柱與底層技術棧

3.1 鍵盤至上:Keyboard-Driven 的極速操控

Omarchy 的原生設計讓使用者能最大程度保持「手不離鍵盤主鍵區」:

  • 直覺的原生快捷鍵體系: Omarchy 預設圍繞 SuperAlt 鍵構建了完整且層次分明的快捷操作網(例如切換工作區、分割視窗、調整大小與多螢幕跳轉)。
  • 極簡的宣告式 Lua 綁定 API: 不同於過去修改複雜的配置檔,Omarchy 在 ~/.config/hypr/bindings.lua 中提供了 o.bindhl.unbind 等高階 API。使用者可以非常優雅地疊加個人自訂鍵位(例如自訂 Meh key 複合鍵、特殊巨集),而完全不破壞系統預設邏輯。
  • 全鍵盤搜尋與啟動器(omarchy-menu: 透過 Alt + SpaceSuper + Space 喚出 Quickshell 即時選單,支援模糊搜尋所有系統設定、主題切換、AI agent 選擇與應用程式啟動。
navigation-browser-terminal.webp clipboard-history-search.webp

3.2 平鋪優先:Tile-Preferred 與現代 Wayland 桌面

對於多視窗重度使用者與程式開發者而言,傳統重疊視窗(floating windows)需要不斷使用滑鼠拉伸與移動視窗邊界,極度分散注意力。

Omarchy 選擇了 Hyprland 作為核心合成器,並以平鋪視窗作為第一公民:

  • 動態平鋪與空間利用率:視窗開啟時自動分割排版,有效利用螢幕空間;搭配流暢的動畫與邊框樣式,兼具實用與視覺一致性。
  • UWSM 會話管理:採用 Universal Wayland Session Manager,所有桌面常駐程式(如 Fcitx5 輸入法、音訊守護)皆註冊為獨立的 systemd user units,徹底解決 Wayland 下環境變數不同步與程序崩潰難以追蹤的問題。
  • 模組化 Lua 視窗規則(windows.lua:個別應用程式(例如密碼庫、計算機)可精準宣告為自動浮動並置中,其餘開發工具(終端機、瀏覽器、Obsidian)則維持全平鋪排版。
navigation-fourway-tiling.webp

3.3 AI 原生:AI-Native 架構與 Agent 深度協同

傳統 Linux 發行版對 AI coding agent(如 Claude Code、Antigravity、Aider、Pi)極為不友善——設定檔散落在 /etc/usr~/.config,常需要互動式 sudo 輸入密碼導致 agent 阻塞,且一旦修改錯誤可能造成系統黑畫面。

Omarchy 從設計之初便將 AI 協作納入作業系統核心:

  1. 結構化自省介面(Machine-Readable CLI): AI agent 不需要靠猜測指令參數,Omarchy 提供了強大的自省 API:
    # 輸出全系統所有指令的 JSON Schema(包含群組、路由、參數與說明)
    omarchy commands --json
    
    # 免互動式 sudo 的系統健康與除錯資訊輸出(避免 agent 執行時阻塞)
    omarchy debug --no-sudo --print
  2. 內建 agent skills 規範(/usr/share/omarchy/default/agents/skills/: Omarchy 預先為 AI agent 封裝了專屬的 skill 知識庫:
    • omarchy skill:定義了安全的配置修改邊界、熱重載策略與備份復原命令。
    • diagnose-crash skill:自動擷取 journalctlcoredumpctl 與 Wayland 合成器日誌,讓 agent 能精準分析桌面當機原因並修復。
  3. 狀態列即時 AI 額度追蹤(omarchy.agents: 狀態列隨附第一方 AI 插件,點擊即可即時展開目前 Claude / OpenAI / 本地模型的 token 消耗步調、今日用量與額度分析。
  4. 隔離與插件克隆模式(plugin clone pattern): 系統預設組件位於 /usr/share/omarchy/(唯讀保護)。AI agent 在擴充狀態列元件時,可以使用 omarchy plugin clone <plugin-name>,將系統內建插件安全複製到 ~/.config/omarchy/plugins/ 下建立專屬版本,修改絕不會破壞上游核心。
  5. 快速安全回滾(Self-Healing Mechanisms): 若 AI agent 在調整配置時寫出語法錯誤,Omarchy 提供非破壞性的還原指令:
    # 自動備份當前錯誤配置並還原回預設狀態
    omarchy refresh shell
    omarchy refresh hyprland

3.4 穩健底層:Btrfs + Snapper + Limine 快照回滾

為了確保滾動發行庫(rolling release)的穩定性,Omarchy 在底層構建了自動快照保護網:

  • Btrfs 子卷隔離:根目錄(@)與家目錄(@home)分離,快照回滾不影響個人使用者資料。
  • Snapper + Libalpm Hooks:每次 pacman 寫入套件前後自動透過 libalpm hooks 捕捉 Pre/Post 快照。
  • Limine 開機選單同步:整合 limine-snapper-sync,每次更新自動在開機選單生成快照項目,遇到異常可直接從選單回滾。
snapshots-bootloader.webp

4. 深入 Quickshell 插件架構與生態

Omarchy 的狀態列(Bar)、通知中心、鎖定螢幕、OSD 與彈出面板全都是基於 Quickshell(以 Qt6/QML 實作的 Wayland shell 框架) 以插件形式掛載:

flowchart TD subgraph Host ["omarchy-shell (Quickshell 單一常駐主體)"] direction TB Services["全域共用服務 (QML)
• 統一主題色票 (colors.toml)
• PipeWire 音訊 / Network 狀態"] Registry["PluginRegistry 外掛註冊表
• inotify 監聽即時熱重載
• manifest.json 契約驗證"] end subgraph Plugins ["插件生態系統 (Plugins)"] direction LR Builtin["系統第一方插件 (/usr/share/...)
• omarchy.bar · omarchy.audio
• omarchy.agents · omarchy.network"] Custom["使用者自訂插件 (~/.config/...)
• custom.cpu-monitor (自訂)
• 第三方 Git 克隆插件"] end Services --- Registry Registry ==>|動態載入 & 生命週期託管| Builtin Registry ==>|動態載入 & 熱重載| Custom classDef hostNode fill:#1e293b,stroke:#38bdf8,stroke-width:2px,color:#f0f9ff; classDef subNode fill:#0f172a,stroke:#64748b,stroke-width:1px,color:#e2e8f0; classDef builtinNode fill:#1e3a8a,stroke:#60a5fa,stroke-width:2px,color:#eff6ff; classDef customNode fill:#064e3b,stroke:#34d399,stroke-width:2px,color:#f0fdf4; class Host hostNode; class Services,Registry subNode; class Builtin builtinNode; class Custom customNode; linkStyle default stroke:#38bdf8,stroke-width:2.5px,fill:none;

4.1 核心運作機制

  1. 單一常駐 Host(single shell host): 全桌面只跑一個 omarchy-shell 程序。點擊狀態列展開音訊面板、Wi-Fi 列表或日曆時,是在同一個記憶體空間內呼叫 IPC 顯示 UI,實現零冷啟動延遲
  2. inotify 即時熱重載(hot-reloading)PluginRegistry.qml 透過後台 inotifywait 監聽 ~/.config/omarchy/plugins/。當你儲存任何 .qmlmanifest.json 時,外掛會在幾十毫秒內自動重載,完全不影響工作區與執行中的應用程式。
  3. 嚴謹的 Manifest 契約 (manifest.json): 每個插件透過清單宣告其支援的型態(kinds):bar-widget(狀態列元件)、panel(彈出面板)、overlay(全螢幕遮罩)、service(背景單例服務)與 bar(替換式狀態列)。

4.2 哪裡可以找到與探索 Omarchy 插件?

  • 官方插件探索中心(Plugins Hub):造訪 https://plugins.omarchy.org/ 可以瀏覽由社群與官方維護的海量插件庫(包含各式狀態列小工具、控制面板、系統監控與主題擴充)。
  • 第一方內建插件庫:位於 /usr/share/omarchy/shell/plugins/,使用 omarchy plugin list 即可檢視(如 omarchy.agentsomarchy.tailscaleomarchy.audioomarchy.disk-speedtest 等)。
  • 插件克隆模式:使用 omarchy plugin clone <source-id> --edit 將內建插件複製到 ~/.config/omarchy/plugins/ 進行安全魔改。
  • 社群第三方 Git 插件:使用 omarchy plugin add <git-url> --enable 快速安裝並加入狀態列。

5. 實戰演練:客製與擴充 Omarchy 範例

5.1 客製化 Meh Key 體系與 Voxtype 語音聽寫切換

雖然 Omarchy 預設提供了完整的 Super 鍵操作網,但為了徹底杜絕與個別開發工具(如 IDE、終端機內部快捷鍵)的鍵位衝突,我個人在 ~/.config/hypr/bindings.lua 中引入了 Meh key(Ctrl + Alt + Shift 作為高階快捷鍵前綴。

透過 Omarchy 提供的標準 o.bind API,可以非常直覺地將系統常駐的 Voxtype 本地 Whisper 語音聽寫守護程序voxtype record toggle)綁定至 Meh + V

-- ~/.config/hypr/bindings.lua
local o = require("omarchy.bindings")

-- 個人客製化:綁定 Meh + V (Ctrl + Alt + Shift + V) 隨手切換語音錄音
o.bind("CTRL + ALT + SHIFT + V", "Toggle dictation", "voxtype record toggle")

執行 hyprctl reload 後立即生效。現在無論在哪個視窗,按下 Meh + V 就能立即開始或結束語音錄音並自動完成文字輸出,完全不影響一般的應用程式快速鍵。

5.2 實作 CPU 溫度與使用率狀態列 Widget + btop 整合(長駐串流優化)

~/.config/omarchy/plugins/custom.cpu-monitor/ 建立自訂小工具。為了避免每 2 秒透過 Timer 重複 fork 子行程造成 CPU 開銷,我們採用 單一長駐串流進程 + Quickshell 原生 SplitParser 的高效架構:

  1. manifest.json
{
  "schemaVersion": 1,
  "id": "custom.cpu-monitor",
  "name": "CPU Monitor",
  "version": "1.0.0",
  "kinds": ["bar-widget"],
  "entryPoints": { "barWidget": "CpuWidget.qml" },
  "barWidget": {
    "displayName": "CPU Monitor",
    "category": "System",
    "defaultSection": "right"
  }
}
  1. cpu_stream.sh(純 bash 常駐採集腳本,每 2 秒向 stdout 輸出單行 JSON,全生命週期僅 fork 1 次):
#!/usr/bin/env bash
# ~/.config/omarchy/plugins/custom.cpu-monitor/cpu_stream.sh

# 啟動時定位溫度感測路徑
temp_file=""
for d in /sys/class/hwmon/hwmon*; do
    if [ -f "$d/name" ] && grep -q "coretemp\|k10temp\|zenpower\|cpu_thermal" "$d/name" 2>/dev/null; then
        [ -f "$d/temp1_input" ] && temp_file="$d/temp1_input" && break
    fi
done

read -r _ u1 n1 s1 i1 io1 ir1 sir1 st1 _ < /proc/stat
prev_total=$((u1 + n1 + s1 + i1 + io1 + ir1 + sir1 + st1))
prev_idle=$((i1 + io1))

# 持續串流輸出,零額外子程序
while true; do
    sleep 2
    read -r _ u2 n2 s2 i2 io2 ir2 sir2 st2 _ < /proc/stat
    total=$((u2 + n2 + s2 + i2 + io2 + ir2 + sir2 + st2))
    idle=$((i2 + io2))

    total_diff=$((total - prev_total))
    idle_diff=$((idle - prev_idle))
    prev_total=$total
    prev_idle=$idle

    usage=$(( total_diff > 0 ? (100 * (total_diff - idle_diff)) / total_diff : 0 ))

    temp="--"
    if [ -n "$temp_file" ] && [ -r "$temp_file" ]; then
        read -r raw_temp < "$temp_file" 2>/dev/null
        temp="$(( raw_temp / 1000 ))°C"
    fi

    printf '{"usage": %d, "temp": "%s"}\n' "$usage" "$temp"
done
  1. CpuWidget.qml(使用 SplitParser 串流事件驅動,搭配 TextMetrics 固定欄位寬度防止字元跳動):
import QtQuick
import Quickshell
import Quickshell.Io
import qs.Commons
import qs.Ui

BarWidget {
  id: root
  moduleName: "custom.cpu-monitor"
  property int cpuUsage: 0
  property string cpuTemp: "--"

  // 預先計算 3 位數百分比與溫度的最大字元寬度,防止數字跳動造成狀態列抖動
  TextMetrics { id: usageMetrics; font.family: Style.font.family; font.pixelSize: Style.font.body; text: "100%" }
  TextMetrics { id: tempMetrics; font.family: Style.font.family; font.pixelSize: Style.font.body; text: "100°C" }

  Process {
    id: statStream
    running: true
    command: ["bash", Quickshell.env("HOME") + "/.config/omarchy/plugins/custom.cpu-monitor/cpu_stream.sh"]
    stdout: SplitParser {
      onRead: function(line) {
        try {
          var data = JSON.parse(line)
          if (data.usage !== undefined) root.cpuUsage = data.usage
          if (data.temp !== undefined) root.cpuTemp = data.temp
        } catch (e) {}
      }
    }
  }

  Row {
    anchors.centerIn: parent
    spacing: Style.space(4)
    Text { text: ""; color: Color.foreground; anchors.verticalCenter: parent.verticalCenter }
    Text { width: usageMetrics.width; horizontalAlignment: Text.AlignRight; text: root.cpuUsage + "%"; color: Color.foreground; anchors.verticalCenter: parent.verticalCenter }
    Text { text: "·"; color: Color.foreground; opacity: 0.6; anchors.verticalCenter: parent.verticalCenter }
    Text { width: tempMetrics.width; horizontalAlignment: Text.AlignLeft; text: root.cpuTemp; color: Color.foreground; anchors.verticalCenter: parent.verticalCenter }
  }

  MouseArea {
    anchors.fill: parent
    cursorShape: Qt.PointingHandCursor
    onClicked: root.bar.run("omarchy launch or focus tui btop")
  }
}
  1. 啟用與掛載
omarchy plugin enable custom.cpu-monitor --section right

啟用後狀態列右上角即時渲染出 CPU 負載與溫度,且固定寬度不晃動,點擊即可無縫展開 btop 監控!

5.3 全域色票生成與動態編譯(AI-Native)

由 AI agent 自動生成 Cyberpunk 2077 配色 colors.toml,並透過單一指令完成全域推播:

omarchy theme set cyber-neon

Omarchy 的模板引擎會自動讀取 /usr/share/omarchy/default/themed/*.tpl,將色票即時注入 Ghostty、Alacritty、VS Code、Neovim、Obsidian 與 Quickshell 並發送熱重載訊號。

tokyo-night-preview.webp

6. 總結

特性維度 傳統 DIY Arch Linux Omarchy Linux
操作哲學 依賴滑鼠或分散的快速鍵 Keyboard-Driven:直覺原生快捷鍵、宣告式 Lua 擴充(如 Meh key)與 Voxtype
視窗佈局 需手動調整重疊視窗 Tile-Preferred:Hyprland 動態平鋪 + UWSM systemd 工作階段隔離
AI 整合 無原生支援,指令易因 sudo 阻塞 AI-Native:結構化自省 CLI、agent skills、狀態列 token 追蹤
狀態列與 UI Waybar (GTK) 或 Polybar Quickshell (Qt6/QML):單一常駐 host、毫秒級熱重載
外觀一致性 手動設定 10+ 個獨立設定檔 colors.toml 單一來源 + 跨應用模板編譯管線
更新防護 需自行設置 Btrfs 快照 Limine + Snapper + omarchy-update 預檢與開機選單快照回滾

Omarchy 並非要取代 Arch Linux 的極簡靈魂,而是以 Keyboard-DrivenTile-PreferredAI-Native 為核心,透過高度模組化且優雅的架構,打造出兼具流暢操控力、視覺一致性與 AI 深度協作的現代化開發者工作站。