13 Commits
Author SHA1 Message Date
ZacharyZhang-NYandClaude Fable 5 495b24cedf Point the site and README at the 4.0.0.alpha-cn.7 release
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kb7vDj6PHwymeDeSUUk1eX
2026-08-28 22:23:26 -04:00
ZacharyZhang-NYandClaude Fable 5 9ce9979ce5 Begin the 4.0.0.alpha-cn.7 release: cn/release to 7
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kb7vDj6PHwymeDeSUUk1eX
2026-08-28 22:14:10 -04:00
ZacharyZhang-NYandClaude Fable 5 06174bbd06 Distribute release ISOs through the dl.zacharyzhang.com R2 host
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kb7vDj6PHwymeDeSUUk1eX
2026-08-28 21:14:10 -04:00
ZacharyZhang-NYandClaude Fable 5 101a3db393 Anchor the cn-convert style exemption to the exact command
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kb7vDj6PHwymeDeSUUk1eX
2026-08-28 14:15:02 -04:00
ZacharyZhang-NYandClaude Fable 5 64a531f999 Exempt the cn-convert bootstrap from the command-helper style rule
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kb7vDj6PHwymeDeSUUk1eX
2026-08-28 14:12:26 -04:00
ZacharyZhang-NYandClaude Fable 5 7f9236777f Harden the new cn assertions against false passes and fix overlay update wording
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kb7vDj6PHwymeDeSUUk1eX
2026-08-28 14:04:34 -04:00
ZacharyZhang-NYandClaude Fable 5 92ebed0f34 Assert the cn update wiring in tests and document the unified update path
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kb7vDj6PHwymeDeSUUk1eX
2026-08-28 13:57:07 -04:00
ZacharyZhang-NYandClaude Fable 5 e62584b31f Add WeCom to the China app catalog and menu
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kb7vDj6PHwymeDeSUUk1eX
2026-08-28 13:51:58 -04:00
ZacharyZhang-NYandClaude Fable 5 39026fd41e Move the cn migration call into omarchy-migrate and guard downgrades onto pre-migrate trees
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kb7vDj6PHwymeDeSUUk1eX
2026-08-28 13:46:25 -04:00
ZacharyZhang-NYandClaude Fable 5 81c253b86e Restore executable bits on omarchy-cn-convert and omarchy-cn-revert
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kb7vDj6PHwymeDeSUUk1eX
2026-08-28 13:46:11 -04:00
ZacharyZhang-NYandClaude Fable 5 f4d5fa4013 Run cn migrations in the update pipeline and serve package installs from omarchy cn update
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kb7vDj6PHwymeDeSUUk1eX
2026-08-28 13:35:25 -04:00
ZacharyZhang-NYandClaude Fable 5 7d22dc14a5 Fix stale step number in sync SLA and stale README version
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kb7vDj6PHwymeDeSUUk1eX
2026-08-28 13:32:23 -04:00
ZacharyZhang-NYandClaude Fable 5 9f15d42c2c Make cn/release mean the current release, bumped as step one of a release
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kb7vDj6PHwymeDeSUUk1eX
2026-08-28 13:26:44 -04:00
17 changed files with 162 additions and 49 deletions
+3 -3
View File
@@ -18,16 +18,16 @@ This fork carries the OmarchyCN China-integration layer on top of upstream `base
- `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) - `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 - 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/` 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/` - cn migrations live in `cn/migrations/*.sh`, run by `omarchy-cn-migrate` with per-file completion markers under `~/.local/state/omarchycn/`; `bin/omarchy-migrate` calls it after the upstream migrations, and `omarchy-cn-update` serves both install forms (overlay: git pull + reinstall + migrate; package: exec `omarchy-update`)
- 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/` - 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/`
- Upstream repo mirror: `packages/sync-omarchy-repo.sh` + `.gitea/workflows/pkg-repo-sync.yml` mirror the upstream `[omarchy]` stable channel into the Gitea Arch registry every 6h; `pacman-stable.conf` lists the mirror first (upstream fallback), clients must trust the registry key (install import + cn migration), `omarchycn doctor mirror --fix` re-heals the line; see `docs/pacman-repo.md` - Upstream repo mirror: `packages/sync-omarchy-repo.sh` + `.gitea/workflows/pkg-repo-sync.yml` mirror the upstream `[omarchy]` stable channel into the Gitea Arch registry every 6h; `pacman-stable.conf` lists the mirror first (upstream fallback), clients must trust the registry key (install import + cn migration), `omarchycn doctor mirror --fix` re-heals the line; see `docs/pacman-repo.md`
- ISO: `packages/omarchy-iso-cn.patch` must be applied to the sibling `omarchy-iso` checkout — Chinese installer (cage+foot graphical console with English VT fallback) and live-env packages - ISO: `packages/omarchy-iso-cn.patch` must be applied to the sibling `omarchy-iso` checkout — Chinese installer (cage+foot graphical console with English VT fallback) and live-env packages
- Release process: `docs/release-checklist.md`; signing: `docs/release-signing.md`; pacman repo: `docs/pacman-repo.md` - Release process: `docs/release-checklist.md`; signing: `docs/release-signing.md`; pacman repo: `docs/pacman-repo.md`; ISO distribution: Cloudflare R2 bucket behind `dl.zacharyzhang.com` via `packages/upload-release-r2.sh` (Gitea releases carry only the small artifacts)
- Site: `site/` is the omarchycn.zacharyzhang.com landing page (Vite 8 vanilla + GSAP + self-hosted Fusion Pixel + reicon, kami palette on a 12-col grid); deploy with `npx wrangler deploy` from `site/`, rendered-state checks via `node shots.mjs` against a preview or the live URL - Site: `site/` is the omarchycn.zacharyzhang.com landing page (Vite 8 vanilla + GSAP + self-hosted Fusion Pixel + reicon, kami palette on a 12-col grid); deploy with `npx wrangler deploy` from `site/`, rendered-state checks via `node shots.mjs` against a preview or the live URL
- Chinese-first defaults: OmarchyCN ships Simplified Chinese as the default UX. User-visible strings in `default/omarchy/omarchy-menu.jsonc` (all labels), `default/hypr/bindings/*.lua` (bind descriptions, including the generated workspace/group/panel loops), `bin/omarchy-menu-keybindings` (its merge list and priority patterns must match the shipped Chinese descriptions), `bin/omarchy-update-confirm`, and `install/user/first-run/*` notifications are Chinese with brand names kept in English; menu search stays reachable in English through leaf ids. When syncing upstream, translate new strings in these files and resolve string conflicts toward our Chinese text. - Chinese-first defaults: OmarchyCN ships Simplified Chinese as the default UX. User-visible strings in `default/omarchy/omarchy-menu.jsonc` (all labels), `default/hypr/bindings/*.lua` (bind descriptions, including the generated workspace/group/panel loops), `bin/omarchy-menu-keybindings` (its merge list and priority patterns must match the shipped Chinese descriptions), `bin/omarchy-update-confirm`, and `install/user/first-run/*` notifications are Chinese with brand names kept in English; menu search stays reachable in English through leaf ids. When syncing upstream, translate new strings in these files and resolve string conflicts toward our Chinese text.
- Default set changes vs upstream: `install/omarchy-base.packages` adds fcitx5-rime/chinese-addons/configtool and drops aether/libreoffice-fresh/obs-studio; the Basecamp/Discord/HEY/Google/WhatsApp/X launchers, their webapp keybindings, the whatsapp-slim extension, and the HEY mailto handler are removed (preinstall add/remove lists, launcher.hides, chromium flags, and mimeapps stay in sync); `install/user/cn-chinese.sh` seeds IME/font config on zh_CN systems - Default set changes vs upstream: `install/omarchy-base.packages` adds fcitx5-rime/chinese-addons/configtool and drops aether/libreoffice-fresh/obs-studio; the Basecamp/Discord/HEY/Google/WhatsApp/X launchers, their webapp keybindings, the whatsapp-slim extension, and the HEY mailto handler are removed (preinstall add/remove lists, launcher.hides, chromium flags, and mimeapps stay in sync); `install/user/cn-chinese.sh` seeds IME/font config on zh_CN systems
- AI: `cn/registry/` drives providers (DeepSeek/Kimi/Z.AI/MiniMax/Ollama-local) with zero-code adapters; Ollama uses a fixed `static_token` and runtime-listed models (`models_dynamic`); `omarchy-default-agent` also accepts kimi (official installer script, not mise), deepcode, dim, and dsh (mise npm); the Default Agent menu carries them plus an AI Hub combo entry - AI: `cn/registry/` drives providers (DeepSeek/Kimi/Z.AI/MiniMax/Ollama-local) with zero-code adapters; Ollama uses a fixed `static_token` and runtime-listed models (`models_dynamic`); `omarchy-default-agent` also accepts kimi (official installer script, not mise), deepcode, dim, and dsh (mise npm); the Default Agent menu carries them plus an AI Hub combo entry
- Upstream sync: `.gitea/workflows/upstream-sync.yml` opens a PR per upstream change; keep upstream file edits minimal and inventoried (currently: one `GROUP_DESCRIPTIONS[cn]` line in `bin/omarchy`, the localized menu/bindings/update/first-run surfaces above, the western-app removals above, the cn agent roster in `bin/omarchy-default-agent` / `bin/omarchy-agent` (kimi/deepcode/dim/dsh), the `[omarchy]` mirror line in `default/pacman/pacman-stable.conf`, the registry-key import in `install/post-install/pacman.sh`, a rewritten `README.md` (known recurring sync conflict, resolve toward ours), `AGENTS.md` additions, and two `.gitignore` lines) - Upstream sync: `.gitea/workflows/upstream-sync.yml` opens a PR per upstream change; keep upstream file edits minimal and inventoried (currently: one `GROUP_DESCRIPTIONS[cn]` line in `bin/omarchy`, the `omarchy-cn-migrate` line in `bin/omarchy-migrate`, the localized menu/bindings/update/first-run surfaces above, the western-app removals above, the cn agent roster in `bin/omarchy-default-agent` / `bin/omarchy-agent` (kimi/deepcode/dim/dsh), the `[omarchy]` mirror line in `default/pacman/pacman-stable.conf`, the registry-key import in `install/post-install/pacman.sh`, a rewritten `README.md` (known recurring sync conflict, resolve toward ours), `AGENTS.md` additions, and two `.gitignore` lines)
- cn tests: `test/shell.d/omarchycn-test.sh`, `test/shell.d/omarchycn-ai-test.sh`; localized UI expectations live in the upstream suites (menu, keybindings-menu, hyprland-default-config, binding-conflicts, clock, screenrecording, update-disk-space) - cn tests: `test/shell.d/omarchycn-test.sh`, `test/shell.d/omarchycn-ai-test.sh`; localized UI expectations live in the upstream suites (menu, keybindings-menu, hyprland-default-config, binding-conflicts, clock, screenrecording, update-disk-space)
# Documentation Layout # Documentation Layout
+2 -2
View File
@@ -2,7 +2,7 @@
面向中国开发者的 [Omarchy](https://omarchy.org) 下游发行版:完整保留 Omarchy 的 Arch + Hyprland 桌面体验,为中国网络环境、中文使用习惯与国内 AI 服务做系统级增强。 面向中国开发者的 [Omarchy](https://omarchy.org) 下游发行版:完整保留 Omarchy 的 Arch + Hyprland 桌面体验,为中国网络环境、中文使用习惯与国内 AI 服务做系统级增强。
当前版本 `4.0.0.alpha-cn.4`(基于上游 `quattro` 分支构建的基线 ISO)。 当前版本 `4.0.0.alpha-cn.7`(基于上游 `quattro` 分支构建的基线 ISO)。
## 特性 ## 特性
@@ -19,7 +19,7 @@
- **中文环境开箱即用**:zh_CN locale、思源黑体 / 宋体字体栈、高分屏分数缩放预设 - **中文环境开箱即用**:zh_CN locale、思源黑体 / 宋体字体栈、高分屏分数缩放预设
- **中文输入法**:Fcitx5 + Rime 预配置,Wayland / GTK / Qt / Electron 全栈兼容,快捷键冲突自动处理 - **中文输入法**:Fcitx5 + Rime 预配置,Wayland / GTK / Qt / Electron 全栈兼容,快捷键冲突自动处理
- **AI Hub**:Kimi、DeepSeek、Z.AI/GLM、MiniMax 与本地 Ollama 的一等 Provider 支持,与 Claude Code、Codex、OpenCode、Kimi Code、Deep Code 等 Harness 的统一配置向导、凭据安全存储与连接诊断;另有 Dim、DSH 等自管登录的 Agent CLI 一键安装 - **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 等应用的可信安装入口 - **国内应用中心**:微信、企业微信、QQ、飞书、钉钉、腾讯会议、WPS 等应用的可信安装入口
- **一键转换**:原版 Omarchy(包安装)一条命令转成 OmarchyCN,logo/菜单/键位/输入法/软件源全套切换,`omarchy cn revert` 一键还原 - **一键转换**:原版 Omarchy(包安装)一条命令转成 OmarchyCN,logo/菜单/键位/输入法/软件源全套切换,`omarchy cn revert` 一键还原
- **Overlay 安装器**:在现有 Omarchy checkout 上叠加 OmarchyCN,全程可逆、可卸载 - **Overlay 安装器**:在现有 Omarchy checkout 上叠加 OmarchyCN,全程可逆、可卸载
- **统一诊断**:`omarchycn doctor` 覆盖网络、镜像、输入法、显示与 AI 配置 - **统一诊断**:`omarchycn doctor` 覆盖网络、镜像、输入法、显示与 AI 配置
Regular → Executable
View File
+21
View File
@@ -0,0 +1,21 @@
#!/bin/bash
# omarchy:summary=Run pending OmarchyCN migrations
# omarchy:examples=omarchycn migrate
set -euo pipefail
MIGRATIONS_DIR="$OMARCHY_PATH/cn/migrations"
DONE_DIR="$HOME/.local/state/omarchycn/migrations-done"
[[ -d $MIGRATIONS_DIR ]] || exit 0
mkdir -p "$DONE_DIR"
for m in "$MIGRATIONS_DIR"/*.sh; do
[[ -f $m ]] || continue
name="${m##*/}"
if [[ ! -f $DONE_DIR/$name ]]; then
echo "OmarchyCN migration: $name"
bash -euo pipefail "$m"
touch "$DONE_DIR/$name"
fi
done
Regular → Executable
View File
+11 -21
View File
@@ -1,15 +1,17 @@
#!/bin/bash #!/bin/bash
# omarchy:summary=Update an overlay install: pull source, reinstall, run migrations # omarchy:summary=Full OmarchyCN update: system, cn data, and migrations
# omarchy:examples=omarchycn update # omarchy:examples=omarchycn update
set -euo pipefail set -euo pipefail
MANIFEST="$HOME/.local/state/omarchycn/overlay-manifest" MANIFEST="$HOME/.local/state/omarchycn/overlay-manifest"
MIGRATION_DONE_DIR="$HOME/.local/state/omarchycn/migrations-done"
if [[ ! -f $MANIFEST ]]; then if [[ ! -f $MANIFEST ]]; then
echo "Not an overlay install (no $MANIFEST)." >&2 # Package install: the pipeline brings the new cn tree and runs cn migrations
echo "Package-based installs update through 'omarchy update' / pacman." >&2 if [[ -d $OMARCHY_PATH/cn ]]; then
exec omarchy-update
fi
echo "未检测到 OmarchyCN($OMARCHY_PATH/cn 不存在,也没有 overlay manifest)" >&2
exit 1 exit 1
fi fi
@@ -52,11 +54,11 @@ stable)
;; ;;
esac esac
# Never move onto a tree that predates the channel mechanism: its update # Never move onto a tree that predates the channel or migrate mechanism:
# command cannot switch back, stranding the install # it cannot switch back or finish this update's migration step
if [[ ! -f $src/bin/omarchy-cn-channel ]]; then if [[ ! -f $src/bin/omarchy-cn-channel || ! -f $src/bin/omarchy-cn-migrate ]]; then
git -C "$src" checkout -q "$old" git -C "$src" checkout -q "$old"
echo "$channel 通道的目标发布早于通道机制,已回退;请使用 nightly 或更新的发布" >&2 echo "$channel 通道的目标发布早于当前更新机制,已回退;请使用 nightly 或更新的发布" >&2
exit 1 exit 1
fi fi
@@ -65,18 +67,6 @@ echo "Channel: $channel, source: $old -> $new"
"$src/bin/omarchy-cn-install-overlay" "$src/bin/omarchy-cn-install-overlay"
# Run each not-yet-completed migration in filename order, one marker per file "$src/bin/omarchy-cn-migrate"
if [[ -d $src/cn/migrations ]]; then
mkdir -p "$MIGRATION_DONE_DIR"
for m in "$src"/cn/migrations/*.sh; do
[[ -f $m ]] || continue
name="${m##*/}"
if [[ ! -f $MIGRATION_DONE_DIR/$name ]]; then
echo "Migration: $name"
bash -euo pipefail "$m"
touch "$MIGRATION_DONE_DIR/$name"
fi
done
fi
echo "OmarchyCN update complete ($(omarchy-cn-version 2>/dev/null || echo unknown))" echo "OmarchyCN update complete ($(omarchy-cn-version 2>/dev/null || echo unknown))"
+3
View File
@@ -96,6 +96,9 @@ while IFS=$'\t' read -r name file marker; do
fi fi
done < <(migration_entries) done < <(migration_entries)
# Here (not omarchy-update) so the first update from a pre-cn package runs them
OMARCHY_PATH="$OMARCHY_PATH" omarchy-cn-migrate
# Clear a login-time notification the user left sitting there and then resolved # Clear a login-time notification the user left sitting there and then resolved
# by running migrations some other way. The substring matches both the current # by running migrations some other way. The substring matches both the current
# and legacy notification titles. # and legacy notification titles.
+2 -1
View File
@@ -1,7 +1,8 @@
{ {
"_verified": "2026-08-24, AUR RPC 实证在维护且未 out-of-date", "_verified": "2026-08-28, AUR RPC 实证在维护且未 out-of-date",
"apps": { "apps": {
"wechat": { "name": "微信", "source": "aur", "package": "wechat-universal-bwrap", "license": "proprietary" }, "wechat": { "name": "微信", "source": "aur", "package": "wechat-universal-bwrap", "license": "proprietary" },
"wecom": { "name": "企业微信", "source": "aur", "package": "com.qq.weixin.work.deepin", "license": "proprietary" },
"qq": { "name": "QQ", "source": "aur", "package": "linuxqq", "license": "proprietary" }, "qq": { "name": "QQ", "source": "aur", "package": "linuxqq", "license": "proprietary" },
"feishu": { "name": "飞书", "source": "aur", "package": "feishu-bin", "license": "proprietary" }, "feishu": { "name": "飞书", "source": "aur", "package": "feishu-bin", "license": "proprietary" },
"dingtalk": { "name": "钉钉", "source": "aur", "package": "dingtalk-bin", "license": "proprietary" }, "dingtalk": { "name": "钉钉", "source": "aur", "package": "dingtalk-bin", "license": "proprietary" },
+2 -1
View File
@@ -385,6 +385,7 @@
"omarchycn.ai.doctor": {"icon":"󰨮","label":"AI 诊断","action":"omarchy-launch-floating-terminal-with-presentation omarchy-cn-ai-doctor"}, "omarchycn.ai.doctor": {"icon":"󰨮","label":"AI 诊断","action":"omarchy-launch-floating-terminal-with-presentation omarchy-cn-ai-doctor"},
"omarchycn.apps": {"icon":"󰀻","label":"国内应用"}, "omarchycn.apps": {"icon":"󰀻","label":"国内应用"},
"omarchycn.apps.wechat": {"icon":"","label":"微信","disabled":"omarchy-pkg-present wechat-universal-bwrap","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-app-install wechat'"}, "omarchycn.apps.wechat": {"icon":"","label":"微信","disabled":"omarchy-pkg-present wechat-universal-bwrap","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-app-install wechat'"},
"omarchycn.apps.wecom": {"icon":"","label":"企业微信","disabled":"omarchy-pkg-present com.qq.weixin.work.deepin","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-app-install wecom'"},
"omarchycn.apps.qq": {"icon":"","label":"QQ","disabled":"omarchy-pkg-present linuxqq","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-app-install qq'"}, "omarchycn.apps.qq": {"icon":"","label":"QQ","disabled":"omarchy-pkg-present linuxqq","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-app-install qq'"},
"omarchycn.apps.feishu": {"icon":"","label":"飞书","disabled":"omarchy-pkg-present feishu-bin","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-app-install feishu'"}, "omarchycn.apps.feishu": {"icon":"","label":"飞书","disabled":"omarchy-pkg-present feishu-bin","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-app-install feishu'"},
"omarchycn.apps.dingtalk": {"icon":"","label":"钉钉","disabled":"omarchy-pkg-present dingtalk-bin","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-app-install dingtalk'"}, "omarchycn.apps.dingtalk": {"icon":"","label":"钉钉","disabled":"omarchy-pkg-present dingtalk-bin","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-app-install dingtalk'"},
@@ -417,7 +418,7 @@
"omarchycn.diagnostics.doctor": {"icon":"󰨮","label":"系统诊断","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-doctor all'"}, "omarchycn.diagnostics.doctor": {"icon":"󰨮","label":"系统诊断","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-doctor all'"},
"omarchycn.diagnostics.mirror-fix": {"icon":"󰇧","label":"镜像修复","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-doctor mirror --fix'"}, "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.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.update": {"icon":"","label":"更新","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.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"}, "omarchycn.about": {"icon":"","label":"关于","action":"omarchy-launch-floating-terminal-with-presentation omarchy-cn-status"},
} }
+20 -12
View File
@@ -2,28 +2,36 @@
每次发布 `<upstream>-cn.<n>` 按序执行,任一步失败即停止: 每次发布 `<upstream>-cn.<n>` 按序执行,任一步失败即停止:
1. `./test/all`:相对上游基线零新增失败;`test/shell.d/omarchycn-*.sh` 全绿 1. `cn/release` 写入本次发布号 `<n>`(上次 +1)并提交;此后所有构建产物自称 cn.`<n>`
2. 用 `--local-source` 重建 ISO(`packages/omarchy-pkgs-cn.patch` 已应用到 omarchy-pkgs) 2. `./test/all`:相对上游基线零新增失败;`test/shell.d/omarchycn-*.sh` 全绿
3. 验证 omarchy-dev 包含 cn 层(`tar -tf … | grep usr/share/omarchy/cn/`) 3. 用 `--local-source` 重建 ISO(`packages/omarchy-pkgs-cn.patch` 已应用到 omarchy-pkgs)
4. QEMU OVMF UEFI 冒烟:进入安装器欢迎屏 4. 验证 omarchy-dev 包含 cn 层(`tar -tf … | grep usr/share/omarchy/cn/`)
5. `sha256sum` → `SHA256SUMS.txt`;签名 SUMS 与 ISO(发布子钥) 5. QEMU OVMF UEFI 冒烟:进入安装器欢迎屏
6. SBOM 两份:syft(live airootfs)+ 离线仓库 .PKGINFO 采集 6. `sha256sum` → `SHA256SUMS.txt`;签名 SUMS 与 ISO(发布子钥)
7. `release.json`(版本、双向提交、包版本表、迁移列表、min_compatible、产物清单)→ 签名 release.json 7. SBOM 两份:syft(live airootfs)+ 离线仓库 .PKGINFO 采集
8. 把本次构建的 `omarchy-dev` / `omarchy-settings-dev` 发布到 [omarchycn] registry 8. `release.json`(版本、双向提交、包版本表、迁移列表、min_compatible、产物清单)→ 签名 release.json
9. 把本次构建的 `omarchy-dev` / `omarchy-settings-dev` 发布到 [omarchycn] registry
(`packages/publish-cn-packages.sh`;先于公开 Release,一键转换才不会装到旧包) (`packages/publish-cn-packages.sh`;先于公开 Release,一键转换才不会装到旧包)
9. 建 tag 与 Release,上传全部产物,Release Notes 写明上游基线与已知问题 10. ISO 上传 R2 下载站:`packages/upload-release-r2.sh <版本> <iso>`(脚本自带匿名回读 sha256 复核,
10. 匿名回读已发布 ISO 并 sha256 复核 == 本地构建值 并自动只保留最新 2 个版本目录;公网地址 `https://dl.zacharyzhang.com/<版本>/<文件名>`,
11. `cn/release` 数字 +1,提交 凭据在 `~/omarchycn-build/.r2.env`)
11. 建 tag 与 Release,上传其余小件产物(SUMS/签名/SBOM/release.json),Release Notes 写明上游基线、
已知问题与 R2 ISO 下载链接;ISO 不再挂 Gitea 附件(带宽走 R2)
12. 匿名回读 R2 ISO 与 Release 附件并 sha256 复核 == 本地构建值
## 版本规则 ## 版本规则
`<omarchy-upstream-version>-cn.<n>`;`min_compatible` 只在有破坏性迁移时前移。 `<omarchy-upstream-version>-cn.<n>`;`min_compatible` 只在有破坏性迁移时前移。
`cn/release` 表示当前树所属的发布号:发布的第一步把它写成本次发布号,两次发布之间 HEAD 保持上一
发布号(与上游 `version` 文件同语义)。发布之间构建并发到 [omarchycn] 的中间包因此自称上一发布号,
不会出现自称未发布版本的产物。
# 上游同步 SLA # 上游同步 SLA
- `upstream-sync.yml` 每日拉取 basecamp/omarchy quattro,自动开同步 PR(含试合并冲突标注) - `upstream-sync.yml` 每日拉取 basecamp/omarchy quattro,自动开同步 PR(含试合并冲突标注)
- 常规变更:7 天内完成审查合并;上游安全修复:48 小时内 - 常规变更:7 天内完成审查合并;上游安全修复:48 小时内
- 合并后必须重跑第 1 步测试门禁 - 合并后必须重跑第 2 步测试门禁
# 安全响应 # 安全响应
+1 -1
View File
@@ -2,7 +2,7 @@
## 下载与校验 ## 下载与校验
从 [Releases](https://git.zacharyzhang.com/ZacharyZhang-NY/omarchycn/releases) 下载最新 ISO 及 `SHA256SUMS.txt`、`SHA256SUMS.txt.asc`: ISO 从下载站 `https://dl.zacharyzhang.com/<版本>/<文件名>` 获取([Releases](https://git.zacharyzhang.com/ZacharyZhang-NY/omarchycn/releases) 页面给出各版本的具体链接),`SHA256SUMS.txt`、`SHA256SUMS.txt.asc` 仍从 Releases 附件下载:
```bash ```bash
curl -sSf https://git.zacharyzhang.com/ZacharyZhang-NY/omarchycn/raw/branch/quattro/cn/keys/omarchycn-release.asc | gpg --import curl -sSf https://git.zacharyzhang.com/ZacharyZhang-NY/omarchycn/raw/branch/quattro/cn/keys/omarchycn-release.asc | gpg --import
+4 -2
View File
@@ -2,8 +2,10 @@
## 更新 ## 更新
- ISO 安装:系统随上游 `omarchy update`;cn 层当前随新版 ISO 迭代([omarchycn] pacman 仓库暂只分发 keyring,omarchy-dev 包上仓后将改为 pacman 更新) 所有安装形态都可以用 `omarchycn update`(即 `omarchy cn update`):
- Overlay 安装:`omarchycn update`(拉取源码 → 重装 overlay → 执行未跑过的 cn 迁移)
- ISO / 一键转换等包安装:完整更新管线(系统包 + [omarchycn] 仓库里的 cn 包 → 应用目录、镜像表、AI registry 随包更新 → 上游迁移与 cn 迁移);直接跑 `omarchy update` 效果相同(cn 迁移已并入其管线)
- Overlay 安装:只更新 cn 层(拉取源码 → 重装 overlay → 执行未跑过的 cn 迁移);底下的 Omarchy 系统仍用 `omarchy update` 更新
## 备份位置 ## 备份位置
+41
View File
@@ -0,0 +1,41 @@
#!/bin/bash
# Upload release artifacts to the omarchycn-releases R2 bucket, then verify each
# by anonymous public re-read (sha256 must match the local file).
# Usage: upload-release-r2.sh <version> <file...>
# Public URL shape: https://dl.zacharyzhang.com/<version>/<name>
# Credentials: ~/omarchycn-build/.r2.env (rclone S3 env config, mode 0600)
set -euo pipefail
BUCKET=omarchycn-releases
PUBLIC=https://dl.zacharyzhang.com
version="${1:?usage: upload-release-r2.sh <version> <file...>}"
shift
(($#)) || { echo "no files given" >&2; exit 1; }
source "$HOME/omarchycn-build/.r2.env"
for f in "$@"; do
[[ -f $f ]] || { echo "no such file: $f" >&2; exit 1; }
name=$(basename "$f")
echo "==> $name -> $PUBLIC/$version/$name"
rclone copyto --s3-upload-cutoff 200M --s3-chunk-size 100M --retries 6 "$f" "r2:$BUCKET/$version/$name"
want=$(sha256sum "$f" | cut -d' ' -f1)
got=$(curl -fsSL "$PUBLIC/$version/$name" | sha256sum | cut -d' ' -f1)
if [[ $want != "$got" ]]; then
echo "sha256 mismatch for $name: local $want public $got" >&2
exit 1
fi
echo "verified $want"
done
# Keep the newest two release prefixes (current + rollback), purge older ones
keep=2
mapfile -t versions < <(rclone lsf --dirs-only "r2:$BUCKET" | sed 's|/$||' | sort -V)
if ((${#versions[@]} > keep)); then
for old in "${versions[@]:0:${#versions[@]}-keep}"; do
echo "==> purge old release $old"
rclone purge "r2:$BUCKET/$old"
done
fi
+3 -3
View File
@@ -25,7 +25,7 @@
<main> <main>
<section class="band hero" aria-labelledby="hero-title"> <section class="band hero" aria-labelledby="hero-title">
<p class="eyebrow" style="grid-column: 1 / 13">OMARCHY CN · 4.0.0.alpha-cn.6</p> <p class="eyebrow" style="grid-column: 1 / 13">OMARCHY CN · 4.0.0.alpha-cn.7</p>
<h1 id="hero-title" style="grid-column: 1 / 12"> <h1 id="hero-title" style="grid-column: 1 / 12">
<span class="line">华丽、现代、观点鲜明</span><span class="line">的 Linux。中国版。</span> <span class="line">华丽、现代、观点鲜明</span><span class="line">的 Linux。中国版。</span>
</h1> </h1>
@@ -36,7 +36,7 @@
<div class="actions" style="grid-column: 1 / 13"> <div class="actions" style="grid-column: 1 / 13">
<a <a
class="btn" class="btn"
href="https://git.zacharyzhang.com/ZacharyZhang-NY/omarchycn/releases/download/4.0.0.alpha-cn.6/omarchy-2026.08.27-x86_64-local.iso" href="https://dl.zacharyzhang.com/4.0.0.alpha-cn.7/omarchy-2026.08.29-x86_64-local.iso"
> >
<span class="i" data-icon="Download" aria-hidden="true"></span>下载 ISO<span class="btn-meta">5.9 GB</span> <span class="i" data-icon="Download" aria-hidden="true"></span>下载 ISO<span class="btn-meta">5.9 GB</span>
</a> </a>
@@ -93,7 +93,7 @@
<div><dt>签名子钥</dt><dd>PGP 211B9B82E17CFB67</dd></div> <div><dt>签名子钥</dt><dd>PGP 211B9B82E17CFB67</dd></div>
<div> <div>
<dt>清单</dt> <dt>清单</dt>
<dd><a href="https://git.zacharyzhang.com/ZacharyZhang-NY/omarchycn/releases/download/4.0.0.alpha-cn.6/SHA256SUMS.txt">SHA256SUMS.txt</a> · <a href="https://git.zacharyzhang.com/ZacharyZhang-NY/omarchycn/releases/download/4.0.0.alpha-cn.6/SHA256SUMS.txt.asc">SHA256SUMS.txt.asc</a></dd> <dd><a href="https://git.zacharyzhang.com/ZacharyZhang-NY/omarchycn/releases/download/4.0.0.alpha-cn.7/SHA256SUMS.txt">SHA256SUMS.txt</a> · <a href="https://git.zacharyzhang.com/ZacharyZhang-NY/omarchycn/releases/download/4.0.0.alpha-cn.7/SHA256SUMS.txt.asc">SHA256SUMS.txt.asc</a></dd>
</div> </div>
</dl> </dl>
</section> </section>
+2 -1
View File
@@ -4,8 +4,9 @@ set -euo pipefail
source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh" source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh"
# cn-convert is a curl-able bootstrap like upgrade-to-quattro: helpers may not exist yet
raw_command_checks=$(rg -l 'command -v' "$ROOT/bin" \ raw_command_checks=$(rg -l 'command -v' "$ROOT/bin" \
| rg -v '/omarchy-(cmd-|pkg-|upgrade-to-quattro)' || true) | rg -v '/omarchy-(cmd-|pkg-|upgrade-to-quattro|cn-convert$)' || true)
[[ -z $raw_command_checks ]] || fail "bin commands use command helpers" "$raw_command_checks" [[ -z $raw_command_checks ]] || fail "bin commands use command helpers" "$raw_command_checks"
pass "bin commands use command helpers" pass "bin commands use command helpers"
+5 -2
View File
@@ -22,7 +22,7 @@ SH
calls="$test_tmp/calls" calls="$test_tmp/calls"
if ! HOME="$test_home" OMARCHY_PATH="$test_root" "$ROOT/bin/omarchy-migrate" --pending >"$test_tmp/pending.out"; then if ! HOME="$test_home" OMARCHY_PATH="$test_root" PATH="$ROOT/bin:$PATH" "$ROOT/bin/omarchy-migrate" --pending >"$test_tmp/pending.out"; then
fail "migration runner reports pending migrations before state exists" fail "migration runner reports pending migrations before state exists"
fi fi
grep -q '^100-first\.sh$' "$test_tmp/pending.out" || fail "migration runner lists first pending migration filename" grep -q '^100-first\.sh$' "$test_tmp/pending.out" || fail "migration runner lists first pending migration filename"
@@ -33,6 +33,7 @@ HOME="$test_home" \
OMARCHY_PATH="$test_root" \ OMARCHY_PATH="$test_root" \
TEST_EXPECTED_OMARCHY_PATH="$test_root" \ TEST_EXPECTED_OMARCHY_PATH="$test_root" \
TEST_CALLS="$calls" \ TEST_CALLS="$calls" \
PATH="$ROOT/bin:$PATH" \
"$ROOT/bin/omarchy-migrate" >"$test_tmp/first-run.out" "$ROOT/bin/omarchy-migrate" >"$test_tmp/first-run.out"
[[ $(sed -n '1p' "$calls") == "first" ]] || fail "migration runner runs first migration" [[ $(sed -n '1p' "$calls") == "first" ]] || fail "migration runner runs first migration"
[[ $(sed -n '2p' "$calls") == "second" ]] || fail "migration runner runs second migration" [[ $(sed -n '2p' "$calls") == "second" ]] || fail "migration runner runs second migration"
@@ -44,11 +45,12 @@ HOME="$test_home" \
OMARCHY_PATH="$test_root" \ OMARCHY_PATH="$test_root" \
TEST_EXPECTED_OMARCHY_PATH="$test_root" \ TEST_EXPECTED_OMARCHY_PATH="$test_root" \
TEST_CALLS="$calls" \ TEST_CALLS="$calls" \
PATH="$ROOT/bin:$PATH" \
"$ROOT/bin/omarchy-migrate" >"$test_tmp/second-run.out" "$ROOT/bin/omarchy-migrate" >"$test_tmp/second-run.out"
[[ $(wc -l <"$calls") -eq 2 ]] || fail "migration runner skips completed migrations" [[ $(wc -l <"$calls") -eq 2 ]] || fail "migration runner skips completed migrations"
pass "migration runner skips completed migrations" pass "migration runner skips completed migrations"
if HOME="$test_home" OMARCHY_PATH="$test_root" "$ROOT/bin/omarchy-migrate" --pending >"$test_tmp/not-pending.out"; then if HOME="$test_home" OMARCHY_PATH="$test_root" PATH="$ROOT/bin:$PATH" "$ROOT/bin/omarchy-migrate" --pending >"$test_tmp/not-pending.out"; then
fail "migration runner reports no pending migrations after state exists" fail "migration runner reports no pending migrations after state exists"
fi fi
pass "migration runner detects no pending migrations" pass "migration runner detects no pending migrations"
@@ -67,6 +69,7 @@ set +e
HOME="$failure_home" \ HOME="$failure_home" \
OMARCHY_PATH="$failure_root" \ OMARCHY_PATH="$failure_root" \
TEST_CALLS="$calls" \ TEST_CALLS="$calls" \
PATH="$ROOT/bin:$PATH" \
"$ROOT/bin/omarchy-migrate" >"$test_tmp/failure.out" 2>"$test_tmp/failure.err" "$ROOT/bin/omarchy-migrate" >"$test_tmp/failure.out" 2>"$test_tmp/failure.err"
failure_status=$? failure_status=$?
set -e set -e
+42
View File
@@ -121,6 +121,48 @@ revert_mirror=$(grep -m1 '^MIRROR_LINE=' "$ROOT/bin/omarchy-cn-revert" | cut -d'
fail "revert MIRROR_LINE drifted from cn/lib/mirror.sh" "$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" pass "convert/revert pair: parse, main() guard, ask=4, mirror constant in sync"
# Update pipeline: cn migrations ride omarchy-migrate, cn update serves both forms
bash -n "$ROOT/bin/omarchy-cn-migrate" || fail "omarchy-cn-migrate parses"
grep -q '^OMARCHY_PATH="\$OMARCHY_PATH" omarchy-cn-migrate$' "$ROOT/bin/omarchy-migrate" ||
fail "omarchy-migrate runs cn migrations (upstream-sync drift)"
grep -qE '^\s*exec omarchy-update$' "$ROOT/bin/omarchy-cn-update" ||
fail "omarchy-cn-update serves package installs via omarchy-update"
grep -q '^if \[\[ .* ! -f \$src/bin/omarchy-cn-migrate \]\]' "$ROOT/bin/omarchy-cn-update" ||
fail "downgrade guard checks for omarchy-cn-migrate"
pass "update pipeline: cn migrate wired into omarchy-migrate, package branch present"
# cn migrate runner: pending run once, markers at the contract path suppress and persist
mig_root=$(mktemp -d)
mig_done="$HOME/.local/state/omarchycn/migrations-done"
mkdir -p "$mig_root/cn/migrations" "$mig_done"
printf 'echo seeded >> "$HOME/mig-calls"\n' > "$mig_root/cn/migrations/999999999.sh"
printf 'echo ran >> "$HOME/mig-calls"\n' > "$mig_root/cn/migrations/1000000000.sh"
touch "$mig_done/999999999.sh"
OMARCHY_PATH="$mig_root" omarchy-cn-migrate > /dev/null
OMARCHY_PATH="$mig_root" omarchy-cn-migrate > /dev/null
[[ $(cat "$HOME/mig-calls") == "ran" ]] || fail "cn migrate runs pending once, honors seeded markers" "$(cat "$HOME/mig-calls")"
[[ -f $mig_done/1000000000.sh ]] || fail "cn migrate writes markers to the contract path"
rm -rf "$mig_root"
pass "omarchy-cn-migrate marker contract holds"
# Every cn command must be executable (the menu launches them directly)
nonexec=$(find "$ROOT/bin" -maxdepth 1 \( -name omarchycn -o -name 'omarchy-cn-*' \) ! -perm -u+x)
[[ -z $nonexec ]] || fail "non-executable cn commands" "$nonexec"
if [[ -d $ROOT/.git ]]; then
badmode=$(git -C "$ROOT" ls-files -s bin/omarchycn 'bin/omarchy-cn-*' | grep -v '^100755' || true)
[[ -z $badmode ]] || fail "cn commands tracked without exec mode" "$badmode"
fi
pass "all cn commands carry the executable bit"
# App catalog and menu install entries stay in sync
catalog_ids=$(jq -r '.apps | keys[]' "$ROOT/cn/apps.json" | sort)
menu_ids=$(grep -v '^\s*//' "$ROOT/default/omarchy/omarchy-menu.jsonc" |
grep -o '"omarchycn\.apps\.[a-z-]*"' |
sed 's/.*apps\.//; s/"//' | sort)
diff <(printf '%s\n' "$catalog_ids") <(printf '%s\n' "$menu_ids") > /dev/null ||
fail "menu app entries drift from cn/apps.json"
pass "menu app entries match the catalog"
# Menu: OmarchyCN entries parse and reference only existing commands # Menu: OmarchyCN entries parse and reference only existing commands
node -e ' node -e '
const fs = require("fs"); const fs = require("fs");