One-click convert between vanilla Omarchy and OmarchyCN

omarchy-cn-convert turns a package-based install into OmarchyCN in one
curl-able run: registry key + [omarchycn] repo, --ask=4 swap onto the
cn-built packages (Chinese menu/bindings and OMARCHY CN branding ride
the settings tree), [omarchy] mirror line, zh_CN locale, fcitx5-rime
seeding, CN Arch mirrors, and a plymouth rebrand, recording pre-state
in /var/lib/omarchycn/convert-state. omarchy-cn-revert restores that
state symmetrically and survives user-removed packages, self-deletion
mid-swap, and cosmetic plymouth failures after the state is cleared.
Checkout installs are refused toward the overlay.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019hLK3wsDuKVAC37GgDqg6H
This commit is contained in:
2026-08-27 18:20:51 -04:00
co-authored by Claude Fable 5
parent c51df9977b
commit f72a48f747
7 changed files with 251 additions and 4 deletions
+2 -1
View File
@@ -15,7 +15,8 @@ matching guide before starting:
This fork carries the OmarchyCN China-integration layer on top of upstream `basecamp/omarchy`:
- `bin/omarchycn` routes to `omarchy cn <command>`; all cn commands are `bin/omarchy-cn-*` and follow the upstream bin conventions (metadata, helpers, `$OMARCHY_PATH`sole exception: the overlay installer bootstraps by resolving its own checkout)
- `bin/omarchycn` routes to `omarchy cn <command>`; all cn commands are `bin/omarchy-cn-*` and follow the upstream bin conventions (metadata, helpers, `$OMARCHY_PATH`bootstrap exceptions: the overlay installer resolves its own checkout, and `omarchy-cn-convert` / `omarchy-cn-revert` are curl-able standalone scripts that default `OMARCHY_PATH` because they run before/while the cn tree exists)
- Convert/revert: `omarchy-cn-convert` turns a vanilla package-based Omarchy into OmarchyCN (registry key + [omarchycn] repo, `--ask=4` package swap to the cn-built omarchy-dev/omarchy-settings-dev published by `packages/publish-cn-packages.sh`, [omarchy] mirror line, zh_CN locale, fcitx5 seeding, plymouth rebrand) recording pre-state in `/var/lib/omarchycn/convert-state`; `omarchy-cn-revert` restores that state; checkout installs are refused toward the overlay
- `cn/` holds the data layer: `mirrors.json`, `dev-mirrors.json`, `apps.json`, `registry/` (AI providers/harnesses/compatibility), `fcitx5/`, `fontconfig/`, `keys/`, `lib/` (sourced helpers), `release` (cn release number)
- cn migrations live in `cn/migrations/*.sh`, run by `omarchy-cn-update` with per-file completion markers under `~/.local/state/omarchycn/`
- Packaging: `packages/omarchy-pkgs-cn.patch` must be applied to the sibling `omarchy-pkgs` checkout so `omarchy-dev` ships `cn/`; keyring in `packages/omarchycn-keyring/`
+19 -2
View File
@@ -18,9 +18,10 @@
- **中国镜像管理**Arch / npm / pip / Cargo / Go 等软件源测速、自动选择与故障切换
- **中文环境开箱即用**zh_CN locale、思源黑体 / 宋体字体栈、高分屏分数缩放预设
- **中文输入法**Fcitx5 + Rime 预配置,Wayland / GTK / Qt / Electron 全栈兼容,快捷键冲突自动处理
- **AI Hub**Kimi、DeepSeek、Z.AI/GLM 一等 Provider 支持,与 Claude Code、Codex、OpenCode、Kimi Code、Deep Code 等 Harness 的统一配置向导、凭据安全存储与连接诊断
- **AI Hub**Kimi、DeepSeek、Z.AI/GLM、MiniMax 与本地 Ollama 的一等 Provider 支持,与 Claude Code、Codex、OpenCode、Kimi Code、Deep Code 等 Harness 的统一配置向导、凭据安全存储与连接诊断;另有 Dim、DSH 等自管登录的 Agent CLI 一键安装
- **国内应用中心**:微信、QQ、飞书、钉钉、腾讯会议、WPS 等应用的可信安装入口
- **Overlay 安装器**:在现有 Omarchy 上叠加 OmarchyCN,全程可逆、可卸载
- **一键转换**:原版 Omarchy(包安装)一条命令转成 OmarchyCN,logo/菜单/键位/输入法/软件源全套切换,`omarchy cn revert` 一键还原
- **Overlay 安装器**:在现有 Omarchy checkout 上叠加 OmarchyCN,全程可逆、可卸载
- **统一诊断**`omarchycn doctor` 覆盖网络、镜像、输入法、显示与 AI 配置
## 下载与安装
@@ -31,6 +32,22 @@
sha256sum -c SHA256SUMS.txt
```
## 已有原版 Omarchy?一键转换
包安装的原版 Omarchy(quattro)可直接转换,无需重装系统:
```bash
curl -fsSL https://git.zacharyzhang.com/ZacharyZhang-NY/omarchycn/raw/branch/quattro/bin/omarchy-cn-convert | bash
```
转换内容:换装 OmarchyCN 构建的系统包(中文菜单/键位/更新界面、OMARCHY CN 品牌、AI 全家桶)、启用 [omarchy] 自建镜像与 [omarchycn] 仓库、zh_CN 语言与 Fcitx5+Rime 输入法、国内 Arch 镜像自动测速。重新登录后生效。
随时一键还原(按转换时记录的状态逐项回退):
```bash
omarchy cn revert
```
## 上游文档
Omarchy 完整英文手册在 [`manual/`](manual/) 目录,亦见 [learn.omacom.io](https://learn.omacom.io/2/the-omarchy-manual)。
+107
View File
@@ -0,0 +1,107 @@
#!/bin/bash
# omarchy:summary=Convert a vanilla package-based Omarchy install into OmarchyCN
# omarchy:examples=omarchy cn convert
# Curl-able bootstrap (like the overlay installer): everything before the
# package swap must run without the cn tree, so no $OMARCHY_PATH until then.
set -euo pipefail
GITEA=${GITEA:-https://git.zacharyzhang.com}
OWNER=${OWNER:-ZacharyZhang-NY}
REGISTRY="$GITEA/api/packages/$OWNER/arch"
REG_KEY_FPR=74DCF57ACD812B24D959F146BD386048867B33B4
STATE_DIR=/var/lib/omarchycn
STATE=$STATE_DIR/convert-state
# Bootstrap exception: curl|bash runs outside a session, so default the path
export OMARCHY_PATH=${OMARCHY_PATH:-/usr/share/omarchy}
main() {
command -v pacman > /dev/null || { echo "需要 Arch Linux(未找到 pacman" >&2; exit 1; }
if (( EUID == 0 )); then
echo "请以普通用户运行(脚本内部按需 sudo" >&2
exit 1
fi
local prev_omarchy prev_settings
prev_omarchy=$(pacman -Q omarchy 2> /dev/null || pacman -Q omarchy-dev 2> /dev/null || true)
prev_settings=$(pacman -Q omarchy-settings 2> /dev/null || pacman -Q omarchy-settings-dev 2> /dev/null || true)
if [[ -z $prev_omarchy || -z $prev_settings ]]; then
if [[ -d $HOME/.local/share/omarchy/.git ]]; then
echo "检测到 checkout 安装(非包安装):请改用 overlaybin/omarchycn-install-overlay" >&2
else
echo "未检测到 Omarchy 包安装(需要 omarchy 与 omarchy-settings" >&2
fi
exit 1
fi
[[ -f $STATE ]] && echo "已转换过($STATE 在案):本次仅同步更新,不覆盖回退状态"
echo "==> 信任 OmarchyCN registry 公钥并配置 [omarchycn] 仓库"
local tmpkey
tmpkey=$(mktemp)
curl -fsSL "$REGISTRY/repository.key" -o "$tmpkey"
sudo pacman-key --add "$tmpkey"
sudo pacman-key --lsign-key "$REG_KEY_FPR"
rm -f "$tmpkey"
if ! grep -q '^\[omarchycn\]' /etc/pacman.conf; then
printf '\n[omarchycn]\nSigLevel = Required DatabaseOptional\nServer = %s/omarchycn/x86_64\n' \
"$REGISTRY" | sudo tee -a /etc/pacman.conf > /dev/null
fi
if [[ ! -f $STATE ]]; then
echo "==> 记录转换前状态(供 omarchy cn revert 还原)"
sudo mkdir -p "$STATE_DIR"
if [[ -f /etc/locale.conf ]]; then
sudo cp /etc/locale.conf "$STATE_DIR/locale.conf.pre"
fi
sudo cp /etc/pacman.d/mirrorlist "$STATE_DIR/mirrorlist.pre"
local p new_pkgs=""
for p in fcitx5-rime fcitx5-chinese-addons fcitx5-configtool omarchycn-keyring; do
pacman -Q "$p" > /dev/null 2>&1 || new_pkgs+="$p "
done
# Values are quoted because revert sources this file; publish atomically
{
echo "prev_omarchy=\"${prev_omarchy%% *}\""
echo "prev_settings=\"${prev_settings%% *}\""
echo "new_pkgs=\"${new_pkgs% }\""
echo "converted_at=\"$(date +%s)\""
} | sudo tee "$STATE.new" > /dev/null
sudo mv "$STATE.new" "$STATE"
fi
echo "==> 系统更新并换装 OmarchyCN 软件包(替换 ${prev_omarchy%% *}/${prev_settings%% *}"
sudo pacman -Syu --noconfirm
sudo pacman -S --noconfirm omarchycn/omarchycn-keyring
# --ask=4 auto-confirms removing the conflicting upstream omarchy packages
sudo pacman -S --noconfirm --ask=4 omarchycn/omarchy-dev omarchycn/omarchy-settings-dev
sudo pacman -S --needed --noconfirm fcitx5-rime fcitx5-chinese-addons fcitx5-configtool
echo "==> [omarchy] 仓库启用自建镜像(Cloudflare 上游兜底)"
source /usr/share/omarchy/cn/lib/mirror.sh
cn_mirror_omarchy_repo_fix
echo "==> 系统语言 zh_CN.UTF-8"
grep -q '^zh_CN.UTF-8 UTF-8' /etc/locale.gen ||
echo 'zh_CN.UTF-8 UTF-8' | sudo tee -a /etc/locale.gen > /dev/null
sudo locale-gen > /dev/null
if grep -q '^LANG=' /etc/locale.conf 2> /dev/null; then
sudo sed -i 's/^LANG=.*/LANG=zh_CN.UTF-8/' /etc/locale.conf
else
echo 'LANG=zh_CN.UTF-8' | sudo tee -a /etc/locale.conf > /dev/null
fi
echo "==> 中文输入法与字体(用户级)"
OMARCHY_PATH=/usr/share/omarchy bash /usr/share/omarchy/install/user/cn-chinese.sh
systemctl --user restart omarchy-fcitx5.service 2> /dev/null || true
echo "==> Arch 官方仓库切换国内镜像(自动测速,失败则保留现状)"
omarchy-cn-mirror-apply china || echo "国内镜像不可达,保留当前 mirrorlist"
echo "==> OMARCHY CN 开机画面"
omarchy-refresh-plymouth
omarchy-notification-send "OmarchyCN" "转换完成:重新登录后菜单/键位/输入法全中文" 2> /dev/null || true
echo
echo "转换完成(重新登录生效)。回退: omarchy cn revert"
}
main "$@"
+89
View File
@@ -0,0 +1,89 @@
#!/bin/bash
# omarchy:summary=Revert an OmarchyCN conversion back to vanilla Omarchy
# omarchy:examples=omarchy cn revert
# Curl-able and self-deleting-safe: main() is fully parsed before the package
# swap removes this file from the cn tree it may be running from.
set -euo pipefail
STATE_DIR=/var/lib/omarchycn
STATE=$STATE_DIR/convert-state
MIRROR_LINE="Server = https://git.zacharyzhang.com/api/packages/ZacharyZhang-NY/arch/omarchy/x86_64"
REG_KEY_FPR=74DCF57ACD812B24D959F146BD386048867B33B4
# Bootstrap exception: curl|bash runs outside a session, so default the path
export OMARCHY_PATH=${OMARCHY_PATH:-/usr/share/omarchy}
main() {
if [[ ! -f $STATE ]]; then
echo "未发现转换状态($STATE):本机不是由 omarchy cn convert 转换而来" >&2
exit 1
fi
if (( EUID == 0 )); then
echo "请以普通用户运行(脚本内部按需 sudo" >&2
exit 1
fi
local prev_omarchy="" prev_settings="" new_pkgs=""
# State is trusted root-owned key=value lines written by convert
source "$STATE"
[[ -n $prev_omarchy && -n $prev_settings ]] || { echo "转换状态损坏: $STATE" >&2; exit 1; }
echo "==> 清理转换时播种的用户配置(与 cn 层原件一致才删除)"
local seeded
for seeded in \
"$HOME/.config/fcitx5/profile:/usr/share/omarchy/cn/fcitx5/profile" \
"$HOME/.config/fontconfig/conf.d/64-omarchycn-cjk.conf:/usr/share/omarchy/cn/fontconfig/64-omarchycn-cjk.conf"; do
if cmp -s "${seeded%%:*}" "${seeded#*:}" 2> /dev/null; then
rm -f "${seeded%%:*}"
fi
done
echo "==> 还原 mirrorlist 与系统语言"
sudo cp "$STATE_DIR/mirrorlist.pre" /etc/pacman.d/mirrorlist
if [[ -f $STATE_DIR/locale.conf.pre ]]; then
sudo cp "$STATE_DIR/locale.conf.pre" /etc/locale.conf
fi
echo "==> pacman.conf 移除 [omarchycn] 与 [omarchy] 镜像行"
sudo sed -i "\|^$MIRROR_LINE\$|d" /etc/pacman.conf
# Delete the section header and body, but keep any section that follows
sudo sed -i '/^\[omarchycn\]$/,/^\[/{ /^\[omarchycn\]$/d; /^\[/!d; }' /etc/pacman.conf
echo "==> 换回上游软件包($prev_omarchy/$prev_settings"
sudo pacman -Sy
# --ask=4 auto-confirms removing the conflicting cn packages
sudo pacman -S --noconfirm --ask=4 "omarchy/$prev_omarchy" "omarchy/$prev_settings"
if [[ -n $new_pkgs ]]; then
# Only what is still installed: a user may have removed some already,
# and a -R failure here would strand the swap-completed system
local p still=""
for p in $new_pkgs; do
# grep without -q consumes the whole list: -q's early exit would
# SIGPIPE pacman and read as "not installed" under pipefail
pacman -Qq | grep -xF "$p" > /dev/null && still+="$p "
done
if [[ -n $still ]]; then
echo "==> 移除转换时新装的包: ${still% }"
# shellcheck disable=SC2086
sudo pacman -R --noconfirm ${still% }
fi
fi
echo "==> 移除 registry 公钥信任"
sudo pacman-key --delete "$REG_KEY_FPR" > /dev/null 2>&1 || true
# The system is vanilla again: clear state before the cosmetic tail so a
# plymouth failure cannot strand a reverted machine in "converted" state
systemctl --user restart omarchy-fcitx5.service 2> /dev/null || true
sudo rm -rf "$STATE_DIR"
echo "==> 还原上游开机画面"
if ! omarchy-refresh-plymouth; then
echo "开机画面还原失败:手动执行 omarchy-refresh-plymouth 即可" >&2
exit 1
fi
echo
echo "已回退为原版 Omarchy(重新登录生效)。再次转换: omarchy cn convert"
}
main "$@"
+1
View File
@@ -418,5 +418,6 @@
"omarchycn.diagnostics.mirror-fix": {"icon":"󰇧","label":"镜像修复","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-doctor mirror --fix'"},
"omarchycn.diagnostics.ime": {"icon":"󰌌","label":"输入法状态","action":"omarchy-launch-floating-terminal-with-presentation omarchy-cn-ime-status"},
"omarchycn.update": {"icon":"","label":"更新","when":"[[ -f ~/.local/state/omarchycn/overlay-manifest ]]","action":"omarchy-launch-floating-terminal-with-presentation omarchy-cn-update"},
"omarchycn.revert": {"icon":"󰕍","label":"回退为原版 Omarchy","when":"[[ -f /var/lib/omarchycn/convert-state ]]","action":"omarchy-launch-floating-terminal-with-presentation omarchy-cn-revert"},
"omarchycn.about": {"icon":"","label":"关于","action":"omarchy-launch-floating-terminal-with-presentation omarchy-cn-status"},
}
+21 -1
View File
@@ -24,7 +24,27 @@ omarchycn setup
向导依次配置:语言、时区、显示缩放、中文 locale、中文字体、Fcitx5+Rime 输入法、输入法切换键、pacman 镜像、开发工具镜像、国内应用、AI Hub、隐私说明。每一步都可跳过,中断后重跑会从未完成的步骤继续。
## 现有 Omarchy 叠加安装(Overlay
## 原版 Omarchy 一键转换(包安装
quattro 的原版 Omarchy 是包安装形态(`pacman -Q omarchy` 有输出),可以整机转换成 OmarchyCN,无需重装:
```bash
curl -fsSL https://git.zacharyzhang.com/ZacharyZhang-NY/omarchycn/raw/branch/quattro/bin/omarchy-cn-convert | bash
```
转换做的事:信任 OmarchyCN registry 公钥并接入 [omarchycn] 仓库;把 `omarchy`/`omarchy-settings` 换成 OmarchyCN 构建的 `omarchy-dev`/`omarchy-settings-dev`(中文菜单、中文键位描述、OMARCHY CN 品牌、AI 全家桶随包生效);给 `[omarchy]` 仓库加自建镜像(Cloudflare 上游兜底);系统语言切到 zh_CN.UTF-8 并安装配置 Fcitx5+Rime;Arch 官方仓库自动测速切换国内镜像;刷新 OMARCHY CN 开机画面。重新登录后生效。
转换前的包名、语言与 mirrorlist 会记录在 `/var/lib/omarchycn/convert-state`,随时一键还原:
```bash
omarchy cn revert
```
还原会换回上游软件包、恢复语言与 mirrorlist、移除 [omarchycn] 仓库与镜像行、卸载转换时新装的输入法包,并恢复上游开机画面。菜单 OmarchyCN 区段也有「回退为原版 Omarchy」入口。
## 现有 Omarchy 叠加安装(Overlaycheckout 形态)
老的 checkout 安装(`~/.local/share/omarchy` 是 git 检出)用 Overlay 叠加,不走一键转换:
```bash
git clone https://git.zacharyzhang.com/ZacharyZhang-NY/omarchycn.git
+12
View File
@@ -109,6 +109,18 @@ printf 'Server = https://pkgs.omarchy.org/stable/$arch\n' > "$tmpconf"
rm -f "$tmpconf"
pass "omarchy mirror guard ignores comments and matches only the exact line"
# Convert/revert bootstrap pair: parse, self-delete guard, no constant drift
for s in omarchy-cn-convert omarchy-cn-revert; do
bash -n "$ROOT/bin/$s" || fail "$s parses"
grep -q '^main "\$@"$' "$ROOT/bin/$s" || fail "$s wraps work in main() against self-deletion"
done
grep -q -- '--ask=4' "$ROOT/bin/omarchy-cn-convert" || fail "convert auto-confirms the conflict swap"
lib_mirror=$(grep -m1 '^CN_OMARCHY_MIRROR=' "$ROOT/cn/lib/mirror.sh" | cut -d'"' -f2)
revert_mirror=$(grep -m1 '^MIRROR_LINE=' "$ROOT/bin/omarchy-cn-revert" | cut -d'"' -f2)
[[ "Server = $lib_mirror" == "$revert_mirror" ]] ||
fail "revert MIRROR_LINE drifted from cn/lib/mirror.sh" "$revert_mirror"
pass "convert/revert pair: parse, main() guard, ask=4, mirror constant in sync"
# Menu: OmarchyCN entries parse and reference only existing commands
node -e '
const fs = require("fs");