夜雨聆风学习资料网

ARTICLE · 1327741

从github源码剥开Omarchy的架构设计

从github源码剥开Omarchy的架构设计

先看一句最朴素的话:Omarchy 是一套 Linux 桌面,但它默认的操作者不是人,是 Agent。

这句话决定了后面所有看起来奇怪的设计。人的眼睛看窗口、点菜单、拖图标;Agent 不看这些,它读文本、调命令、查状态。所以这套系统真正的骨架,不是「界面长什么样」,而是「一台机器要让程序来操作,得先把自己改成什么样」。我把 quattro 分支(commit 7eedd17,版本 4.0.0.alpha)拉到本机,从最外层开始,一层层往里剥。为了避免又变成零件清单,先给一张地图:先立三条规矩(这套系统为什么这么设计)→ 再看全景(一共几层、每层干什么)→ 然后逐层下钻(桌面、命令、Agent 座位、知识、状态)→ 最后算账(买到什么、欠了什么)。再说清楚「架构设计」到底在看什么:其实就三件事——分几层、边界划在哪、谁依赖谁。功能怎么实现是细节,这三件事才是骨架。

01 先看这栋房子长什么样

这一层要解决的问题:别让读者在零件里迷路,先给一张全景。

把 Omarchy 想成一栋房子,一共五层,从下往上:

地基是 Arch Linux 加一个定制内核,负责让硬件跑起来。水电是 mise,一个专门管工具版本的层——各种 Agent 命令行工具、语言运行时都由它按需下载,不归系统包管理器管。墙和门是 Hyprland,管窗口怎么摆、怎么切、焦点在哪。家具和面板是 Quickshell,状态栏、菜单、通知、锁屏、启动器全在这里,一个进程包办。说明书加对讲机是 bin/ 下那套命令,它把整栋房子的开关都变成一句句能调用的话。住在里面的,是 Agent。

这个比喻里最关键的一句:Agent 不是靠看窗户来认识这栋房子的。 它不截图、不做视觉识别,而是读对讲机报上来的结构化状态,再按说明书上的条目去按开关。所以「界面」在这套架构里反而不是主角,说明书才是。

还要补一句关于边界的话:说明书那一层其实是横着穿过去的。地基、水电、窗口、界面的所有操作,最后都得变成一条命令,Agent 才调得动。所以它不是摞在顶上的第五块砖,而是从上到下贯穿的一条线。分层和横切叠在一起,才是这张全景图的完整形状。

还有一条暗线:地基里有个环境变量的真源,被四个不同入口引用——登录时、开终端时、进桌面时、远程连进来时。四个入口,一份定义。这种「不让同一件事有两份说法」的思路,后面会反复出现。

这张图里没有画任何想象出来的组件。01 区照抄 docs/file-layout.md 的官方构建映射:一个仓库拆成两个包,切分点不是功能模块,而是「useradd -m 之前还是之后」。02 区把五层逐个标回源码目录,底下那条横切就是 Agent 的岗位。03 区是这次本地克隆逐目录数出来的规模底数。04 区是家目录的三层填充,以及三个状态目录分别归谁。细节看不懂不影响往下读,记住「源码目录 → 两个包 → 目标机路径」这条主线就够了。

小结:这栋房子是照着「程序来住」盖的,所以说明书比对讲机重要,对讲机比墙纸重要。

02 盖房子之前,先立了三条规矩

这一层要解决的问题:为什么后面那些设计看起来都那么「懒」?

翻源码会发现,很多决定朴素到有点偷懒:加一个功能就是新建一个文件;描述就写在代码前几行;教程和程序装在一起发。这不是没设计,是三条没写在任何文档里、但代码到处在执行的规矩。

规矩一:Agent 是个岗位,不是某个产品。

系统记住的是「现在谁坐这个位置」,不记住厂商。今天用 Claude,明天换 Codex,快捷键、窗口规则、主题、用量面板全都不用改。为了做到这点,所有 Agent 窗口共用一个名字,窗口规则只针对这一个名字写一次。岗位在,人可换。

规矩二:知识和实现必须一起发货。

说明书不能单独放一个网站、单独发一版。它和它描述的代码装在同一个软件包里:配置路径改了,说明里的路径在同一次提交里改掉。好处是教程永远不会骗人,代价是想改一句话也得发个包。

规矩三:一切可执行的都是命令,文件名就是它的名字。

没有注册表,没有插件清单,没有代码生成。往 bin/ 放一个可执行文件,它自动成为一条命令,文件名决定怎么调用它。

三条规矩各有代价,但它们合起来指向同一件事:这套系统极度害怕「两份东西对不上」。注册表和实现、文档和代码、教程和版本,只要分成两份,就迟早会漂移;而漂移发生在 Agent 身上尤其危险,因为它会一本正经地按过期的说明去操作真实的机器。所以后面你会看到,几乎所有「偷懒」的设计,都是在删掉第二份东西。

小结:先定「谁在开车、说明跟不跟车、开关怎么加」,再谈功能。

03 第一层:你眼睛能看见的那部分

这一层要解决的问题:桌面怎么让程序读得懂,而不只是让人看得顺眼?

最外层是 Quickshell 写的桌面外壳,两百多个文件、近六万行,状态栏、菜单、通知、锁屏、屏幕提示、程序坞都在里面。它和传统桌面的差别不在好看,在状态是双向的。

底下那层 Hyprland 管窗口,它一方面被命令驱动(切工作区、改布局、调亮度),另一方面会把当前有哪些窗口、谁在前台、分辨率多少,用结构化数据吐回来。对 Agent 来说,这就意味着它想知道「现在屏幕上有什么」,不需要截图、不需要 OCR、不需要猜哪个像素是按钮——直接读一段 JSON 就行。

少一整层视觉识别,就少一整套「看错了怎么办」的容错代码。这是这套架构相比「截屏加视觉理解」路线最实在的优势。

桌面上的插件也顺手解决了一个老问题:一个插件就是一个目录加一份清单文件,清单里除了声明「我是什么、什么时候加载」,还带一份字段定义——比如刷新间隔是整数、最小 30 秒、最大 3600 秒、默认 900。这份定义同时用来自动生成设置界面,也用来校验用户输入。作者不用写界面代码,也不可能出现「界面让填、后台却拒绝」的尴尬。

不过这里有个必须说清的边界,源码注释自己写得坦率:这套插件接口是能力收窄,不是保险箱。插件能看到的世界被限制住了,但它和桌面外壳跑在同一个进程里、共享同一棵对象树。它防的是手滑,不防恶意。装社区插件时要明白这一点。

小结:桌面这一层的价值,不是让人看得更舒服,是让 Agent 不必靠「看」来认识系统。

04 第二层:一本不用人翻的说明书

这一层要解决的问题:Agent 怎么知道这台机器能干什么、怎么干?

答案是 bin/ 目录。我数了一遍:567 个文件,其中 566 个是命令,剩下那个是总路由器。它们全平铺在一个目录里,没有子目录,也没有任何总目录去登记它们。

因为它不需要。文件名本身就是索引:omarchy-theme-set 就是「主题 → 设置」,omarchy-update 就是「更新」。要给系统加一条命令,新建一个文件即可,不用去别处登记。这就是标题里「没有一行注册表」的意思。

每条命令的开头几行注释,就是它的说明:summary 一句人话讲它是干什么的,args 说要几个参数,哪些可选,examples 给例子,requires-sudo 提前声明要不要管理员权限。路由器只读文件开头 80 行,读到第一行真正的代码就停。于是描述和实现长在同一个文件里。改代码的人顺手就改了头上那几行,不可能出现「帮助文档还写着旧用法」。

对 Agent 真正有用的是另一条命令:omarchy commands --json。它输出的不是给人看的帮助页,而是一份机器能读的能力清单——每条命令叫什么、怎么调、什么意思、要不要提权、有哪些等价写法。模型拿到它,就知道自己手上有哪些开关,而不是靠猜。

调用时还有个小心思:路由器不会每次都去读几百个文件的头部(那样太慢),而是先把命令名拼成文件名去探一下,命中就直接执行;探不到,才去翻那些可能被改过名字的命令。只有列帮助时才会全量加载。

源码里还留着一个挺有人味的坑:早期版本检查 --help 只看剩余参数的第一个词,结果有人敲了 omarchy update aur --help,帮忙没弹出来,系统真的开始更新了一次。现在的版本会把所有剩余参数都扫一遍。

小结:这一层把「这台机器能做什么」变成了一份机器自己读得懂的清单,而且清单永远不会和实现对不上。

05 第三层:Agent 坐在哪个位置

这一层要解决的问题:换一个 Agent,要不要把整栋房子重新装修一遍?

不用。这就是「岗位」那条规矩落地的地方。

所有 Agent 窗口共用一个固定名字 org.omarchy.agent。窗口规则、主题同步、工作区分配只针对这一个名字写一次,不为二十多个不同的命令行工具各写一遍。换厂商,规则原样继承。

源码里那段适配代码很有意思:二十多个 Agent 工具,每个对「别停下来问我」都有自己的写法——有的叫 --yolo,有的叫 --dangerously-skip-permissions,有的叫 --permission-mode bypassPermissions,有的压根没有这个开关。系统把它们全收进一个 case 语句里,对用户只暴露「选一个默认 Agent」。

还有两个很生活化的处理。一是起始目录:Agent 通常拒绝把整个家目录记成「可信」,从家目录启动会每次都弹确认。折中办法是给它一个专门的工作区 ~/Work,从那儿起步,只把这一块交出去。二是工具来源:启动器会读文件开头几个 KB,判断这是用户自己装的程序,还是 mise 的懒加载替身,免得路径顺序不对、悄悄跑了一个不是你装的副本。

但这层也藏着整套架构最大的一笔安全债:二十多个分支里,二十一个默认以「不停下来问」的模式启动。官方手册的原话是「准备好它们真的会动手」。更麻烦的是,没有一个总开关能一次全关掉,要改得逐条改那段 case 语句。安全默认值在这里不是配置项,是发行版的立场。

为什么这么在意「换人」?因为模型供给变得太快,今天好用的工具,半年后未必还在。系统只记住岗位、不记住厂商,等于给自己留了不被任何一家绑死的余地。这不只是设计上的洁癖,是它想做平台而不是做某个产品的附属,就必须守住的一条线。

小结:换人很容易,是这套设计最聪明的地方;默认不提问,是它最该被追问的地方。

06 第四层:说明书怎么送到 Agent 手上

这一层要解决的问题:光有命令清单还不够,Agent 得知道「办事的规矩」。

仓库里有两个名字很像的目录,特别容易搞混,先分清楚:

agents/skills/ 里是 10 篇文档,写给参与开发这套系统的 Agent 看,讲的是「怎么写命令元数据」「怎么写迁移脚本」「怎么做验收」,不装到用户机器上。

default/agents/skills/ 里只有 3 个,才是装到用户机器上、被用户自己的 Agent 读取的技能。分清楚这个,才知道设计意图在哪:前者是内部开发规范,后者是运行时知识。

后者怎么送出去?核心代码只有十几行:把这三个目录用符号链接接到六个约定位置——不同 Agent 工具各有各的习惯路径,格式却是同一套。链接而不是拷贝,好处是开发时把检出目录一换,链接自动指过去;坏处是链接断了会悄悄失效,Agent 看不到技能,也不知道为什么。

技能里写什么?以崩溃诊断那个为例,它不是教「coredumpctl 怎么用」——模型本来就会。它写的是方法论:先排除内存不足,别急着怪程序;查所有线程,别只看崩溃那一帧;把「证据证明的」和「我在推断的」明确分开;符号化不出来就说符号化不出来,别编函数名填空;诊断只读,不修、不整理、不重新配置。用法模型会,方法论才是它容易跳过的。

再接回第二条规矩:这三个技能和它们描述的代码装在同一个软件包里,一起升级。教程永不漂移,代价是不能独立发版。

小结:这一层给的不是知识百科,是一套「别偷懒、别编故事」的办事纪律,而且纪律跟着版本走。

07 第五层:东西放哪,改坏了怎么退回去

这一层要解决的问题:Agent 会改系统,那怎么让它知道哪些能改、改错了怎么回来?

先说「放哪」。系统把文件分成三个抽屉,规则极清楚:

第一个抽屉归软件包(/usr/share/omarchy/):命令、模板、默认值、主题,只读参考,手改了下次升级会被覆盖。第二个抽屉归你(~/.config/omarchy/):你的主题、布局、插件、自定义覆盖,可以随便改,适合放进自己的配置仓库。第三个抽屉归系统自己(~/.local/state/omarchy/):当前主题、迁移标记、完成标记,是运行时账本,不该手改。三个抽屉一分,Agent 就不必猜「这个文件我能不能动」。而猜,正是它开始编故事的起点。

再说「怎么回来」。这里有个我很喜欢的设计。新用户开箱就有配置,靠的是安装时把一批默认文件铺进 /etc/skel/,创建用户时系统自动复制成家目录。而「恢复出厂设置」这个命令,没有另写一套恢复逻辑,只是把同一个复制动作再放一遍。也就是说,创建用户和重置用户,是同一个动作。没有第二份「默认值应该长什么样」的定义,也就不会出现恢复逻辑和实际安装对不上这种经典 bug。代价是:默认文件只在创建用户时铺一次,老用户拿不到新默认值。补这个窟窿的,是 migrations/ 下 222 个以时间戳命名的脚本——它们按时间顺序、按用户、幂等地给老机器打补丁。一条典型迁移会先看清当前状态是不是自己认识的旧值,是才改,用户自己动过的配置绝不误伤。

这里也顺带解释了那个容易被忽略的怪事:一个仓库为什么要打两个包。因为「默认文件」必须在创建用户之前就位,而运行时程序可以在之后装。于是仓库按「这个文件需要在用户存在之前还是之后」切成两半,两个包之间用依赖关系保证先后顺序。不是按功能切,是按时间切——看着别扭,但不用额外写一行安装编排。

顺带一提,连测试都带着这个思路:oligarchy-tests/ 里是 7 份 JSON,写的不是代码,是给 Agent 看的自然语言操作说明——背景知识是什么、按哪几步做、什么样算通过。人负责写清楚意图和判据,Agent 负责执行和取证。里面甚至专门交代「锁屏上不显示时钟是正常现象,别当成故障报上来」。

小结:先划清归属,再留一条退路;退路不是另写一套,而是重放一次。

08 最后算一笔账:买了什么,欠了什么

这一层要解决的问题:这套设计到底值不值得学,哪里有坑。

把前面七层收成一张账。

买到的:一致性。描述和实现长在一起、知识和程序一起发货、创建和重置共用一套动作、四个入口共用一个真源,所以很难出现「两份说法对不上」。低摩擦:加一条命令就是新建一个文件,社区插件几天就能长到几百个。可预测:文件归谁、命令要不要提权、状态从哪读,都有明确答案,Agent 不用猜。

欠下的:没有集中视图——567 个文件铺在一个目录里,没有一张总表能一眼看全,语义全靠命名约定。没有集中开关——想把这些免确认开关一次关掉,得逐条改代码。没有独立迭代——技能改一句话也要发个包。没有快速失败——注释写错了不报错,只会悄悄退回按文件名调用,--check 是唯一防线,而它跑不跑取决于 CI 配置。

四条风险值得单独记,都是从代码里读出来的,不是评论:

默认不提问是架构级的。 不是配置选项,是写死在适配代码里的立场。技能是软约束。 说明里写「别改这个目录」没用,真正拦住写入的是文件权限;系统里没有专门针对 Agent 身份的策略层,也没有系统调用过滤。插件不是保险箱。 前面说过,接口收窄挡的是手滑,不是恶意。写错会静默降级。 一个拼写错误的元数据声明,可能让本该提权的命令悄悄失败。

四句话可以再压成一句:这套架构把「让 Agent 好用」做到了很深,把「让 Agent 受控」几乎留白。

这不是缺点清单,是取舍清单。它服务的是一个人开发者主导、面向愿意折腾的用户的发行版——在那儿,「说一句就干完」的连续感比层层审批重要。把同样的默认值搬到多人共用的生产环境,就是另一回事了。

小结:架构没有好坏,只有「它替谁把哪件事做到了极致,又在哪件事上主动放弃」。

09 结语:抄什么,别抄什么

剥到这里,从看得见的桌面一直走到地基和账本,其实只绕着一句话:当操作者从人变成程序,系统就得把自己从「看得懂」改成「读得懂」。

界面让位给结构化状态,帮助文档让位给机器可读的能力清单,教程让位给随版本发布的技能,恢复功能让位给一次重放。看起来是四个不相干的决定,其实是同一个判断的四个侧面。

别抄的是默认不提问。 那是发行版的立场,不是架构的必然。真要用到自己的系统里,第一件该补的事,就是给那些硬编码的免确认找一个总开关。

它把「让 Agent 顺畅地操作这台机器」回答得极漂亮;至于「凭什么信任它」,这套代码没有试图回答,也诚实得没有假装自己回答了。


参考来源

这篇用到的资料,按推荐程度排序。

01|omarchy/omarchy 源码,quattro 分支,commit 7eedd17 — 2026-11-01,version 4.0.0.alphahttps://github.com/omacom/omarchy/tree/quattro 本文所有文件计数、目录结构、命令路由、技能链接、迁移写法与注释均据此实测。一手,最可信。quattro 是开发线,稳定发行标签是 4.0.6,两者不是同一棵树。

02|docs/file-layout.md(仓库内)两个 Arch 包的切分依据、哪些目录不进包、平台文件根的硬契约。想搞清楚「改一个东西该放哪」,这份是权威。

03|Omarchy 官方手册,特别是 17-ai.mdhttps://omarchy.org/manual/ 默认 Agent、免确认模式的官方原话、agents 面板与主题同步。手册与开发分支可能有版本差,冲突时以源码为准。

04|《Omarchy 架构设计文档》 — 本项目,2026-11-01(HTML,reports/ 目录) 源码核查版的完整分层、权衡表与扩展点地图。本文按「顶层视角 + 通俗化」重新组织,想看逐项细节可翻这份。

05|《Omarchy 与阿里云 Agentic OS 深度研究报告》 — 本项目,2026-11-01(MD + HTML,reports/ 目录) 12 个来源的可信度分级与矛盾标注,背景数字(基金会、赞助、旧命令计数)的来历在这里。

06|oligarchy-tests/(仓库内,7 份 JSON)自然语言验收规格的实例。本文提到的是 lock-screen.json 里「别把缺失的时钟报成故障」那句。

07|Omarchy 官网与 4.0 发布说明https://omarchy.org/ omakase 哲学、Quickshell 重写桌面的背景与社区插件生态时间线。

08|GOSIM Shenzhen 2026,DHH 演讲实录基金会成立、八人各出一百万美元、中国区本地化与此芯 P1 端侧演示。演讲实录,无稳定链接。

09|十天 Omarchy 实测长文 — blackanger https://x.com/blackanger/article/2093013029579534582 较早讲清状态分层的一篇二手实测。但其中「436 条命令」是旧快照,已被源码实测的 567 个文件覆盖。

回首页,搜索你想要的文档

在首页搜索框输入关键词,快速定位资料

文库首页搜索指引 立即搜索

相关学习资料