05 · 元数据驱动的 CLI¶
430 个注册命令若手写成一棵 case/switch,帮助文本、别名、权限提示和真实文件很快会失去同步。Quattro 反过来:可执行文件就是命令,文件头元数据就是目录。
一个命令如何声明自己¶
router 只读取 omarchy-* 文件前 80 行的注释元数据,字段包括:
| 字段 | 作用 |
|---|---|
@omarchy-group |
命令分组 |
@omarchy-name |
规范路由名 |
@omarchy-summary |
单行帮助摘要 |
@omarchy-args |
参数提示与必填判断 |
@omarchy-examples |
例子 |
@omarchy-requires-sudo |
帮助中标注权限 |
@omarchy-hidden |
从常规列表隐藏 |
@omarchy-aliases |
额外路由 |
缺省时,router 从文件名推导路由:omarchy-theme-set 对应 omarchy theme set。规范元数据可以覆盖该映射,alias 再增加额外入口。
为什么有两条路由路径¶
每次运行都扫描数百个文件会让最常用的 CLI 付出发现成本。router 因此分成快慢两条路径:
flowchart TD
Args[argv] --> MetaNeed{help/list/check/alias?}
MetaNeed -->|否| Prefix[最长前缀文件匹配]
Prefix --> Found{找到可执行文件?}
Found -->|是| Exec[exec 目标命令]
Found -->|否| Registry[建立完整注册表]
MetaNeed -->|是| Registry
Registry --> Resolve[规范名/别名/部分路由解析]
Resolve --> Exec
快路径:最长前缀¶
给定:
router 从最长前缀开始尝试:
找到 omarchy-theme-set 后,把剩余的 catppuccin 作为参数传入。日常执行只做少量文件存在/可执行检查,不解析全库元数据。
慢路径:完整注册表¶
帮助、命令列表、alias、歧义解析和一致性检查需要知道所有命令。此时 router 扫描元数据,构造规范路由、别名与显示信息。
这种“双路径”设计把性能优化限定在不改变语义的地方:普通 filename route 快;复杂发现功能仍由统一注册表给出确定答案。
参数与帮助拦截¶
router 在 -- 之前发现 --help 时拦截,并展示目标命令的结构化帮助。-- 后的同名参数属于下游命令,不应被 router 吃掉。
若元数据声明必填参数而调用没有提供,router 展示帮助而不是启动一个注定失败的脚本。这只是一层可用性防线;真正的命令仍应校验参数,因为它也可能被直接执行。
exec 是一个重要细节¶
最终 dispatch 使用 exec 替换 router 进程,而不是 fork 后等待:
- 调用者收到的退出码就是目标命令退出码;
- SIGINT/SIGTERM 直接送到真实命令;
- process tree 中没有无意义的 shell wrapper;
- 需要前台终端和 sudo 的程序行为更自然。
sequenceDiagram
participant T as 终端/systemd/菜单
participant R as bin/omarchy
participant C as omarchy-theme-set
T->>R: omarchy theme set nord
R->>R: fast resolve
R->>C: exec ... nord
Note over R,C: PID/信号/退出状态直接交接
C-->>T: exit status
帮助本身也是可检查的接口¶
omarchy commands 可输出人读格式、JSON 和 Markdown,也能运行 --check。检查覆盖:
- 路由或 alias 是否冲突;
- 文件是否可执行;
- 摘要与关键元数据是否缺失;
- 声明的路由是否能解析到唯一目标。
这让 CLI 目录成为一个可以在 CI 中验证的数据模型,而不是依赖人工发现的文档漂移。
规模与分组¶
固定快照有 432 个 omarchy-* 命名文件,其中 430 个具有 executable bit,因而被 router 注册:361 条常规可见、69 条隐藏、84 条声明 sudo,分布在 72 个组。两个非可执行文件 omarchy-remove-service-dropbox 与 omarchy-remove-service-tailscale 不会被 router 发现;它们也解释了“按文件名计数”和“按真实命令计数”的差异。最大组包括 install、theme、hw、hyprland、remove、launch 和 update。
隐藏不等于私有或不安全,只表示不希望污染日常发现界面。内部 helper、兼容入口或机器调用命令仍可以通过完整路径使用。
新增命令的最小契约¶
- 在
bin/新建可执行的omarchy-*文件; - 在前 80 行给出准确摘要与必要元数据;
- 参数校验仍写在命令自身;
- 运行
omarchy commands --check; - 为路由、关键副作用或输出添加 CLI 测试。
文件名仍是 API
即使元数据可覆盖规范路由,快路径依赖文件名。随意重命名可能改变启动性能、直接调用与兼容性;需要保留旧入口时应明确使用 alias 或 wrapper。
边界案例¶
| 情况 | 处理 |
|---|---|
--help 在 -- 后 |
传给下游命令 |
| 多个前缀都存在 | 最长前缀胜出 |
| alias 不能从文件名发现 | 回退完整 registry |
| route 冲突 | commands --check 报错 |
| 文件存在但不可执行 | 不作为可 dispatch 命令 |
| command 自身失败 | exec 原样传播退出码 |
关键源码索引¶
bin/omarchy入口状态与分组bin/omarchy元数据解析bin/omarchy最长前缀查找bin/omarchy列表/JSON/Markdown 输出bin/omarchy快路径 dispatchbin/omarchy完整 registry dispatchdocs/cli-router.md— 上游路由设计说明
所有命令的自动生成索引见 CLI 命令全集。下一章先厘清它们共同读写的状态:06 · 配置、状态与覆盖层。