Author SHA1 Message Date
ZacharyZhang-NYandClaude Fable 5 c4dcd2b63a Document and test the [omarchy] mirror wiring
Static suite assertions pin the stable conf's server order and keep
edge/rc upstream-only; the guard test proves exact-line semantics.
docs/pacman-repo.md gains the mirror section with the honest
operational contract: staleness is invisible to pacman, fallback
fires only on retrieval failure, and omarchy-refresh-pacman's -Syyuu
downgrade wipes the cn layer while upstream ships older omarchy-dev.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019hLK3wsDuKVAC37GgDqg6H
2026-08-27 16:29:34 -04:00
ZacharyZhang-NYandClaude Fable 5 b183be2832 Put the OmarchyCN [omarchy] mirror first on the stable channel
The Gitea mirror db is registry-signed, so installs trust the registry
key right after the pacman.conf restore, and a cn migration does the
same on existing systems with an idempotent exact-line guard. The
insertion lives in cn/lib/mirror.sh so 'omarchycn doctor mirror --fix'
can restore the line after omarchy-refresh-pacman resets an overlay
system's conf. Only stable is mirrored: the Gitea repository name must
equal the pacman section name, and edge/rc stay on upstream directly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019hLK3wsDuKVAC37GgDqg6H
2026-08-27 16:20:48 -04:00
ZacharyZhang-NYandClaude Fable 5 fc9afae2b6 Cover the ollama provider paths in the AI mock regression suite
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019hLK3wsDuKVAC37GgDqg6H
2026-08-27 16:02:06 -04:00
ZacharyZhang-NYandClaude Fable 5 111b857cda Add local Ollama as an AI Hub provider for claude-code
Ollama v0.14+ speaks the Anthropic Messages API natively, so the
registry drives it with a fixed 'ollama' token and runtime-listed
models: static_token skips secret storage everywhere keys resolve,
models_dynamic defers model validation to the live /api/tags list,
and the setup wizard installs the right GPU variant and starts the
service before listing local models. Doctor stops treating the
endpoint port as part of the hostname.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019hLK3wsDuKVAC37GgDqg6H
2026-08-27 15:55:15 -04:00
ZacharyZhang-NYandClaude Fable 5 4b280a1767 Add DSH to the agent roster and Install > AI
Official npm @deepseek-ai/dsh (bin: dsh) rides the mise path like Dim.
dsh has no TUI, so the interactive launch is the documented 'dsh web'
and one-shot prompts use 'dsh --profile headless'. Auth is dsh-managed,
so it stays out of the AI Hub registry.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019hLK3wsDuKVAC37GgDqg6H
2026-08-27 15:42:46 -04:00
ZacharyZhang-NYandClaude Fable 5 602a82621a Run the package repo mirror sync from CI every six hours
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019hLK3wsDuKVAC37GgDqg6H
2026-08-27 15:34:44 -04:00
ZacharyZhang-NYandClaude Fable 5 87b4cc4da1 Mirror the upstream stable package repo into the Gitea Arch registry
packages/sync-omarchy-repo.sh diffs the upstream omarchy.db against the
registry's own db by filename, streams missing packages through (409 =
already present), and deletes entries upstream no longer lists. Only a
404 counts as first sync; any other mirror-db failure aborts rather
than faking an empty mirror.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019hLK3wsDuKVAC37GgDqg6H
2026-08-27 15:34:01 -04:00
ZacharyZhang-NYandClaude Fable 5 70895d4f1c Bump cn/release to 6 after publishing 4.0.0.alpha-cn.5
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKxGW1raAWaqeU8WdHsMsp
2026-08-25 22:36:59 -04:00
ZacharyZhang-NYandClaude Fable 5 aa87ed97c1 Dim prompts use the documented dim exec form
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKxGW1raAWaqeU8WdHsMsp
2026-08-25 15:03:35 -04:00
ZacharyZhang-NYandClaude Fable 5 a3cd27dba3 Add Dim Agent CLI to the agent roster and Install > AI
npm dimcode (bin: dim) rides the mise path like Deep Code; entries
land alphabetically in the Default Agent and Install > AI menus.
CLI-only per dimagent.cn, login handled by the CLI itself.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKxGW1raAWaqeU8WdHsMsp
2026-08-25 14:59:18 -04:00
ZacharyZhang-NYandClaude Fable 5 0812b28527 Detect the missing official repo dbs by core.db, not any db
pacstrap leaves the offline repo's db in the target's sync dir, so
the any-db glob skipped the first-run update path on real installs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKxGW1raAWaqeU8WdHsMsp
2026-08-25 13:50:11 -04:00
ZacharyZhang-NYandClaude Fable 5 9bf870449b Link kimi into ~/.local/bin after the official install
The installer only appends PATH to .bashrc, so the fresh binary was
invisible to the launching process and the login never started.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKxGW1raAWaqeU8WdHsMsp
2026-08-25 13:46:23 -04:00
ZacharyZhang-NYandClaude Fable 5 9be4d24d6d App installs route first-time updates through omarchy-update
Direct pacman -Syu trips the update pacman guard once real upgrades
exist; the catalog installer now runs the upstream update pipeline
interactively and fails fast with instructions when non-interactive.
omarchy-cn-kimi-install gains its executable bit.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKxGW1raAWaqeU8WdHsMsp
2026-08-25 13:27:38 -04:00
ZacharyZhang-NYandClaude Fable 5 a317bfb36f Fix China app installs and wire the CN AI stack into Install > AI
Offline installs ship no pacman sync db, so yay resolved official
repo dependencies as AUR packages and every catalog install failed;
omarchy-cn-app-install now runs a full -Syu first (verified end to
end: WeChat builds and installs in the VM). Kimi Code gains a real
installer command reused by the harness registry, the default-agent
path, and new Install > AI entries (Kimi Code, Deep Code, AI Hub),
and the AI Hub wizard offers to launch native harnesses immediately
so their official CLI login runs, matching how Claude Code works.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKxGW1raAWaqeU8WdHsMsp
2026-08-25 13:17:52 -04:00
ZacharyZhang-NYandClaude Fable 5 0f888ffe31 Bump cn/release to 5 after publishing 4.0.0.alpha-cn.4
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKxGW1raAWaqeU8WdHsMsp
2026-08-25 12:25:27 -04:00
ZacharyZhang-NY 41ddd9052a Update README.md 2026-08-25 16:14:20 +00:00
ZacharyZhang-NYandClaude Fable 5 68a994b223 Document the Chinese-first defaults in the OmarchyCN layer
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKxGW1raAWaqeU8WdHsMsp
2026-08-25 12:03:04 -04:00
ZacharyZhang-NYandClaude Fable 5 d7938dd10b Localize the fingerprint first-run notice
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKxGW1raAWaqeU8WdHsMsp
2026-08-25 11:21:31 -04:00
ZacharyZhang-NYandClaude Fable 5 f338f6cb15 Localize update confirmation and first-run notifications
The update prompt speaks Chinese and points What's new at the
OmarchyCN releases page; the Wi-Fi, update, keybindings, dictation,
and default-agent first-run notices follow.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKxGW1raAWaqeU8WdHsMsp
2026-08-25 11:18:02 -04:00
ZacharyZhang-NYandClaude Fable 5 b85a998404 Keybindings menu test fixtures follow localization
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKxGW1raAWaqeU8WdHsMsp
2026-08-25 11:16:37 -04:00
ZacharyZhang-NYandClaude Fable 5 e32f1eca8e Binding-conflicts test follows localized descriptions
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKxGW1raAWaqeU8WdHsMsp
2026-08-25 11:12:43 -04:00
ZacharyZhang-NYandClaude Fable 5 6e3eb678b1 Bar panel test expectation follows localization
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKxGW1raAWaqeU8WdHsMsp
2026-08-25 11:10:09 -04:00
ZacharyZhang-NYandClaude Fable 5 2fce4924e6 Remaining scratchpad test expectations follow localization
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKxGW1raAWaqeU8WdHsMsp
2026-08-25 11:09:55 -04:00
ZacharyZhang-NYandClaude Fable 5 6e73f9f797 Scratchpad binding test follows the localized description
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKxGW1raAWaqeU8WdHsMsp
2026-08-25 11:09:39 -04:00
ZacharyZhang-NYandClaude Fable 5 9e1bb767c0 Voxtype binding test follows localized descriptions
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKxGW1raAWaqeU8WdHsMsp
2026-08-25 11:09:23 -04:00
ZacharyZhang-NYandClaude Fable 5 2eff2a37b3 Localize dynamic bind templates and the Super+K matcher
Workspace, group-window, and bar-panel loops emit Chinese
descriptions; omarchy-menu-keybindings' merge list and priority
patterns follow them, so combined chords and curated ordering
survive localization. Affected tests updated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKxGW1raAWaqeU8WdHsMsp
2026-08-25 11:09:05 -04:00
ZacharyZhang-NYandClaude Fable 5 e673e63baa Localize keybinding descriptions for the Super+K cheatsheet
All 176 bind descriptions across the shipped Hyprland binding files
switch to Simplified Chinese; brand names stay English.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKxGW1raAWaqeU8WdHsMsp
2026-08-25 11:03:38 -04:00
ZacharyZhang-NYandClaude Fable 5 907f7b81aa Fix kimi install error masking, prompt flag, and setup default hop
The official installer downloads to a temp file so curl failures
cannot be masked by the pipe; Kimi prompts use --prompt per the CLI
reference; the AI Hub wizard now offers omarchy-cn-ai-default for
claude-code/codex profiles so the combo really becomes the default
agent.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKxGW1raAWaqeU8WdHsMsp
2026-08-25 11:01:50 -04:00
ZacharyZhang-NYandClaude Fable 5 8ce169f7fa Keep the agent menu alphabetical with the CN additions
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKxGW1raAWaqeU8WdHsMsp
2026-08-25 10:56:16 -04:00
ZacharyZhang-NYandClaude Fable 5 0778554984 Add Kimi Code and Deep Code to the default agent roster
kimi installs through its official script rather than mise;
deepcode rides the existing mise path as npm:@vegamo/deepcode-cli.
Both gain launch branches and Default Agent menu entries, plus an
AI Hub entry for provider combos (Kimi/DeepSeek/Z.AI/MiniMax over
Claude Code) via the omarchycn setup wizard.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKxGW1raAWaqeU8WdHsMsp
2026-08-25 10:55:45 -04:00
ZacharyZhang-NYandClaude Fable 5 6b491d52be Add MiniMax as an Anthropic-compatible AI provider
MiniMax-M3[1m] via api.minimaxi.com/anthropic per the official
Claude Code token-plan docs; the claude-code combo enters the
compatibility matrix as stable with mock regression coverage,
including the Haiku-slot fallback to the single model.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKxGW1raAWaqeU8WdHsMsp
2026-08-25 10:49:53 -04:00
ZacharyZhang-NYandClaude Fable 5 e57d2a3424 Plugin menu test expects the localized labels
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKxGW1raAWaqeU8WdHsMsp
2026-08-25 10:38:21 -04:00
ZacharyZhang-NYandClaude Fable 5 b7dd8c7125 Menu search test follows the localized labels
The exact-label ranking case now queries in Chinese, and a new case
pins English reachability through the leaf id.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKxGW1raAWaqeU8WdHsMsp
2026-08-25 10:37:59 -04:00
ZacharyZhang-NYandClaude Fable 5 f182234796 Localize the Omarchy menu and add AI Hub and China apps sections
All category and action labels switch to Simplified Chinese with
brand names kept in English per the PRD terminology rule. The
OmarchyCN section gains an AI Hub submenu (wizard, profiles, test,
doctor) and a China apps submenu backed by the cn/apps.json catalog.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKxGW1raAWaqeU8WdHsMsp
2026-08-25 10:36:42 -04:00
ZacharyZhang-NYandClaude Fable 5 b7aa5d9d7d Drop mailto handler for removed HEY launcher from mimeapps
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKxGW1raAWaqeU8WdHsMsp
2026-08-25 10:33:49 -04:00
ZacharyZhang-NYandClaude Fable 5 43f274ce63 Docs: stop claiming removed apps ship by default
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKxGW1raAWaqeU8WdHsMsp
2026-08-25 10:32:51 -04:00
ZacharyZhang-NYandClaude Fable 5 763ebb83c3 Purge remaining references to removed western apps
The quattro upgrade script no longer registers the HEY mailto
handler, installer tips stop naming LibreOffice, and the hotkeys,
GUIs, and web-apps manuals drop the entries for removed apps.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKxGW1raAWaqeU8WdHsMsp
2026-08-25 10:30:28 -04:00
ZacharyZhang-NYandClaude Fable 5 6d8acfca9f Drop western default apps from the CN default set
Basecamp, Discord, HEY, Google Contacts/Maps/Messages/Photos,
WhatsApp, and X lose their shipped launchers, webapp keybindings,
and the whatsapp-slim extension; aether, libreoffice-fresh, and
obs-studio leave the base package set. The HEY mailto handler and
its registration go with them. Preinstall add/remove lists, the
launcher hide list, and chromium flags stay in sync.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKxGW1raAWaqeU8WdHsMsp
2026-08-25 10:23:52 -04:00
ZacharyZhang-NYandClaude Fable 5 7150f63544 Ship Chinese IME and font fallback by default on zh_CN systems
fcitx5-rime, fcitx5-chinese-addons, and fcitx5-configtool join the
base package set, and a provisioning step seeds the Rime profile and
CJK fontconfig for users on systems whose locale is zh_CN, so Chinese
input works at first boot without omarchycn setup.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKxGW1raAWaqeU8WdHsMsp
2026-08-25 10:14:00 -04:00
ZacharyZhang-NYandClaude Fable 5 e71a9de012 Install zh_CN.UTF-8 as system language for Chinese installs
The configurator wrote en_US.UTF-8 unconditionally, so a Chinese
install booted into an English system. sys_lang now follows the
installer language, and both zh_CN and en_US locales are always
generated in the target.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKxGW1raAWaqeU8WdHsMsp
2026-08-25 10:00:14 -04:00
ZacharyZhang-NYandClaude Fable 5 960e0a6211 Bump cn/release to 4 after publishing 4.0.0.alpha-cn.3
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKxGW1raAWaqeU8WdHsMsp
2026-08-25 08:57:39 -04:00
91 changed files with 1156 additions and 882 deletions
+24
View File
@@ -0,0 +1,24 @@
name: pkg-repo-sync
on:
schedule:
- cron: "17 */6 * * *"
workflow_dispatch:
jobs:
sync:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: quattro
- name: Mirror upstream [omarchy] stable into the Gitea Arch registry
env:
PKG_SYNC_TOKEN: ${{ secrets.PKG_SYNC_TOKEN }}
run: |
set -euo pipefail
if ! command -v zstd > /dev/null; then
apt-get update -qq && apt-get install -y -qq zstd
fi
bash packages/sync-omarchy-repo.sh
+6 -2
View File
@@ -19,10 +19,14 @@ This fork carries the OmarchyCN China-integration layer on top of upstream `base
- `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-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/` - 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`
- 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`
- Upstream sync: `.gitea/workflows/upstream-sync.yml` opens a PR per upstream change; keep upstream file edits minimal (currently: one `GROUP_DESCRIPTIONS[cn]` line in `bin/omarchy`, the OmarchyCN section in `default/omarchy/omarchy-menu.jsonc`, a rewritten `README.md` (known recurring sync conflict, resolve toward ours), `AGENTS.md` additions, and two `.gitignore` lines) - 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.
- cn tests: `test/shell.d/omarchycn-test.sh`, `test/shell.d/omarchycn-ai-test.sh` - 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
- 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)
- 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
+1 -3
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.1`(基于上游 `quattro` 分支构建的基线 ISO)。 当前版本 `4.0.0.alpha-cn.4`(基于上游 `quattro` 分支构建的基线 ISO)。
## 特性 ## 特性
@@ -15,8 +15,6 @@
- Btrfs + Snapper 更新前快照与系统回滚 - Btrfs + Snapper 更新前快照与系统回滚
- archiso 离线安装镜像,支持无人值守安装与双系统引导 - archiso 离线安装镜像,支持无人值守安装与双系统引导
OmarchyCN 增强(开发中,按路线图逐步交付):
- **中国镜像管理**Arch / npm / pip / Cargo / Go 等软件源测速、自动选择与故障切换 - **中国镜像管理**Arch / npm / pip / Cargo / Go 等软件源测速、自动选择与故障切换
- **中文环境开箱即用**zh_CN locale、思源黑体 / 宋体字体栈、高分屏分数缩放预设 - **中文环境开箱即用**zh_CN locale、思源黑体 / 宋体字体栈、高分屏分数缩放预设
- **中文输入法**Fcitx5 + Rime 预配置,Wayland / GTK / Qt / Electron 全栈兼容,快捷键冲突自动处理 - **中文输入法**Fcitx5 + Rime 预配置,Wayland / GTK / Qt / Electron 全栈兼容,快捷键冲突自动处理
-8
View File
@@ -1,8 +0,0 @@
[Desktop Entry]
Version=1.0
Name=Basecamp
Exec=omarchy-launch-webapp https://launchpad.37signals.com
Terminal=false
Type=Application
Icon=basecamp
StartupNotify=true
-8
View File
@@ -1,8 +0,0 @@
[Desktop Entry]
Version=1.0
Name=Discord
Exec=omarchy-launch-webapp https://discord.com/channels/@me
Terminal=false
Type=Application
Icon=omarchy-discord
StartupNotify=true
-8
View File
@@ -1,8 +0,0 @@
[Desktop Entry]
Version=1.0
Name=Google Contacts
Exec=omarchy-launch-webapp https://contacts.google.com/
Terminal=false
Type=Application
Icon=google-contacts
StartupNotify=true
-8
View File
@@ -1,8 +0,0 @@
[Desktop Entry]
Version=1.0
Name=Google Maps
Exec=omarchy-launch-webapp https://maps.google.com
Terminal=false
Type=Application
Icon=google-maps
StartupNotify=true
-8
View File
@@ -1,8 +0,0 @@
[Desktop Entry]
Version=1.0
Name=Google Messages
Exec=omarchy-launch-webapp https://messages.google.com/web/conversations
Terminal=false
Type=Application
Icon=google-messages
StartupNotify=true
-8
View File
@@ -1,8 +0,0 @@
[Desktop Entry]
Version=1.0
Name=Google Photos
Exec=omarchy-launch-webapp https://photos.google.com/
Terminal=false
Type=Application
Icon=google-photos
StartupNotify=true
-9
View File
@@ -1,9 +0,0 @@
[Desktop Entry]
Version=1.0
Name=HEY
Exec=omarchy-webapp-handler-hey %u
Terminal=false
Type=Application
Icon=hey
StartupNotify=true
MimeType=x-scheme-handler/mailto
-8
View File
@@ -1,8 +0,0 @@
[Desktop Entry]
Version=1.0
Name=WhatsApp
Exec=omarchy-launch-webapp https://web.whatsapp.com/
Terminal=false
Type=Application
Icon=whatsapp
StartupNotify=true
-8
View File
@@ -1,8 +0,0 @@
[Desktop Entry]
Version=1.0
Name=X
Exec=omarchy-launch-webapp https://x.com/
Terminal=false
Type=Application
Icon=x
StartupNotify=true
Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 196 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

+24
View File
@@ -99,6 +99,30 @@ pi)
command=(pi) command=(pi)
[[ -n ${prompt:-} ]] && command+=("$prompt") [[ -n ${prompt:-} ]] && command+=("$prompt")
;; ;;
kimi)
command=(kimi)
[[ -n ${prompt:-} ]] && command+=(--prompt "$prompt")
;;
deepcode)
command=(deepcode)
[[ -n ${prompt:-} ]] && command+=("$prompt")
;;
dim)
# `dim exec` is the documented one-shot prompt form
if [[ -n ${prompt:-} ]]; then
command=(dim exec "$prompt")
else
command=(dim)
fi
;;
dsh)
# dsh has no TUI: `dsh web` is the interactive form, headless the one-shot
if [[ -n ${prompt:-} ]]; then
command=(dsh --profile headless "$prompt")
else
command=(dsh web)
fi
;;
*) *)
echo "Unsupported default agent: $agent" >&2 echo "Unsupported default agent: $agent" >&2
exit 1 exit 1
+3 -2
View File
@@ -36,7 +36,7 @@ if omarchy-cmd-missing "$command"; then
$install $install
fi fi
key=$(omarchy-cn-ai-secret get "$provider") key=$(cn_ai_resolve_key "$provider")
case "$harness" in case "$harness" in
claude-code) claude-code)
@@ -45,7 +45,8 @@ claude-code)
settings="$HOME/.claude/settings.json" settings="$HOME/.claude/settings.json"
mkdir -p "${settings%/*}" mkdir -p "${settings%/*}"
base=$(cn_ai_endpoint "$provider" anthropic) base=$(cn_ai_endpoint "$provider" anthropic)
fast=$(cn_ai_fast_model "$provider") # Dynamic-model providers have no fast alias: every tier maps to the model
fast=$(cn_ai_fast_model "$provider" 2>/dev/null || printf '%s' "$model")
current="{}" current="{}"
if [[ -s $settings ]]; then if [[ -s $settings ]]; then
current=$(cat "$settings") current=$(cat "$settings")
+3 -1
View File
@@ -38,6 +38,8 @@ fi
if [[ $proto == "native" ]]; then if [[ $proto == "native" ]]; then
echo "INFO ai: $harness 自管鉴权,跳过 OmarchyCN Key 检查" echo "INFO ai: $harness 自管鉴权,跳过 OmarchyCN Key 检查"
elif cn_ai_static_token "$provider" > /dev/null 2>&1; then
echo "PASS ai: $provider 使用内置 token,无需存储 Key"
elif omarchy-cn-ai-secret get "$provider" > /dev/null 2>&1; then elif omarchy-cn-ai-secret get "$provider" > /dev/null 2>&1; then
echo "PASS ai: $provider API Key stored" echo "PASS ai: $provider API Key stored"
else else
@@ -47,7 +49,7 @@ fi
if [[ $proto != "native" ]]; then if [[ $proto != "native" ]]; then
base=$(cn_ai_endpoint "$provider" "$proto") base=$(cn_ai_endpoint "$provider" "$proto")
host=$(sed -E 's|https?://([^/]+).*|\1|' <<<"$base") host=$(sed -E 's|https?://([^/:]+).*|\1|' <<<"$base")
if getent hosts "$host" > /dev/null 2>&1; then if getent hosts "$host" > /dev/null 2>&1; then
echo "PASS ai: endpoint DNS resolves ($host)" echo "PASS ai: endpoint DNS resolves ($host)"
else else
+1 -1
View File
@@ -32,7 +32,7 @@ fi
case "$config_method" in case "$config_method" in
env) env)
key=$(omarchy-cn-ai-secret get "$provider") key=$(cn_ai_resolve_key "$provider")
if [[ $harness == "codex" ]]; then if [[ $harness == "codex" ]]; then
cn_ai_render_codex_config "$provider" "$model" "$key" cn_ai_render_codex_config "$provider" "$model" "$key"
exec "$command" exec "$command"
+4 -2
View File
@@ -33,7 +33,9 @@ if [[ $level == "unsupported" ]]; then
fi fi
allowlist=$(cn_ai_combo_models "$harness" "$provider") allowlist=$(cn_ai_combo_models "$harness" "$provider")
if [[ -n $allowlist ]]; then if cn_ai_models_dynamic "$provider"; then
: # runtime-listed models; omarchycn ai test validates against the live server
elif [[ -n $allowlist ]]; then
# Combo-restricted model set (e.g. codex uses its own catalog slugs) # Combo-restricted model set (e.g. codex uses its own catalog slugs)
if ! grep -qxF "$model" <<<"$allowlist"; then if ! grep -qxF "$model" <<<"$allowlist"; then
echo "Model $model not supported for $harness x $provider" >&2 echo "Model $model not supported for $harness x $provider" >&2
@@ -68,6 +70,6 @@ secret_ref = "omarchycn://ai/$provider"
EOF EOF
echo "Profile $name: $harness x $provider x $model (compat: $level)" echo "Profile $name: $harness x $provider x $model (compat: $level)"
if ! omarchy-cn-ai-secret get "$provider" > /dev/null 2>&1; then if ! cn_ai_resolve_key "$provider" > /dev/null 2>&1; then
echo "提示: 尚未存储 $provider 的 API Key,运行: omarchycn ai secret set $provider" echo "提示: 尚未存储 $provider 的 API Key,运行: omarchycn ai secret set $provider"
fi fi
+36 -3
View File
@@ -24,7 +24,31 @@ provider=$(printf '%s\n' "${providers[@]}" | gum choose --header "选择 Provide
harness_proto=$(cn_ai_harness_field "$harness" protocol) harness_proto=$(cn_ai_harness_field "$harness" protocol)
allowlist=$(cn_ai_combo_models "$harness" "$provider") allowlist=$(cn_ai_combo_models "$harness" "$provider")
if [[ -n $allowlist ]]; then if cn_ai_models_dynamic "$provider"; then
base=$(cn_ai_endpoint "$provider" "$harness_proto")
if [[ $provider == "ollama" ]]; then
if omarchy-cmd-missing ollama; then
gum confirm "Ollama 未安装,现在安装本地服务?" || exit 1
if omarchy-cmd-present nvidia-smi; then
ollama_pkg=ollama-cuda
elif omarchy-cmd-present rocminfo; then
ollama_pkg=ollama-rocm
else
ollama_pkg=ollama
fi
omarchy-pkg-add "$ollama_pkg"
fi
if ! curl -sf --connect-timeout 3 "$base/api/tags" > /dev/null; then
sudo systemctl enable --now ollama
fi
fi
models=$(curl -sf --connect-timeout 3 "$base/api/tags" | jq -r '.models[].name' || true)
if [[ -z $models ]]; then
echo "无法列出本地模型(服务未运行或尚未拉取):先 ollama pull <模型>(如 qwen3-coder)再重试" >&2
exit 1
fi
model=$(gum choose --header "选择本地模型" <<<"$models")
elif [[ -n $allowlist ]]; then
model=$(gum choose --header "选择模型" <<<"$allowlist") model=$(gum choose --header "选择模型" <<<"$allowlist")
else else
# Hide models bound to a different wire protocol than the harness speaks # Hide models bound to a different wire protocol than the harness speaks
@@ -40,12 +64,15 @@ proto=$(cn_ai_harness_field "$harness" protocol)
if [[ $proto == "native" ]]; then if [[ $proto == "native" ]]; then
omarchy-cn-ai-profile-create "$name" "$harness" "$provider" "$model" omarchy-cn-ai-profile-create "$name" "$harness" "$provider" "$model"
omarchy-cn-ai-profile-use "$name" omarchy-cn-ai-profile-use "$name"
echo "$harness 自管鉴权:首次启动时按其官方流程登录/配置" echo "$harness 自管鉴权:首次启动时在 CLI 内完成官方登录"
if gum confirm "立即启动并完成官方登录?"; then
exec omarchy-cn-ai-launch "$name"
fi
echo "完成。启动: omarchycn ai launch" echo "完成。启动: omarchycn ai launch"
exit 0 exit 0
fi fi
if ! omarchy-cn-ai-secret get "$provider" > /dev/null 2>&1; then if ! cn_ai_resolve_key "$provider" > /dev/null 2>&1; then
key=$(gum input --password --header "$provider API Key(获取: $(jq -r --arg p "$provider" '.providers[$p].key_url' "$CN_AI_PROVIDERS")") key=$(gum input --password --header "$provider API Key(获取: $(jq -r --arg p "$provider" '.providers[$p].key_url' "$CN_AI_PROVIDERS")")
printf '%s' "$key" | omarchy-cn-ai-secret set "$provider" printf '%s' "$key" | omarchy-cn-ai-secret set "$provider"
fi fi
@@ -73,4 +100,10 @@ fi
rm -f "$profile_file.omarchycn-prev" rm -f "$profile_file.omarchycn-prev"
omarchy-cn-ai-profile-use "$name" omarchy-cn-ai-profile-use "$name"
if [[ $harness == "claude-code" || $harness == "codex" ]]; then
if gum confirm "设为系统默认 AgentSuper+Shift+Ctrl+A)?"; then
omarchy-cn-ai-default "$name"
fi
fi
echo "完成。启动: omarchycn ai launch" echo "完成。启动: omarchycn ai launch"
+1 -1
View File
@@ -31,7 +31,7 @@ fi
base="${OMARCHYCN_AI_TEST_BASE_URL:-$(cn_ai_endpoint "$provider" "${proto%-responses}")}" base="${OMARCHYCN_AI_TEST_BASE_URL:-$(cn_ai_endpoint "$provider" "${proto%-responses}")}"
echo "INFO ai-test: $profile ($harness x $provider x $model) -> $base" echo "INFO ai-test: $profile ($harness x $provider x $model) -> $base"
if ! key=$(omarchy-cn-ai-secret get "$provider" 2>/dev/null); then if ! key=$(cn_ai_resolve_key "$provider" 2>/dev/null); then
echo "FAIL ai-test: 未存储 $provider 的 API Key (omarchycn ai secret set $provider)" echo "FAIL ai-test: 未存储 $provider 的 API Key (omarchycn ai secret set $provider)"
exit 1 exit 1
fi fi
+11
View File
@@ -32,6 +32,17 @@ fi
case "$source_type" in case "$source_type" in
aur) aur)
# Offline installs leave only offline.db in sync; without the official
# repo dbs yay treats repo deps as AUR. Upgrades must go through the
# omarchy-update pipeline (pacman guard).
if [[ ! -f /var/lib/pacman/sync/core.db ]]; then
if [[ ! -t 0 ]]; then
echo "首次安装应用前请先完成一次系统更新: omarchy-update" >&2
exit 1
fi
echo "首次安装应用前需要完成一次系统更新。"
omarchy-update
fi
omarchy-pkg-aur-add "$(jq -r '.package' <<<"$entry")" omarchy-pkg-aur-add "$(jq -r '.package' <<<"$entry")"
;; ;;
webapp) webapp)
+26 -1
View File
@@ -69,6 +69,27 @@ check_mirror() {
fi fi
} }
# refresh-pacman restores the checkout's template, which on overlay installs
# has no OmarchyCN mirror line; this check makes that loss visible and fixable
check_omarchy_repo() {
local conf="${OMARCHYCN_PACMAN_CONF:-/etc/pacman.conf}"
if ! grep -q "^Server = https://pkgs.omarchy.org/stable/" "$conf"; then
echo "INFO omarchy-repo: 非 stable 通道,跳过 OmarchyCN 镜像检查"
return 0
fi
if cn_mirror_omarchy_repo_ok; then
echo "PASS omarchy-repo: OmarchyCN 镜像行在位"
return 0
fi
if [[ $fix == "true" ]] && cn_mirror_omarchy_repo_fix && cn_mirror_omarchy_repo_ok; then
echo "PASS omarchy-repo: 已重新插入 OmarchyCN 镜像行"
return 0
fi
echo "FAIL omarchy-repo: [omarchy] 缺 OmarchyCN 镜像行(omarchycn doctor mirror --fix 可修复)"
failures=$((failures + 1))
}
check_dev_mirror() { check_dev_mirror() {
omarchy-cn-dev-mirror-doctor || failures=$((failures + 1)) omarchy-cn-dev-mirror-doctor || failures=$((failures + 1))
} }
@@ -79,12 +100,16 @@ check_ime() {
case "$module" in case "$module" in
network) check_network ;; network) check_network ;;
mirror) check_mirror ;; mirror)
check_mirror
check_omarchy_repo
;;
dev-mirror) check_dev_mirror ;; dev-mirror) check_dev_mirror ;;
ime) check_ime ;; ime) check_ime ;;
all) all)
check_network check_network
check_mirror check_mirror
check_omarchy_repo
check_dev_mirror check_dev_mirror
check_ime check_ime
;; ;;
+23
View File
@@ -0,0 +1,23 @@
#!/bin/bash
# omarchy:summary=Install Kimi Code with the official installer script
# omarchy:examples=omarchycn kimi install
set -euo pipefail
if omarchy-cmd-present kimi; then
echo "Kimi Code 已安装"
exit 0
fi
installer=$(mktemp)
trap 'rm -f "$installer"' EXIT
curl -fsSL https://code.kimi.com/kimi-code/install.sh -o "$installer"
bash "$installer"
# The official installer only touches .bashrc PATH; expose kimi now
if [[ ! -x $HOME/.kimi-code/bin/kimi ]]; then
echo "kimi binary missing after the official installer" >&2
exit 1
fi
mkdir -p "$HOME/.local/bin"
ln -sf "$HOME/.kimi-code/bin/kimi" "$HOME/.local/bin/kimi"
+29 -12
View File
@@ -1,8 +1,8 @@
#!/bin/bash #!/bin/bash
# omarchy:summary=Set and launch the default coding agent # omarchy:summary=Set and launch the default coding agent
# omarchy:args=[pi|omp|opencode|ori|claude|codex|grok|agy|copilot|crush] # omarchy:args=[pi|omp|opencode|ori|claude|codex|grok|agy|copilot|crush|kimi|deepcode|dim|dsh]
# omarchy:examples=omarchy default agent | omarchy default agent codex | omarchy default agent claude # omarchy:examples=omarchy default agent | omarchy default agent codex | omarchy default agent kimi
installing=false installing=false
if [[ ${1:-} == "--install" ]]; then if [[ ${1:-} == "--install" ]]; then
@@ -34,25 +34,42 @@ crush) agent="crush"; name="Crush" ;;
grok) agent="grok"; name="Grok"; agent_package="npm:@xai-official/grok" ;; grok) agent="grok"; name="Grok"; agent_package="npm:@xai-official/grok" ;;
agy | antigravity | antigravity-cli | gemini | gemini-cli) agent="agy"; name="Antigravity"; agent_package="antigravity-cli" ;; agy | antigravity | antigravity-cli | gemini | gemini-cli) agent="agy"; name="Antigravity"; agent_package="antigravity-cli" ;;
copilot | github-copilot) agent="copilot"; name="GitHub Copilot" ;; copilot | github-copilot) agent="copilot"; name="GitHub Copilot" ;;
kimi | kimi-code) agent="kimi"; name="Kimi Code" ;;
deepcode | deep-code) agent="deepcode"; name="Deep Code"; agent_package="npm:@vegamo/deepcode-cli" ;;
dim | dimcode | dim-agent) agent="dim"; name="Dim Agent"; agent_package="npm:dimcode" ;;
dsh | deepseek-harness) agent="dsh"; name="DSH"; agent_package="npm:@deepseek-ai/dsh" ;;
*) *)
echo "Usage: omarchy-default-agent <pi|omp|opencode|ori|claude|codex|grok|agy|copilot|crush>" echo "Usage: omarchy-default-agent <pi|omp|opencode|ori|claude|codex|grok|agy|copilot|crush|kimi|deepcode|dim|dsh>"
exit 1 exit 1
;; ;;
esac esac
agent_package=${agent_package:-$agent} agent_package=${agent_package:-$agent}
if [[ $installing == "false" ]] && ! mise where "$agent_package" &>/dev/null; then # Kimi Code installs via its official script, not mise
exec omarchy-launch-floating-terminal-with-presentation omarchy-default-agent --install "$agent" if [[ $agent == "kimi" ]]; then
fi if omarchy-cmd-missing kimi; then
if [[ $installing == "false" ]]; then
exec omarchy-launch-floating-terminal-with-presentation omarchy-default-agent --install kimi
fi
if ! omarchy-cn-kimi-install; then
echo "Could not install $name with the official installer" >&2
exit 1
fi
fi
else
if [[ $installing == "false" ]] && ! mise where "$agent_package" &>/dev/null; then
exec omarchy-launch-floating-terminal-with-presentation omarchy-default-agent --install "$agent"
fi
if ! mise use -g "$agent_package"; then if ! mise use -g "$agent_package"; then
if [[ $installing == "true" ]]; then if [[ $installing == "true" ]]; then
echo "Could not install $name with mise" >&2 echo "Could not install $name with mise" >&2
else else
echo "Could not set $name as the default coding agent" >&2 echo "Could not set $name as the default coding agent" >&2
fi
exit 1
fi fi
exit 1
fi fi
mkdir -p "$(dirname "$agent_file")" mkdir -p "$(dirname "$agent_file")"
-3
View File
@@ -12,13 +12,10 @@ if gum confirm "Are you sure you want to restore all preinstalled web apps, TUI
# Mirrors the list in omarchy-remove-preinstalls; both track omarchy-base.packages # Mirrors the list in omarchy-remove-preinstalls; both track omarchy-base.packages
if ! omarchy-pkg-add \ if ! omarchy-pkg-add \
aether \
cliamp \ cliamp \
libreoffice-fresh \
xournalpp \ xournalpp \
pinta \ pinta \
obsidian \ obsidian \
obs-studio \
kdenlive \ kdenlive \
moonlight-qt \ moonlight-qt \
lazydocker \ lazydocker \
+47 -47
View File
@@ -338,10 +338,10 @@ static_bindings() {
# for interchangeably belong on one row. # for interchangeably belong on one row.
alternative_chord_actions() { alternative_chord_actions() {
cat <<'ACTIONS' cat <<'ACTIONS'
Close window 关闭窗口
Calculator 计算器
Toggle scratchpad 切换便签区
Move window to scratchpad 窗口移入便签区
ACTIONS ACTIONS
} }
@@ -442,58 +442,58 @@ prioritize_entries() {
sub(/ \/ [^→]*→/, " →", line) sub(/ \/ [^→]*→/, " →", line)
prio = 50 prio = 50
if (match(line, /Keybindings/)) prio = 0 if (match(line, /快捷键/)) prio = 0
if (match(line, /Omarchy menu/)) prio = 1 if (match(line, /Omarchy 菜单/)) prio = 1
if (match(line, /Terminal/)) prio = 2 if (match(line, /终端/)) prio = 2
if (match(line, /Browser/) && !match(line, /Browser[[:space:]]*\(/) && !match(line, /SUPER SHIFT.*\+.*B.*→.*Browser/)) prio = 3 if (match(line, /浏览器/) && !match(line, /浏览器(/) && !match(line, /SUPER SHIFT.*\+.*B.*→.*浏览器/)) prio = 3
if (match(line, /File manager/) && !match(line, /File manager \(cwd\)/)) prio = 4 if (match(line, /文件管理器/) && !match(line, /文件管理器(当前目录)/)) prio = 4
if (match(line, /Launch apps/)) prio = 5 if (match(line, /Launch apps/)) prio = 5
if (match(line, /System menu/)) prio = 6 if (match(line, /系统菜单/)) prio = 6
if (match(line, /Theme menu/)) prio = 7 if (match(line, /主题菜单/)) prio = 7
if (match(line, /Full screen/)) prio = 8 if (match(line, /全屏/)) prio = 8
if (match(line, /Full width/)) prio = 9 if (match(line, /全宽/)) prio = 9
if (match(line, /Close window/)) prio = 10 if (match(line, /关闭窗口/)) prio = 10
if (match(line, /Close all windows/)) prio = 11 if (match(line, /关闭所有窗口/)) prio = 11
if (match(line, /Lock system/)) prio = 12 if (match(line, /锁定系统/)) prio = 12
if (match(line, /Toggle window floating/)) prio = 13 if (match(line, /切换窗口浮动/)) prio = 13
if (match(line, /Toggle window split/)) prio = 14 if (match(line, /切换窗口分割/)) prio = 14
if (match(line, /Pop window/)) prio = 15 if (match(line, /弹出窗口/)) prio = 15
if (match(line, /Universal/)) prio = 16 if (match(line, /通用/)) prio = 16
if (match(line, /Clipboard/)) prio = 17 if (match(line, /剪贴板/)) prio = 17
if (match(line, /Audio controls/)) prio = 18 if (match(line, /Audio controls/)) prio = 18
if (match(line, /Bluetooth controls/)) prio = 19 if (match(line, /Bluetooth controls/)) prio = 19
if (match(line, /Wifi controls/)) prio = 20 if (match(line, /Wifi controls/)) prio = 20
if (match(line, /Emojis/)) prio = 21 if (match(line, /表情/)) prio = 21
if (match(line, /Color picker/)) prio = 22 if (match(line, /取色器/)) prio = 22
if (match(line, /Screenshot/)) prio = 23 if (match(line, /截图/)) prio = 23
if (match(line, /Screenrecording/)) prio = 24 if (match(line, /录屏/)) prio = 24
if (match(line, /Tmux/)) prio = 25 if (match(line, /Tmux/)) prio = 25
if (match(line, /Herdr/)) prio = 26 if (match(line, /Herdr/)) prio = 26
if (match(line, /SUPER SHIFT.*\+.*B.*→.*Browser/)) prio = 27 if (match(line, /SUPER SHIFT.*\+.*B.*→.*浏览器/)) prio = 27
if (match(line, /File manager \(cwd\)/)) prio = 28 if (match(line, /文件管理器(当前目录)/)) prio = 28
if (match(line, /(Switch|Next|Former|Previous).*workspace/)) prio = 29 if (match(line, /(切换到|下一|上一|上次)工作区/)) prio = 29
if (match(line, /Move window to workspace/)) prio = 30 if (match(line, /窗口移到工作区/)) prio = 30
if (match(line, /Move window silently to workspace/)) prio = 31 if (match(line, /窗口静默移到工作区/)) prio = 31
if (match(line, /Swap window/)) prio = 32 if (match(line, /互换/)) prio = 32
if (match(line, /Focus/)) prio = 33 if (match(line, /聚焦/)) prio = 33
if (match(line, /Move window$/)) prio = 34 if (match(line, /移动窗口$/)) prio = 34
if (match(line, /Resize window/)) prio = 35 if (match(line, /调整窗口大小/)) prio = 35
if (match(line, /Expand window/)) prio = 36 if (match(line, /扩展窗口/)) prio = 36
if (match(line, /Shrink window/)) prio = 37 if (match(line, /收缩窗口/)) prio = 37
if (match(line, /scratchpad/)) prio = 38 if (match(line, /便签区/)) prio = 38
if (match(line, /notification/)) prio = 39 if (match(line, /通知/)) prio = 39
if (match(line, /Toggle window transparency/)) prio = 40 if (match(line, /切换窗口透明/)) prio = 40
if (match(line, /Toggle workspace gaps/)) prio = 41 if (match(line, /切换窗口间距/)) prio = 41
if (match(line, /Toggle nightlight/)) prio = 42 if (match(line, /切换夜间模式/)) prio = 42
if (match(line, /Toggle locking/)) prio = 43 if (match(line, /切换空闲锁定/)) prio = 43
if (match(line, /group/)) prio = 94 if (match(line, /组内|分组/)) prio = 94
if (match(line, /Scroll active workspace/)) prio = 95 if (match(line, /工作区向(前|后)滚动/)) prio = 95
if (match(line, /Cycle to/)) prio = 96 if (match(line, /Cycle to/)) prio = 96
if (match(line, /Reveal active/)) prio = 97 if (match(line, /置顶显示/)) prio = 97
if (match(line, /Apple Display/)) prio = 98 if (match(line, /Apple Display/)) prio = 98
if (match(line, /XF86/)) prio = 99 if (match(line, /XF86/)) prio = 99
if (match(line, /Tmux keybindings/)) prio = 100 if (match(line, /Tmux 快捷键/)) prio = 100
if (match(line, /Herdr keybindings/)) prio = 101 if (match(line, /Herdr 快捷键/)) prio = 101
# print "priority<TAB>record" # print "priority<TAB>record"
printf "%d\t%s\n", prio, $0 printf "%d\t%s\n", prio, $0
+1 -1
View File
@@ -186,7 +186,7 @@ tips=(
"Share files with phones and laptops using LocalSend" "Share files with phones and laptops using LocalSend"
"Turn any website into an app with Install > Web App in the menu" "Turn any website into an app with Install > Web App in the menu"
"Super + Return opens a terminal, Super + Shift + Return the browser" "Super + Return opens a terminal, Super + Shift + Return the browser"
"Edit images with Pinta, videos with Kdenlive, docs with LibreOffice" "Edit images with Pinta and videos with Kdenlive"
"Super + Ctrl + Print grabs text off the screen with OCR" "Super + Ctrl + Print grabs text off the screen with OCR"
"Print takes a screenshot, Alt + Print records the screen" "Print takes a screenshot, Alt + Print records the screen"
"Set a reminder with Super + Ctrl + R" "Set a reminder with Super + Ctrl + R"
+1 -2
View File
@@ -11,7 +11,7 @@ Usage: omarchy finalize user [--force] [--first-install]
Runs the per-user setup steps that /etc/skel can't seed: Runs the per-user setup steps that /etc/skel can't seed:
dev-aware skill symlinks, xdg-user-dirs + gtk bookmarks (need \$HOME), dev-aware skill symlinks, xdg-user-dirs + gtk bookmarks (need \$HOME),
default browser/mailto, and install/user/all.sh. default browser, and install/user/all.sh.
For shipped configs see /etc/skel (new users) and omarchy-reinstall-configs For shipped configs see /etc/skel (new users) and omarchy-reinstall-configs
(existing users explicitly resyncing). (existing users explicitly resyncing).
@@ -110,7 +110,6 @@ source "$OMARCHY_INSTALL/user/all.sh"
omarchy-refresh-applications omarchy-refresh-applications
env -u BROWSER xdg-settings set default-web-browser chromium.desktop env -u BROWSER xdg-settings set default-web-browser chromium.desktop
xdg-mime default HEY.desktop x-scheme-handler/mailto
if (( first_install )); then if (( first_install )); then
mkdir -p "$state_dir/migrations" mkdir -p "$state_dir/migrations"
-3
View File
@@ -18,13 +18,10 @@ if gum confirm "Are you sure you want to remove all preinstalled web apps, TUI w
~/.local/bin/omp ~/.local/bin/ori ~/.local/bin/grok ~/.local/bin/crush ~/.local/bin/ghui ~/.local/bin/hunk ~/.local/bin/omp ~/.local/bin/ori ~/.local/bin/grok ~/.local/bin/crush ~/.local/bin/ghui ~/.local/bin/hunk
omarchy-pkg-drop \ omarchy-pkg-drop \
aether \
cliamp \ cliamp \
libreoffice-fresh \
xournalpp \ xournalpp \
pinta \ pinta \
obsidian \ obsidian \
obs-studio \
kdenlive \ kdenlive \
moonlight-qt \ moonlight-qt \
lazydocker \ lazydocker \
+6 -6
View File
@@ -3,16 +3,16 @@
# omarchy:summary=Prompt for confirmation before starting an update # omarchy:summary=Prompt for confirmation before starting an update
gum style --border normal --padding "1 2" \ gum style --border normal --padding "1 2" \
"Ready to update?" \ "准备好更新了吗?" \
"" \ "" \
"• You cannot stop the update once you start!" \ "• 更新一旦开始就不能中止!" \
"• Make sure you're connected to power or have a full battery" \ "• 请确保已接通电源或电量充足" \
"" \ "" \
"What's new: https://github.com/basecamp/omarchy/releases/latest" "更新内容: https://git.zacharyzhang.com/ZacharyZhang-NY/omarchycn/releases"
echo echo
if ! gum confirm "Continue with update?"; then if ! gum confirm "继续更新?"; then
echo "Update cancelled" echo "已取消更新"
exit 1 exit 1
fi fi
-4
View File
@@ -2196,10 +2196,6 @@ fi
if command -v xdg-settings >/dev/null 2>&1; then if command -v xdg-settings >/dev/null 2>&1; then
env -u BROWSER xdg-settings set default-web-browser chromium.desktop || true env -u BROWSER xdg-settings set default-web-browser chromium.desktop || true
fi fi
if command -v xdg-mime >/dev/null 2>&1; then
xdg-mime default HEY.desktop x-scheme-handler/mailto || true
fi
# This script is fetched from the branch and runs against whatever packaged # This script is fetched from the branch and runs against whatever packaged
# tree the channel currently serves, so the packaged tree can be older than the # tree the channel currently serves, so the packaged tree can be older than the
# script. The completion markers are written directly rather than through # script. The completion markers are written directly rather than through
-15
View File
@@ -1,15 +0,0 @@
#!/bin/bash
# omarchy:summary=Open HEY webmail and translate mailto links
# omarchy:args=[url]
url="$1"
web_url="https://app.hey.com"
# Handle mailto: URLs
if [[ $url =~ ^mailto: ]]; then
email=$(echo "$url" | sed 's/mailto://')
web_url="https://app.hey.com/messages/new?to=$email"
fi
exec omarchy-launch-webapp "$web_url"
+17 -1
View File
@@ -31,6 +31,21 @@ cn_ai_harness_field() {
jq -re --arg h "$1" --arg f "$2" '.harnesses[$h][$f]' "$CN_AI_HARNESSES" jq -re --arg h "$1" --arg f "$2" '.harnesses[$h][$f]' "$CN_AI_HARNESSES"
} }
# Providers with a fixed token (local servers) need no stored secret.
# `// empty` keeps stdout clean when absent (bare -re would print "null").
cn_ai_static_token() {
jq -re --arg p "$1" '.providers[$p].static_token // empty' "$CN_AI_PROVIDERS"
}
cn_ai_resolve_key() {
cn_ai_static_token "$1" 2>/dev/null || omarchy-cn-ai-secret get "$1"
}
# Dynamic-model providers list models at runtime, not in the registry
cn_ai_models_dynamic() {
jq -e --arg p "$1" '.providers[$p].models_dynamic == true' "$CN_AI_PROVIDERS" > /dev/null
}
cn_ai_combo_level() { cn_ai_combo_level() {
jq -r --arg h "$1" --arg p "$2" '.combos[$h][$p].level // "unsupported"' "$CN_AI_COMPAT" jq -r --arg h "$1" --arg p "$2" '.combos[$h][$p].level // "unsupported"' "$CN_AI_COMPAT"
} }
@@ -68,7 +83,8 @@ cn_ai_render_env() {
case "$harness" in case "$harness" in
claude-code) claude-code)
base=$(cn_ai_endpoint "$provider" anthropic) base=$(cn_ai_endpoint "$provider" anthropic)
fast=$(cn_ai_fast_model "$provider") # Dynamic-model providers have no fast alias: every tier maps to the model
fast=$(cn_ai_fast_model "$provider" 2>/dev/null || printf '%s' "$model")
printf 'export ANTHROPIC_BASE_URL=%q\n' "$base" printf 'export ANTHROPIC_BASE_URL=%q\n' "$base"
# Docs vary between AUTH_TOKEN (deepseek/zai) and API_KEY (kimi): set both # Docs vary between AUTH_TOKEN (deepseek/zai) and API_KEY (kimi): set both
printf 'export ANTHROPIC_AUTH_TOKEN=%q\n' "$key" printf 'export ANTHROPIC_AUTH_TOKEN=%q\n' "$key"
+13
View File
@@ -4,6 +4,19 @@
CN_MIRRORS_JSON="$OMARCHY_PATH/cn/mirrors.json" CN_MIRRORS_JSON="$OMARCHY_PATH/cn/mirrors.json"
CN_MIRRORLIST="/etc/pacman.d/mirrorlist" CN_MIRRORLIST="/etc/pacman.d/mirrorlist"
CN_PROFILE_FILE="$HOME/.config/omarchycn/mirror-profile" CN_PROFILE_FILE="$HOME/.config/omarchycn/mirror-profile"
CN_OMARCHY_MIRROR="https://git.zacharyzhang.com/api/packages/ZacharyZhang-NY/arch/omarchy/x86_64"
# [omarchy] mirror line management (stable channel only); shared by the
# rollout migration and doctor --fix so refresh-pacman resets stay healable
cn_mirror_omarchy_repo_ok() {
grep -qxF "Server = $CN_OMARCHY_MIRROR" "${OMARCHYCN_PACMAN_CONF:-/etc/pacman.conf}"
}
cn_mirror_omarchy_repo_fix() {
local conf="${OMARCHYCN_PACMAN_CONF:-/etc/pacman.conf}"
cn_mirror_omarchy_repo_ok && return 0
sudo sed -i "s|^Server = https://pkgs.omarchy.org/stable/|Server = $CN_OMARCHY_MIRROR\nServer = https://pkgs.omarchy.org/stable/|" "$conf"
}
cn_mirror_ids() { cn_mirror_ids() {
jq -r '.mirrors[].id' "$CN_MIRRORS_JSON" jq -r '.mirrors[].id' "$CN_MIRRORS_JSON"
+8
View File
@@ -0,0 +1,8 @@
echo "Trust the OmarchyCN registry key and put the [omarchy] mirror first"
sudo pacman-key --add "$OMARCHY_PATH/cn/keys/omarchycn-registry.asc"
sudo pacman-key --lsign-key 74DCF57ACD812B24D959F146BD386048867B33B4
# Only the stable channel is mirrored; edge/rc systems keep upstream directly
source "$OMARCHY_PATH/cn/lib/mirror.sh"
cn_mirror_omarchy_repo_fix
+11 -1
View File
@@ -1,5 +1,5 @@
{ {
"_verified": "2026-08-24. level=stable: adapter 渲染由 test/shell.d/omarchycn-ai-test.sh mock 回归覆盖; level=official-doc: 官方集成文档存在,native CLI 自管配置", "_verified": "2026-08-25. level=stable: adapter 渲染由 test/shell.d/omarchycn-ai-test.sh mock 回归覆盖; level=official-doc: 官方集成文档存在,native CLI 自管配置",
"combos": { "combos": {
"claude-code": { "claude-code": {
"deepseek": { "deepseek": {
@@ -16,6 +16,16 @@
"level": "stable", "level": "stable",
"doc": "https://docs.z.ai/devpack/tool/claude", "doc": "https://docs.z.ai/devpack/tool/claude",
"adapter": true "adapter": true
},
"minimax": {
"level": "stable",
"doc": "https://platform.minimax.io/docs/token-plan/claude-code",
"adapter": true
},
"ollama": {
"level": "stable",
"doc": "https://docs.ollama.com/api/anthropic-compatibility",
"adapter": true
} }
}, },
"codex": { "codex": {
+2 -2
View File
@@ -1,5 +1,5 @@
{ {
"_verified": "2026-08-24", "_verified": "2026-08-25",
"harnesses": { "harnesses": {
"claude-code": { "claude-code": {
"display_name": "Claude Code", "display_name": "Claude Code",
@@ -25,7 +25,7 @@
"kimi-code": { "kimi-code": {
"display_name": "Kimi Code CLI", "display_name": "Kimi Code CLI",
"command": "kimi", "command": "kimi",
"install": "doc:https://www.kimi.com/code/docs/en/", "install": "omarchy-cn-kimi-install",
"config_method": "native", "config_method": "native",
"protocol": "native" "protocol": "native"
}, },
+130 -12
View File
@@ -1,44 +1,162 @@
{ {
"_verified": "2026-08-24, from official docs (see OmarchyCN PRD §27)", "_verified": "2026-08-27, from official docs (see OmarchyCN PRD §27; minimax: platform.minimax.io/docs/token-plan/claude-code; ollama: docs.ollama.com/api/anthropic-compatibility, fixed token \"ollama\", models are whatever is pulled locally)",
"providers": { "providers": {
"deepseek": { "deepseek": {
"display_name": "DeepSeek", "display_name": "DeepSeek",
"auth": ["api_key"], "auth": [
"api_key"
],
"key_url": "https://platform.deepseek.com/api_keys", "key_url": "https://platform.deepseek.com/api_keys",
"endpoints": { "endpoints": {
"anthropic": "https://api.deepseek.com/anthropic", "anthropic": "https://api.deepseek.com/anthropic",
"openai": "https://api.deepseek.com" "openai": "https://api.deepseek.com"
}, },
"models": [ "models": [
{ "id": "deepseek-v4-pro[1m]", "aliases": ["default-coding"], "capabilities": ["tools", "streaming", "reasoning"] }, {
{ "id": "deepseek-v4-flash", "aliases": ["fast"], "capabilities": ["tools", "streaming"] } "id": "deepseek-v4-pro[1m]",
"aliases": [
"default-coding"
],
"capabilities": [
"tools",
"streaming",
"reasoning"
]
},
{
"id": "deepseek-v4-flash",
"aliases": [
"fast"
],
"capabilities": [
"tools",
"streaming"
]
}
] ]
}, },
"kimi": { "kimi": {
"display_name": "Kimi (Moonshot)", "display_name": "Kimi (Moonshot)",
"auth": ["api_key"], "auth": [
"api_key"
],
"key_url": "https://www.kimi.com/code", "key_url": "https://www.kimi.com/code",
"endpoints": { "endpoints": {
"anthropic": "https://api.kimi.com/coding/", "anthropic": "https://api.kimi.com/coding/",
"openai": "https://api.moonshot.cn/v1" "openai": "https://api.moonshot.cn/v1"
}, },
"models": [ "models": [
{ "id": "kimi-for-coding", "aliases": ["default-coding"], "capabilities": ["tools", "streaming", "reasoning"] }, {
{ "id": "kimi-for-coding-highspeed", "aliases": ["fast"], "capabilities": ["tools", "streaming"] }, "id": "kimi-for-coding",
{ "id": "kimi-k2.6", "aliases": ["general"], "capabilities": ["tools", "streaming"], "protocol": "openai" } "aliases": [
"default-coding"
],
"capabilities": [
"tools",
"streaming",
"reasoning"
]
},
{
"id": "kimi-for-coding-highspeed",
"aliases": [
"fast"
],
"capabilities": [
"tools",
"streaming"
]
},
{
"id": "kimi-k2.6",
"aliases": [
"general"
],
"capabilities": [
"tools",
"streaming"
],
"protocol": "openai"
}
] ]
}, },
"zai": { "zai": {
"display_name": "Z.AI / GLM", "display_name": "Z.AI / GLM",
"auth": ["api_key"], "auth": [
"api_key"
],
"key_url": "https://z.ai/manage-apikey/apikey-list", "key_url": "https://z.ai/manage-apikey/apikey-list",
"endpoints": { "endpoints": {
"anthropic": "https://api.z.ai/api/anthropic" "anthropic": "https://api.z.ai/api/anthropic"
}, },
"models": [ "models": [
{ "id": "glm-5.2[1m]", "aliases": ["default-coding"], "capabilities": ["tools", "streaming", "reasoning"] }, {
{ "id": "GLM-5.3", "aliases": ["latest"], "capabilities": ["tools", "streaming", "reasoning"] }, "id": "glm-5.2[1m]",
{ "id": "GLM-4.7", "aliases": ["fast"], "capabilities": ["tools", "streaming"] } "aliases": [
"default-coding"
],
"capabilities": [
"tools",
"streaming",
"reasoning"
]
},
{
"id": "GLM-5.3",
"aliases": [
"latest"
],
"capabilities": [
"tools",
"streaming",
"reasoning"
]
},
{
"id": "GLM-4.7",
"aliases": [
"fast"
],
"capabilities": [
"tools",
"streaming"
]
}
]
},
"ollama": {
"display_name": "Ollama 本地",
"auth": [
"none"
],
"static_token": "ollama",
"endpoints": {
"anthropic": "http://localhost:11434"
},
"models": [],
"models_dynamic": true
},
"minimax": {
"display_name": "MiniMax",
"auth": [
"api_key"
],
"key_url": "https://platform.minimaxi.com/user-center/payment/token-plan",
"endpoints": {
"anthropic": "https://api.minimaxi.com/anthropic"
},
"models": [
{
"id": "MiniMax-M3[1m]",
"aliases": [
"default-coding"
],
"capabilities": [
"tools",
"streaming",
"reasoning"
]
}
] ]
} }
} }
+1 -1
View File
@@ -1 +1 @@
3 6
+1 -1
View File
@@ -2,4 +2,4 @@
--ozone-platform-hint=wayland --ozone-platform-hint=wayland
--password-store=gnome-libsecret --password-store=gnome-libsecret
--enable-features=TouchpadOverscrollHistoryNavigation --enable-features=TouchpadOverscrollHistoryNavigation
--load-extension=/usr/share/omarchy/default/chromium/extensions/copy-url,/usr/share/omarchy/default/chromium/extensions/yt-dlp,/usr/share/omarchy/default/chromium/extensions/whatsapp-slim --load-extension=/usr/share/omarchy/default/chromium/extensions/copy-url,/usr/share/omarchy/default/chromium/extensions/yt-dlp
-1
View File
@@ -12,7 +12,6 @@ application/pdf=org.gnome.Evince.desktop
x-scheme-handler/http=chromium.desktop x-scheme-handler/http=chromium.desktop
x-scheme-handler/https=chromium.desktop x-scheme-handler/https=chromium.desktop
x-scheme-handler/mailto=HEY.desktop
video/mp4=mpv.desktop video/mp4=mpv.desktop
video/x-msvideo=mpv.desktop video/x-msvideo=mpv.desktop
@@ -1,21 +0,0 @@
{
"manifest_version": 3,
"name": "WhatsApp Slim",
"version": "1.1",
"key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAszLhFYxjvKqx1VAORt3M6b0H1Kz03cmQ1MrUjJZ8gj3nhRcvufk6PS17yUIjEdKKmuj+1HuFVwOaHJQsACGJXwn2TeKQqZmZx/83yd7ydgabHXTsJbhy5O+Yunv+VA1B2IX/phcXpkH9bPv2PuC/bQ13nmmAvT2b+EMyq8EPQHOoSWhE4M4kIhLDczTmxfJX5X3tTxH66952DYuQWvGpIXLAUXkvIgap0qemW68/LymPaWzcg6g3oE/nZ7C0j7JE5bnqLFxqXNlA9Jt+Ss/1Y33QL3OSD9EEsrpgueS0bbqtkmFQ9/jGlruIL+qj0xe+CAtqbJ5ty9H/sqi01kjfyQIDAQAB",
"description": "Make WhatsApp Web follow the system theme and collapse its chat list in narrow windows, this extension is installed by Omarchy",
"content_scripts": [
{
"matches": [
"https://web.whatsapp.com/*"
],
"css": [
"whatsapp.css"
],
"js": [
"system-theme.js"
],
"run_at": "document_start"
}
]
}
@@ -1,4 +0,0 @@
if (localStorage.getItem("system-theme-mode") !== "true") {
localStorage.setItem("system-theme-mode", "true");
location.reload();
}
@@ -1,64 +0,0 @@
/* Collapse WhatsApp Web's chat list to a Signal-style avatar rail when the
* window is too narrow to show both the full list and the conversation.
* Leans on WhatsApp's stable structural ids (#side, #main, #pane-side) and
* data-testid hooks rather than its obfuscated, frequently-churning class
* names. */
@media (max-width: 1100px) {
/* The chat-list column (title header + #side) becomes an avatar rail */
div:has(> div#side) {
flex: 0 0 90px !important;
min-width: 90px !important;
max-width: 90px !important;
}
/* Chat-list title bar, search, filter chips, and banner don't fit.
* Scoped to the column wrapper: the left icon nav rail confusingly
* shares the same chatlist-header testid and must survive. */
div:has(> div#side) > header,
#side > div:first-child,
#side [role="tablist"],
#side span[data-testid="chat-butterbar"] {
display: none !important;
}
/* The rail doesn't need a visible scrollbar, and horizontal overflow
* from the collapsed rows must not wiggle */
#pane-side {
overflow-x: hidden !important;
scrollbar-width: none !important;
}
/* Chat rows: keep the avatar column, collapse the text/preview columns
* without display:none so the unread badge can be resurrected */
[data-testid="cell-frame-container"] {
position: relative !important;
}
[data-testid="cell-frame-container"] > div:not(:first-child) {
visibility: hidden !important;
width: 0 !important;
min-width: 0 !important;
overflow: hidden !important;
}
/* Float the unread badge over the avatar's top-right corner */
[data-testid="cell-frame-container"] span[aria-label*="unread"] {
visibility: visible !important;
position: absolute !important;
top: 2px !important;
left: 50px !important;
}
/* The empty drawer overlay keeps the stock chat-list width, which
* strands its divider border in the middle of the conversation */
[data-testid="drawer-middle"] {
border-left: none !important;
}
/* Let the app shrink below WhatsApp's default minimum width */
#app,
#app .two {
min-width: 0 !important;
}
}
+10 -19
View File
@@ -1,34 +1,25 @@
-- Essential application bindings. -- Essential application bindings.
o.bind("SUPER + RETURN", "Terminal", { omarchy = "terminal" }) o.bind("SUPER + RETURN", "终端", { omarchy = "terminal" })
o.bind("SUPER + SHIFT + RETURN", "Browser", { omarchy = "browser" }) o.bind("SUPER + SHIFT + RETURN", "浏览器", { omarchy = "browser" })
o.bind("SUPER + SHIFT + F", "File manager", { omarchy = "nautilus" }) o.bind("SUPER + SHIFT + F", "文件管理器", { omarchy = "nautilus" })
o.bind("SUPER + ALT + SHIFT + F", "File manager (cwd)", { omarchy = "nautilus-cwd" }) o.bind("SUPER + ALT + SHIFT + F", "文件管理器(当前目录)", { omarchy = "nautilus-cwd" })
o.bind("SUPER + SHIFT + B", "Browser", { omarchy = "browser" }) o.bind("SUPER + SHIFT + B", "浏览器", { omarchy = "browser" })
o.bind("SUPER + SHIFT + ALT + B", "Browser (private)", { omarchy = "browser --private" }) o.bind("SUPER + SHIFT + ALT + B", "浏览器(无痕)", { omarchy = "browser --private" })
o.bind("SUPER + SHIFT + N", "Editor", { omarchy = "editor" }) o.bind("SUPER + SHIFT + N", "编辑器", { omarchy = "editor" })
if o.preinstalled_bindings_enabled() then if o.preinstalled_bindings_enabled() then
-- Bindings for preinstalled Omarchy applications, TUIs, and web apps. -- Bindings for preinstalled Omarchy applications, TUIs, and web apps.
o.bind("SUPER + ALT + RETURN", "Tmux", { omarchy = "terminal-tmux" }) o.bind("SUPER + ALT + RETURN", "Tmux", { omarchy = "terminal-tmux" })
o.bind("SUPER + CTRL + RETURN", "Herdr", { omarchy = "terminal-herdr" }) o.bind("SUPER + CTRL + RETURN", "Herdr", { omarchy = "terminal-herdr" })
o.bind("SUPER + SHIFT + M", "Music", { omarchy = "spotify" }) o.bind("SUPER + SHIFT + M", "音乐", { omarchy = "spotify" })
o.bind("SUPER + SHIFT + ALT + M", "Music TUI", { tui = "cliamp", focus = true }) o.bind("SUPER + SHIFT + ALT + M", "音乐 TUI", { tui = "cliamp", focus = true })
o.bind("SUPER + SHIFT + D", "Docker", { tui = "omarchy-launch-docker-tui" }) o.bind("SUPER + SHIFT + D", "Docker", { tui = "omarchy-launch-docker-tui" })
o.bind("SUPER + SHIFT + G", "Signal", { omarchy = "signal" }) o.bind("SUPER + SHIFT + G", "Signal", { omarchy = "signal" })
o.bind("SUPER + SHIFT + O", "Obsidian", { launch = "obsidian", focus = "^obsidian$" }) o.bind("SUPER + SHIFT + O", "Obsidian", { launch = "obsidian", focus = "^obsidian$" })
o.bind("SUPER + SHIFT + W", "Omawrite", { launch = "omawrite" }) o.bind("SUPER + SHIFT + W", "Omawrite", { launch = "omawrite" })
o.bind("SUPER + SHIFT + SLASH", "Passwords", { omarchy = "1password" }) o.bind("SUPER + SHIFT + SLASH", "密码管理", { omarchy = "1password" })
o.bind("SUPER + SHIFT + A", "ChatGPT", { webapp = "https://chatgpt.com" }) o.bind("SUPER + SHIFT + A", "ChatGPT", { webapp = "https://chatgpt.com" })
o.bind("SUPER + SHIFT + ALT + A", "Grok", { webapp = "https://grok.com" }) o.bind("SUPER + SHIFT + ALT + A", "Grok", { webapp = "https://grok.com" })
o.bind("SUPER + SHIFT + C", "Calendar", { webapp = "https://app.hey.com/calendar/weeks/" })
o.bind("SUPER + SHIFT + E", "Email", { webapp = "https://app.hey.com" })
o.bind("SUPER + SHIFT + ALT + E", "New email", { webapp = "https://app.hey.com/messages/new?display=standalone&new_window=true" })
o.bind("SUPER + SHIFT + Y", "YouTube", { webapp = "https://youtube.com/" }) o.bind("SUPER + SHIFT + Y", "YouTube", { webapp = "https://youtube.com/" })
o.bind("SUPER + SHIFT + ALT + G", "WhatsApp", { webapp = "https://web.whatsapp.com/", focus = true })
o.bind( "SUPER + SHIFT + CTRL + G", "Google Messages", { webapp = "https://messages.google.com/web/conversations", focus = true })
o.bind("SUPER + SHIFT + P", "Google Photos", { webapp = "https://photos.google.com/", focus = true })
o.bind("SUPER + SHIFT + S", "Google Maps", { webapp = "https://maps.google.com/", focus = true })
o.bind("SUPER + SHIFT + X", "X", { webapp = "https://x.com/" })
o.bind("SUPER + SHIFT + ALT + X", "X Post", { webapp = "https://x.com/compose/post" })
end end
+4 -4
View File
@@ -42,7 +42,7 @@ local function universal_clipboard_shortcut(default_mods, default_key, terminal_
end end
end end
o.bind("SUPER + C", "Universal copy", universal_clipboard_shortcut("CTRL", "C", "CTRL", "Insert")) o.bind("SUPER + C", "通用复制", universal_clipboard_shortcut("CTRL", "C", "CTRL", "Insert"))
o.bind("SUPER + V", "Universal paste", universal_clipboard_shortcut("CTRL", "V", "SHIFT", "Insert")) o.bind("SUPER + V", "通用粘贴", universal_clipboard_shortcut("CTRL", "V", "SHIFT", "Insert"))
o.bind("SUPER + X", "Universal cut", send_shortcut_once("CTRL", "X")) o.bind("SUPER + X", "通用剪切", send_shortcut_once("CTRL", "X"))
o.bind("SUPER + CTRL + V", "Clipboard manager", "omarchy-shell shell toggle omarchy.clipboard") o.bind("SUPER + CTRL + V", "剪贴板管理器", "omarchy-shell shell toggle omarchy.clipboard")
+28 -28
View File
@@ -1,34 +1,34 @@
-- Volume, brightness, keyboard backlight, and touchpad controls. -- Volume, brightness, keyboard backlight, and touchpad controls.
o.bind("XF86AudioRaiseVolume", "Volume up", "omarchy-audio-output-volume raise", { locked = true, repeating = true }) o.bind("XF86AudioRaiseVolume", "提高音量", "omarchy-audio-output-volume raise", { locked = true, repeating = true })
o.bind("XF86AudioLowerVolume", "Volume down", "omarchy-audio-output-volume lower", { locked = true, repeating = true }) o.bind("XF86AudioLowerVolume", "降低音量", "omarchy-audio-output-volume lower", { locked = true, repeating = true })
o.bind("XF86AudioMute", "Mute", "omarchy-audio-output-volume mute-toggle", { locked = true }) o.bind("XF86AudioMute", "静音", "omarchy-audio-output-volume mute-toggle", { locked = true })
o.bind("XF86AudioMicMute", "Mute microphone", "omarchy-audio-input-mute", { locked = true }) o.bind("XF86AudioMicMute", "麦克风静音", "omarchy-audio-input-mute", { locked = true })
o.bind("XF86MonBrightnessUp", "Brightness up", "omarchy-brightness-display +5%", { locked = true, repeating = true }) o.bind("XF86MonBrightnessUp", "提高亮度", "omarchy-brightness-display +5%", { locked = true, repeating = true })
o.bind("XF86MonBrightnessDown", "Brightness down", "omarchy-brightness-display 5%-", { locked = true, repeating = true }) o.bind("XF86MonBrightnessDown", "降低亮度", "omarchy-brightness-display 5%-", { locked = true, repeating = true })
o.bind("SHIFT + XF86MonBrightnessUp", "Brightness maximum", "omarchy-brightness-display 100%", { locked = true, repeating = true }) o.bind("SHIFT + XF86MonBrightnessUp", "最大亮度", "omarchy-brightness-display 100%", { locked = true, repeating = true })
o.bind("SHIFT + XF86MonBrightnessDown", "Brightness minimum", "omarchy-brightness-display 1%", { locked = true, repeating = true }) o.bind("SHIFT + XF86MonBrightnessDown", "最小亮度", "omarchy-brightness-display 1%", { locked = true, repeating = true })
o.bind("XF86KbdBrightnessUp", "Keyboard brightness up", "omarchy-brightness-keyboard up", { locked = true, repeating = true }) o.bind("XF86KbdBrightnessUp", "键盘背光提高", "omarchy-brightness-keyboard up", { locked = true, repeating = true })
o.bind("XF86KbdBrightnessDown", "Keyboard brightness down", "omarchy-brightness-keyboard down", { locked = true, repeating = true }) o.bind("XF86KbdBrightnessDown", "键盘背光降低", "omarchy-brightness-keyboard down", { locked = true, repeating = true })
o.bind("XF86KbdLightOnOff", "Keyboard backlight cycle", "omarchy-brightness-keyboard cycle", { locked = true }) o.bind("XF86KbdLightOnOff", "键盘背光循环", "omarchy-brightness-keyboard cycle", { locked = true })
o.bind_toggle("XF86TouchpadToggle", "Toggle touchpad", "touchpad", { locked = true }) o.bind_toggle("XF86TouchpadToggle", "切换触控板", "touchpad", { locked = true })
o.bind("XF86TouchpadOn", "Enable touchpad", "omarchy-toggle-touchpad on", { locked = true }) o.bind("XF86TouchpadOn", "启用触控板", "omarchy-toggle-touchpad on", { locked = true })
o.bind("XF86TouchpadOff", "Disable touchpad", "omarchy-toggle-touchpad off", { locked = true }) o.bind("XF86TouchpadOff", "禁用触控板", "omarchy-toggle-touchpad off", { locked = true })
-- Precise volume and brightness controls. -- Precise volume and brightness controls.
o.bind("ALT + XF86AudioRaiseVolume", "Volume up precise", "omarchy-audio-output-volume +1", { locked = true, repeating = true }) o.bind("ALT + XF86AudioRaiseVolume", "微调提高音量", "omarchy-audio-output-volume +1", { locked = true, repeating = true })
o.bind("ALT + XF86AudioLowerVolume", "Volume down precise", "omarchy-audio-output-volume -1", { locked = true, repeating = true }) o.bind("ALT + XF86AudioLowerVolume", "微调降低音量", "omarchy-audio-output-volume -1", { locked = true, repeating = true })
o.bind("ALT + XF86MonBrightnessUp", "Brightness up precise", "omarchy-brightness-display +1%", { locked = true, repeating = true }) o.bind("ALT + XF86MonBrightnessUp", "微调提高亮度", "omarchy-brightness-display +1%", { locked = true, repeating = true })
o.bind("ALT + XF86MonBrightnessDown", "Brightness down precise", "omarchy-brightness-display 1%-", { locked = true, repeating = true }) o.bind("ALT + XF86MonBrightnessDown", "微调降低亮度", "omarchy-brightness-display 1%-", { locked = true, repeating = true })
-- Media controls. -- Media controls.
o.bind("XF86AudioNext", "Next track", "omarchy-shell media next", { locked = true }) o.bind("XF86AudioNext", "下一曲", "omarchy-shell media next", { locked = true })
o.bind("ALT + XF86AudioPlay", "Next track", "omarchy-shell media next", { locked = true }) o.bind("ALT + XF86AudioPlay", "下一曲", "omarchy-shell media next", { locked = true })
o.bind("XF86AudioPause", "Pause", "omarchy-shell media playPause", { locked = true }) o.bind("XF86AudioPause", "暂停", "omarchy-shell media playPause", { locked = true })
o.bind("XF86AudioPlay", "Play", "omarchy-shell media playPause", { locked = true }) o.bind("XF86AudioPlay", "播放", "omarchy-shell media playPause", { locked = true })
o.bind("XF86AudioPrev", "Previous track", "omarchy-shell media previous", { locked = true }) o.bind("XF86AudioPrev", "上一曲", "omarchy-shell media previous", { locked = true })
o.bind("ALT + SHIFT + XF86AudioPlay", "Previous track", "omarchy-shell media previous", { locked = true }) o.bind("ALT + SHIFT + XF86AudioPlay", "上一曲", "omarchy-shell media previous", { locked = true })
o.bind("XF86Eject", "Eject media", "eject", { locked = true }) o.bind("XF86Eject", "弹出介质", "eject", { locked = true })
o.bind("SHIFT + XF86AudioMute", "Switch audio output", "omarchy-audio-output-switch", { locked = true }) o.bind("SHIFT + XF86AudioMute", "切换音频输出", "omarchy-audio-output-switch", { locked = true })
o.bind("SHIFT + XF86AudioPause", "Switch media source", "omarchy-audio-source-switch", { locked = true }) o.bind("SHIFT + XF86AudioPause", "切换媒体源", "omarchy-audio-source-switch", { locked = true })
o.bind("SHIFT + XF86AudioPlay", "Switch media source", "omarchy-audio-source-switch", { locked = true }) o.bind("SHIFT + XF86AudioPlay", "切换媒体源", "omarchy-audio-source-switch", { locked = true })
+72 -72
View File
@@ -1,98 +1,98 @@
o.bind("SUPER + W", "Close window", hl.dsp.window.close()) o.bind("SUPER + W", "关闭窗口", hl.dsp.window.close())
o.bind("SUPER + Q", "Close window", hl.dsp.window.close()) o.bind("SUPER + Q", "关闭窗口", hl.dsp.window.close())
o.bind("CTRL + ALT + DELETE", "Close all windows", "omarchy-hyprland-window-close-all") o.bind("CTRL + ALT + DELETE", "关闭所有窗口", "omarchy-hyprland-window-close-all")
o.bind("SUPER + J", "Toggle window split", hl.dsp.layout("togglesplit")) o.bind("SUPER + J", "切换窗口分割", hl.dsp.layout("togglesplit"))
o.bind("SUPER + P", "Pseudo window", hl.dsp.window.pseudo()) o.bind("SUPER + P", "伪平铺窗口", hl.dsp.window.pseudo())
o.bind("SUPER + T", "Toggle window floating/tiling", hl.dsp.window.float({ action = "toggle" })) o.bind("SUPER + T", "切换窗口浮动/平铺", hl.dsp.window.float({ action = "toggle" }))
o.bind("SUPER + F", "Full screen", hl.dsp.window.fullscreen({ mode = "fullscreen" })) o.bind("SUPER + F", "全屏", hl.dsp.window.fullscreen({ mode = "fullscreen" }))
o.bind("SUPER + CTRL + F", "Tiled full screen", "omarchy-hyprland-window-tiled-fullscreen-toggle") o.bind("SUPER + CTRL + F", "平铺全屏", "omarchy-hyprland-window-tiled-fullscreen-toggle")
o.bind("SUPER + ALT + F", "Full width", hl.dsp.window.fullscreen({ mode = "maximized" })) o.bind("SUPER + ALT + F", "全宽", hl.dsp.window.fullscreen({ mode = "maximized" }))
o.bind("SUPER + O", "Pop window out (float & pin)", "omarchy-hyprland-window-pop") o.bind("SUPER + O", "弹出窗口(浮动并置顶)", "omarchy-hyprland-window-pop")
o.bind("SUPER + ALT + Home", "Save window width", "omarchy-hyprland-window-width save") o.bind("SUPER + ALT + Home", "保存窗口宽度", "omarchy-hyprland-window-width save")
o.bind("SUPER + Home", "Restore window width", "omarchy-hyprland-window-width restore") o.bind("SUPER + Home", "恢复窗口宽度", "omarchy-hyprland-window-width restore")
o.bind("SUPER + L", "Toggle workspace layout", "omarchy-hyprland-workspace-layout-toggle") o.bind("SUPER + L", "切换工作区布局", "omarchy-hyprland-workspace-layout-toggle")
o.bind("SUPER + LEFT", "Focus on left window", hl.dsp.focus({ direction = "l" })) o.bind("SUPER + LEFT", "聚焦左侧窗口", hl.dsp.focus({ direction = "l" }))
o.bind("SUPER + RIGHT", "Focus on right window", hl.dsp.focus({ direction = "r" })) o.bind("SUPER + RIGHT", "聚焦右侧窗口", hl.dsp.focus({ direction = "r" }))
o.bind("SUPER + UP", "Focus on above window", hl.dsp.focus({ direction = "u" })) o.bind("SUPER + UP", "聚焦上方窗口", hl.dsp.focus({ direction = "u" }))
o.bind("SUPER + DOWN", "Focus on below window", hl.dsp.focus({ direction = "d" })) o.bind("SUPER + DOWN", "聚焦下方窗口", hl.dsp.focus({ direction = "d" }))
for workspace = 1, 10 do for workspace = 1, 10 do
local key = "code:" .. tostring(workspace + 9) local key = "code:" .. tostring(workspace + 9)
o.bind("SUPER + " .. key, "Switch to workspace " .. workspace, hl.dsp.focus({ workspace = tostring(workspace) })) o.bind("SUPER + " .. key, "切换到工作区 " .. workspace, hl.dsp.focus({ workspace = tostring(workspace) }))
o.bind("SUPER + SHIFT + " .. key, "Move window to workspace " .. workspace, hl.dsp.window.move({ workspace = tostring(workspace) })) o.bind("SUPER + SHIFT + " .. key, "窗口移到工作区 " .. workspace, hl.dsp.window.move({ workspace = tostring(workspace) }))
o.bind("SUPER + SHIFT + ALT + " .. key, "Move window silently to workspace " .. workspace, hl.dsp.window.move({ workspace = tostring(workspace), follow = false })) o.bind("SUPER + SHIFT + ALT + " .. key, "窗口静默移到工作区 " .. workspace, hl.dsp.window.move({ workspace = tostring(workspace), follow = false }))
end end
o.bind("SUPER + S", "Toggle scratchpad", hl.dsp.workspace.toggle_special("scratchpad")) o.bind("SUPER + S", "切换便签区", hl.dsp.workspace.toggle_special("scratchpad"))
o.bind("SUPER + ALT + S", "Move window to scratchpad", hl.dsp.window.move({ workspace = "special:scratchpad", follow = false })) o.bind("SUPER + ALT + S", "窗口移入便签区", hl.dsp.window.move({ workspace = "special:scratchpad", follow = false }))
o.bind("SUPER + grave", "Toggle scratchpad", hl.dsp.workspace.toggle_special("scratchpad")) o.bind("SUPER + grave", "切换便签区", hl.dsp.workspace.toggle_special("scratchpad"))
o.bind("SUPER + SHIFT + grave", "Move window to scratchpad", hl.dsp.window.move({ workspace = "special:scratchpad", follow = false })) o.bind("SUPER + SHIFT + grave", "窗口移入便签区", hl.dsp.window.move({ workspace = "special:scratchpad", follow = false }))
o.bind("SUPER + TAB", "Next workspace", hl.dsp.focus({ workspace = "e+1" })) o.bind("SUPER + TAB", "下一工作区", hl.dsp.focus({ workspace = "e+1" }))
o.bind("SUPER + SHIFT + TAB", "Previous workspace", hl.dsp.focus({ workspace = "e-1" })) o.bind("SUPER + SHIFT + TAB", "上一工作区", hl.dsp.focus({ workspace = "e-1" }))
o.bind("SUPER + CTRL + TAB", "Former workspace", hl.dsp.focus({ workspace = "previous" })) o.bind("SUPER + CTRL + TAB", "上次工作区", hl.dsp.focus({ workspace = "previous" }))
o.bind("SUPER + SHIFT + ALT + LEFT", "Move workspace to left monitor", hl.dsp.workspace.move({ monitor = "l" })) o.bind("SUPER + SHIFT + ALT + LEFT", "工作区移到左侧显示器", hl.dsp.workspace.move({ monitor = "l" }))
o.bind("SUPER + SHIFT + ALT + RIGHT", "Move workspace to right monitor", hl.dsp.workspace.move({ monitor = "r" })) o.bind("SUPER + SHIFT + ALT + RIGHT", "工作区移到右侧显示器", hl.dsp.workspace.move({ monitor = "r" }))
o.bind("SUPER + SHIFT + ALT + UP", "Move workspace to up monitor", hl.dsp.workspace.move({ monitor = "u" })) o.bind("SUPER + SHIFT + ALT + UP", "工作区移到上方显示器", hl.dsp.workspace.move({ monitor = "u" }))
o.bind("SUPER + SHIFT + ALT + DOWN", "Move workspace to down monitor", hl.dsp.workspace.move({ monitor = "d" })) o.bind("SUPER + SHIFT + ALT + DOWN", "工作区移到下方显示器", hl.dsp.workspace.move({ monitor = "d" }))
o.bind("SUPER + SHIFT + LEFT", "Swap window to the left", hl.dsp.window.swap({ direction = "l" })) o.bind("SUPER + SHIFT + LEFT", "窗口左移互换", hl.dsp.window.swap({ direction = "l" }))
o.bind("SUPER + SHIFT + RIGHT", "Swap window to the right", hl.dsp.window.swap({ direction = "r" })) o.bind("SUPER + SHIFT + RIGHT", "窗口右移互换", hl.dsp.window.swap({ direction = "r" }))
o.bind("SUPER + SHIFT + UP", "Swap window up", hl.dsp.window.swap({ direction = "u" })) o.bind("SUPER + SHIFT + UP", "窗口上移互换", hl.dsp.window.swap({ direction = "u" }))
o.bind("SUPER + SHIFT + DOWN", "Swap window down", hl.dsp.window.swap({ direction = "d" })) o.bind("SUPER + SHIFT + DOWN", "窗口下移互换", hl.dsp.window.swap({ direction = "d" }))
o.bind("ALT + TAB", "Focus on next window", hl.dsp.window.cycle_next()) o.bind("ALT + TAB", "聚焦下一窗口", hl.dsp.window.cycle_next())
o.bind("ALT + SHIFT + TAB", "Focus on previous window", hl.dsp.window.cycle_next({ next = false })) o.bind("ALT + SHIFT + TAB", "聚焦上一窗口", hl.dsp.window.cycle_next({ next = false }))
o.bind("ALT + TAB", "Reveal active window on top", hl.dsp.window.bring_to_top()) o.bind("ALT + TAB", "活动窗口置顶显示", hl.dsp.window.bring_to_top())
o.bind("ALT + SHIFT + TAB", "Reveal active window on top", hl.dsp.window.bring_to_top()) o.bind("ALT + SHIFT + TAB", "活动窗口置顶显示", hl.dsp.window.bring_to_top())
o.bind("CTRL + ALT + TAB", "Focus on next monitor", hl.dsp.focus({ monitor = "+1" })) o.bind("CTRL + ALT + TAB", "聚焦下一显示器", hl.dsp.focus({ monitor = "+1" }))
o.bind("CTRL + ALT + SHIFT + TAB", "Focus on previous monitor", hl.dsp.focus({ monitor = "-1" })) o.bind("CTRL + ALT + SHIFT + TAB", "聚焦上一显示器", hl.dsp.focus({ monitor = "-1" }))
o.bind("SUPER + code:20", "Expand window left", hl.dsp.window.resize({ x = -100, y = 0, relative = true })) o.bind("SUPER + code:20", "向左扩展窗口", hl.dsp.window.resize({ x = -100, y = 0, relative = true }))
o.bind("SUPER + code:21", "Shrink window left", hl.dsp.window.resize({ x = 100, y = 0, relative = true })) o.bind("SUPER + code:21", "向左收缩窗口", hl.dsp.window.resize({ x = 100, y = 0, relative = true }))
o.bind("SUPER + SHIFT + code:20", "Shrink window up", hl.dsp.window.resize({ x = 0, y = -100, relative = true })) o.bind("SUPER + SHIFT + code:20", "向上收缩窗口", hl.dsp.window.resize({ x = 0, y = -100, relative = true }))
o.bind("SUPER + SHIFT + code:21", "Expand window down", hl.dsp.window.resize({ x = 0, y = 100, relative = true })) o.bind("SUPER + SHIFT + code:21", "向下扩展窗口", hl.dsp.window.resize({ x = 0, y = 100, relative = true }))
o.bind("SUPER + ALT + code:20", "Expand window left a little", hl.dsp.window.resize({ x = -25, y = 0, relative = true })) o.bind("SUPER + ALT + code:20", "向左略微扩展窗口", hl.dsp.window.resize({ x = -25, y = 0, relative = true }))
o.bind("SUPER + ALT + code:21", "Shrink window left a little", hl.dsp.window.resize({ x = 25, y = 0, relative = true })) o.bind("SUPER + ALT + code:21", "向左略微收缩窗口", hl.dsp.window.resize({ x = 25, y = 0, relative = true }))
o.bind("SUPER + SHIFT + ALT + code:20", "Shrink window up a little", hl.dsp.window.resize({ x = 0, y = -25, relative = true })) o.bind("SUPER + SHIFT + ALT + code:20", "向上略微收缩窗口", hl.dsp.window.resize({ x = 0, y = -25, relative = true }))
o.bind("SUPER + SHIFT + ALT + code:21", "Expand window down a little", hl.dsp.window.resize({ x = 0, y = 25, relative = true })) o.bind("SUPER + SHIFT + ALT + code:21", "向下略微扩展窗口", hl.dsp.window.resize({ x = 0, y = 25, relative = true }))
o.bind("SUPER + CTRL + code:20", "Expand window left a lot", hl.dsp.window.resize({ x = -300, y = 0, relative = true })) o.bind("SUPER + CTRL + code:20", "向左大幅扩展窗口", hl.dsp.window.resize({ x = -300, y = 0, relative = true }))
o.bind("SUPER + CTRL + code:21", "Shrink window left a lot", hl.dsp.window.resize({ x = 300, y = 0, relative = true })) o.bind("SUPER + CTRL + code:21", "向左大幅收缩窗口", hl.dsp.window.resize({ x = 300, y = 0, relative = true }))
o.bind("SUPER + CTRL + SHIFT + code:20", "Shrink window up a lot", hl.dsp.window.resize({ x = 0, y = -300, relative = true })) o.bind("SUPER + CTRL + SHIFT + code:20", "向上大幅收缩窗口", hl.dsp.window.resize({ x = 0, y = -300, relative = true }))
o.bind("SUPER + CTRL + SHIFT + code:21", "Expand window down a lot", hl.dsp.window.resize({ x = 0, y = 300, relative = true })) o.bind("SUPER + CTRL + SHIFT + code:21", "向下大幅扩展窗口", hl.dsp.window.resize({ x = 0, y = 300, relative = true }))
o.bind("SUPER + mouse_down", "Scroll active workspace forward", hl.dsp.focus({ workspace = "e+1" })) o.bind("SUPER + mouse_down", "工作区向前滚动", hl.dsp.focus({ workspace = "e+1" }))
o.bind("SUPER + mouse_up", "Scroll active workspace backward", hl.dsp.focus({ workspace = "e-1" })) o.bind("SUPER + mouse_up", "工作区向后滚动", hl.dsp.focus({ workspace = "e-1" }))
o.bind("SUPER + mouse:272", "Move window", hl.dsp.window.drag(), { mouse = true }) o.bind("SUPER + mouse:272", "移动窗口", hl.dsp.window.drag(), { mouse = true })
o.bind("SUPER + mouse:273", "Resize window", hl.dsp.window.resize(), { mouse = true }) o.bind("SUPER + mouse:273", "调整窗口大小", hl.dsp.window.resize(), { mouse = true })
o.bind("SUPER + G", "Toggle window grouping", hl.dsp.group.toggle()) o.bind("SUPER + G", "切换窗口分组", hl.dsp.group.toggle())
o.bind("SUPER + ALT + G", "Move active window out of group", hl.dsp.window.move({ out_of_group = true })) o.bind("SUPER + ALT + G", "将窗口移出分组", hl.dsp.window.move({ out_of_group = true }))
o.bind("SUPER + ALT + LEFT", "Move window to group on left", hl.dsp.window.move({ into_group = "l" })) o.bind("SUPER + ALT + LEFT", "窗口并入左侧分组", hl.dsp.window.move({ into_group = "l" }))
o.bind("SUPER + ALT + RIGHT", "Move window to group on right", hl.dsp.window.move({ into_group = "r" })) o.bind("SUPER + ALT + RIGHT", "窗口并入右侧分组", hl.dsp.window.move({ into_group = "r" }))
o.bind("SUPER + ALT + UP", "Move window to group on top", hl.dsp.window.move({ into_group = "u" })) o.bind("SUPER + ALT + UP", "窗口并入上方分组", hl.dsp.window.move({ into_group = "u" }))
o.bind("SUPER + ALT + DOWN", "Move window to group on bottom", hl.dsp.window.move({ into_group = "d" })) o.bind("SUPER + ALT + DOWN", "窗口并入下方分组", hl.dsp.window.move({ into_group = "d" }))
o.bind("SUPER + ALT + TAB", "Next window in group", hl.dsp.group.next()) o.bind("SUPER + ALT + TAB", "组内下一窗口", hl.dsp.group.next())
o.bind("SUPER + ALT + SHIFT + TAB", "Previous window in group", hl.dsp.group.prev()) o.bind("SUPER + ALT + SHIFT + TAB", "组内上一窗口", hl.dsp.group.prev())
o.bind("SUPER + CTRL + LEFT", "Move grouped window focus left", hl.dsp.group.prev()) o.bind("SUPER + CTRL + LEFT", "组内焦点左移", hl.dsp.group.prev())
o.bind("SUPER + CTRL + RIGHT", "Move grouped window focus right", hl.dsp.group.next()) o.bind("SUPER + CTRL + RIGHT", "组内焦点右移", hl.dsp.group.next())
o.bind("SUPER + ALT + mouse_down", "Next window in group", hl.dsp.group.next()) o.bind("SUPER + ALT + mouse_down", "组内下一窗口", hl.dsp.group.next())
o.bind("SUPER + ALT + mouse_up", "Previous window in group", hl.dsp.group.prev()) o.bind("SUPER + ALT + mouse_up", "组内上一窗口", hl.dsp.group.prev())
for index = 1, 5 do for index = 1, 5 do
o.bind("SUPER + ALT + code:" .. tostring(index + 9), "Switch to group window " .. index, hl.dsp.group.active({ index = index })) o.bind("SUPER + ALT + code:" .. tostring(index + 9), "切换到组内窗口 " .. index, hl.dsp.group.active({ index = index }))
end end
o.bind("SUPER + SLASH", "Monitor scaling up", "omarchy-hyprland-monitor-scaling up") o.bind("SUPER + SLASH", "显示器缩放增大", "omarchy-hyprland-monitor-scaling up")
o.bind("SUPER + ALT + SLASH", "Monitor scaling down", "omarchy-hyprland-monitor-scaling down") o.bind("SUPER + ALT + SLASH", "显示器缩放减小", "omarchy-hyprland-monitor-scaling down")
+54 -54
View File
@@ -1,45 +1,45 @@
o.bind("SUPER + SPACE", "Omarchy menu", "omarchy-menu toggle") o.bind("SUPER + SPACE", "Omarchy 菜单", "omarchy-menu toggle")
o.bind("SUPER + ALT + SPACE", "Apps menu", "omarchy-menu toggle apps") o.bind("SUPER + ALT + SPACE", "应用菜单", "omarchy-menu toggle apps")
o.bind("SUPER + CTRL + E", "Emojis", "omarchy-shell shell toggle omarchy.emojis") o.bind("SUPER + CTRL + E", "表情", "omarchy-shell shell toggle omarchy.emojis")
o.bind("SUPER + CTRL + C", "Capture menu", "omarchy-menu toggle capture") o.bind("SUPER + CTRL + C", "截取菜单", "omarchy-menu toggle capture")
o.bind("SUPER + CTRL + O", "Toggle menu", "omarchy-menu toggle toggle") o.bind("SUPER + CTRL + O", "切换菜单", "omarchy-menu toggle toggle")
o.bind("SUPER + CTRL + H", "Hardware menu", "omarchy-menu toggle hardware") o.bind("SUPER + CTRL + H", "硬件菜单", "omarchy-menu toggle hardware")
o.bind("SUPER + SHIFT + code:201", "Omarchy menu", "omarchy-menu toggle root") o.bind("SUPER + SHIFT + code:201", "Omarchy 菜单", "omarchy-menu toggle root")
o.bind("SUPER + ESCAPE", "System menu", "omarchy-menu toggle system") o.bind("SUPER + ESCAPE", "系统菜单", "omarchy-menu toggle system")
o.bind("XF86PowerOff", "Power menu", "omarchy-menu toggle system", { locked = true }) o.bind("XF86PowerOff", "电源菜单", "omarchy-menu toggle system", { locked = true })
o.bind("SUPER + K", "Keybindings", "omarchy-menu-keybindings") o.bind("SUPER + K", "快捷键", "omarchy-menu-keybindings")
o.bind("SUPER + ALT + K", "Tmux keybindings", "omarchy-menu-tmux-keybindings") o.bind("SUPER + ALT + K", "Tmux 快捷键", "omarchy-menu-tmux-keybindings")
o.bind("SUPER + CTRL + K", "Herdr keybindings", "omarchy-menu-herdr-keybindings") o.bind("SUPER + CTRL + K", "Herdr 快捷键", "omarchy-menu-herdr-keybindings")
o.bind("SUPER + CTRL + Q", "Calculator", "omacalc") o.bind("SUPER + CTRL + Q", "计算器", "omacalc")
o.bind("XF86Calculator", "Calculator", "omacalc") o.bind("XF86Calculator", "计算器", "omacalc")
o.bind_toggle("SUPER + SHIFT + SPACE", "Toggle top bar", "bar") o.bind_toggle("SUPER + SHIFT + SPACE", "切换顶栏", "bar")
o.bind("SUPER + CTRL + SPACE", "Background switcher", "omarchy-menu toggle background") o.bind("SUPER + CTRL + SPACE", "壁纸切换", "omarchy-menu toggle background")
o.bind("SUPER + SHIFT + CTRL + SPACE", "Theme menu", "omarchy-menu toggle theme") o.bind("SUPER + SHIFT + CTRL + SPACE", "主题菜单", "omarchy-menu toggle theme")
o.bind("SUPER + BACKSPACE", "Toggle window transparency", "omarchy-hyprland-window-transparency-toggle") o.bind("SUPER + BACKSPACE", "切换窗口透明", "omarchy-hyprland-window-transparency-toggle")
o.bind("SUPER + SHIFT + BACKSPACE", "Toggle window gaps", "omarchy-hyprland-window-gaps-toggle") o.bind("SUPER + SHIFT + BACKSPACE", "切换窗口间距", "omarchy-hyprland-window-gaps-toggle")
o.bind("SUPER + CTRL + BACKSPACE", "Toggle single-window square aspect", "omarchy-hyprland-window-single-square-aspect-toggle") o.bind("SUPER + CTRL + BACKSPACE", "切换单窗口方形比例", "omarchy-hyprland-window-single-square-aspect-toggle")
-- xkbcommon names the comma keysym "comma"; the upper-case "COMMA" does not match. -- xkbcommon names the comma keysym "comma"; the upper-case "COMMA" does not match.
o.bind("SUPER + comma", "Dismiss last notification", "omarchy-shell notifications dismissOne") o.bind("SUPER + comma", "清除最近通知", "omarchy-shell notifications dismissOne")
o.bind("SUPER + SHIFT + comma", "Dismiss all notifications", "omarchy-shell notifications dismissAll") o.bind("SUPER + SHIFT + comma", "清除全部通知", "omarchy-shell notifications dismissAll")
o.bind_toggle("SUPER + CTRL + comma", "Toggle silencing notifications", "notification-silencing") o.bind_toggle("SUPER + CTRL + comma", "切换通知免打扰", "notification-silencing")
o.bind("SUPER + ALT + comma", "Invoke last notification", "omarchy-shell notifications invokeLast") o.bind("SUPER + ALT + comma", "打开最近通知", "omarchy-shell notifications invokeLast")
o.bind("SUPER + SHIFT + ALT + comma", "Open notification history", "omarchy-shell notifications showHistory") o.bind("SUPER + SHIFT + ALT + comma", "通知历史", "omarchy-shell notifications showHistory")
o.bind_toggle("SUPER + CTRL + I", "Toggle locking on idle", "idle") o.bind_toggle("SUPER + CTRL + I", "切换空闲锁定", "idle")
o.bind_toggle("SUPER + CTRL + N", "Toggle nightlight", "nightlight") o.bind_toggle("SUPER + CTRL + N", "切换夜间模式", "nightlight")
o.bind("SUPER + CTRL + Delete", "Toggle laptop display", "omarchy-hyprland-monitor-internal toggle") o.bind("SUPER + CTRL + Delete", "切换笔记本屏幕", "omarchy-hyprland-monitor-internal toggle")
o.bind("SUPER + CTRL + ALT + Delete", "Toggle laptop display mirroring", "omarchy-hyprland-monitor-internal-mirror toggle") o.bind("SUPER + CTRL + ALT + Delete", "切换笔记本镜像显示", "omarchy-hyprland-monitor-internal-mirror toggle")
o.bind("switch:on:Lid Switch", nil, "omarchy-system-lid-close", { locked = true }) o.bind("switch:on:Lid Switch", nil, "omarchy-system-lid-close", { locked = true })
o.bind("switch:off:Lid Switch", nil, "omarchy-hyprland-monitor-clamshell", { locked = true }) o.bind("switch:off:Lid Switch", nil, "omarchy-hyprland-monitor-clamshell", { locked = true })
o.bind("PRINT", "Screenshot", "omarchy-capture-screenshot") o.bind("PRINT", "截图", "omarchy-capture-screenshot")
o.bind("ALT + PRINT", "Screenrecording", "omarchy-capture-screenrecording --stop-recording || omarchy-menu toggle trigger.capture.screenrecord") o.bind("ALT + PRINT", "录屏", "omarchy-capture-screenrecording --stop-recording || omarchy-menu toggle trigger.capture.screenrecord")
o.bind("SUPER + ALT + code:34", "Make webcam overlay smaller", "omarchy-capture-webcam-resize smaller") o.bind("SUPER + ALT + code:34", "缩小摄像头悬浮窗", "omarchy-capture-webcam-resize smaller")
o.bind("SUPER + ALT + code:35", "Make webcam overlay larger", "omarchy-capture-webcam-resize larger") o.bind("SUPER + ALT + code:35", "放大摄像头悬浮窗", "omarchy-capture-webcam-resize larger")
o.bind("SUPER + PRINT", "Color picker", "pkill hyprpicker || hyprpicker -a") o.bind("SUPER + PRINT", "取色器", "pkill hyprpicker || hyprpicker -a")
o.bind("SUPER + CTRL + PRINT", "Extract text (OCR) from screenshot", "omarchy-capture-text") o.bind("SUPER + CTRL + PRINT", "截图取字(OCR", "omarchy-capture-text")
-- Keyboard control for the slurp region picker (see omarchy-capture-region). -- Keyboard control for the slurp region picker (see omarchy-capture-region).
-- The binds live exactly as long as a selection layer is on screen (slurp -- The binds live exactly as long as a selection layer is on screen (slurp
@@ -81,26 +81,26 @@ hl.on("layer.closed", function(layer)
end end
end) end)
o.bind("SUPER + CTRL + S", "Share", "omarchy-menu toggle share") o.bind("SUPER + CTRL + S", "分享", "omarchy-menu toggle share")
o.bind("SUPER + CTRL + PERIOD", "Transcode", "omarchy-transcode") o.bind("SUPER + CTRL + PERIOD", "转码", "omarchy-transcode")
o.bind("SUPER + CTRL + R", "Set reminder", "omarchy-menu toggle reminder-set") o.bind("SUPER + CTRL + R", "设置提醒", "omarchy-menu toggle reminder-set")
o.bind("SUPER + CTRL + ALT + R", "Show reminders", "omarchy-reminder show") o.bind("SUPER + CTRL + ALT + R", "查看提醒", "omarchy-reminder show")
o.bind("SUPER + SHIFT + CTRL + R", "Clear reminders", "omarchy-reminder clear") o.bind("SUPER + SHIFT + CTRL + R", "清除提醒", "omarchy-reminder clear")
o.bind("SUPER + CTRL + ALT + T", "Show time", "omarchy-notification-time") o.bind("SUPER + CTRL + ALT + T", "查看时间", "omarchy-notification-time")
o.bind("SUPER + CTRL + ALT + B", "Show battery remaining", "omarchy-notification-battery") o.bind("SUPER + CTRL + ALT + B", "查看剩余电量", "omarchy-notification-battery")
o.bind("SUPER + CTRL + ALT + W", "Toggle weather", "omarchy-notification-weather") o.bind("SUPER + CTRL + ALT + W", "切换天气", "omarchy-notification-weather")
o.bind("SUPER + SHIFT + CTRL + A", "Agent", "omarchy-agent --pick") o.bind("SUPER + SHIFT + CTRL + A", "Agent", "omarchy-agent --pick")
o.bind("SUPER + CTRL + A", "Audio", "omarchy-shell shell toggle omarchy.audio") o.bind("SUPER + CTRL + A", "音频", "omarchy-shell shell toggle omarchy.audio")
o.bind("SUPER + CTRL + B", "Bluetooth", "omarchy-shell shell toggle omarchy.bluetooth") o.bind("SUPER + CTRL + B", "蓝牙", "omarchy-shell shell toggle omarchy.bluetooth")
o.bind("SUPER + CTRL + D", "Display", "omarchy-shell shell toggle omarchy.monitor") o.bind("SUPER + CTRL + D", "显示", "omarchy-shell shell toggle omarchy.monitor")
o.bind("SUPER + CTRL + ALT + D", "Calendar", "omarchy-shell shell toggle omarchy.clock") o.bind("SUPER + CTRL + ALT + D", "日历", "omarchy-shell shell toggle omarchy.clock")
o.bind("SUPER + CTRL + W", "Network", "omarchy-shell shell toggle omarchy.network") o.bind("SUPER + CTRL + W", "网络", "omarchy-shell shell toggle omarchy.network")
o.bind("SUPER + CTRL + P", "Power", "omarchy-shell shell toggle omarchy.power") o.bind("SUPER + CTRL + P", "电源", "omarchy-shell shell toggle omarchy.power")
o.bind("SUPER + CTRL + T", "Activity", { tui = "btop" }) o.bind("SUPER + CTRL + T", "系统活动", { tui = "btop" })
-- The letters above name a panel; the numbers count them. 1 is the leftmost -- The letters above name a panel; the numbers count them. 1 is the leftmost
-- panel in the bar's right section, and a widget with no panel of its own (the -- panel in the bar's right section, and a widget with no panel of its own (the
@@ -109,18 +109,18 @@ o.bind("SUPER + CTRL + T", "Activity", { tui = "btop" })
for panel = 1, 9 do for panel = 1, 9 do
o.bind( o.bind(
"SUPER + CTRL + code:" .. tostring(panel + 9), "SUPER + CTRL + code:" .. tostring(panel + 9),
"Bar panel " .. panel, "顶栏面板 " .. panel,
"omarchy-shell -q shell togglePanelAt right " .. panel "omarchy-shell -q shell togglePanelAt right " .. panel
) )
end end
o.bind("SUPER + CTRL + Z", "Zoom in", function() o.bind("SUPER + CTRL + Z", "放大", function()
local zoom = hl.get_config("cursor.zoom_factor") or 1 local zoom = hl.get_config("cursor.zoom_factor") or 1
hl.config({ cursor = { zoom_factor = zoom + 1 } }) hl.config({ cursor = { zoom_factor = zoom + 1 } })
end) end)
o.bind("SUPER + CTRL + ALT + Z", "Reset zoom", function() o.bind("SUPER + CTRL + ALT + Z", "重置缩放", function()
hl.config({ cursor = { zoom_factor = 1 } }) hl.config({ cursor = { zoom_factor = 1 } })
end) end)
o.bind("SUPER + CTRL + L", "Lock system", "omarchy-system-lock") o.bind("SUPER + CTRL + L", "锁定系统", "omarchy-system-lock")
+3 -3
View File
@@ -1,5 +1,5 @@
if o.cmd_present("voxtype") then if o.cmd_present("voxtype") then
o.bind("SUPER + CTRL + X", "Toggle dictation", "voxtype record toggle") o.bind("SUPER + CTRL + X", "切换语音听写", "voxtype record toggle")
o.bind("F9", "Start dictation (push-to-talk)", "voxtype record start") o.bind("F9", "开始听写(按住说话)", "voxtype record start")
o.bind("F9", "Stop dictation (push-to-talk)", "voxtype record stop", { release = true }) o.bind("F9", "停止听写(按住说话)", "voxtype record stop", { release = true })
end end
-5
View File
@@ -19,11 +19,6 @@ kbd-layout-viewer5
kcm_fcitx5 kcm_fcitx5
kcm_kaccounts kcm_kaccounts
kvantummanager kvantummanager
libreoffice-base
libreoffice-draw
libreoffice-math
libreoffice-startcenter
libreoffice-xsltfilter
limine-snapper-restore limine-snapper-restore
lstopo lstopo
org.fcitx.Fcitx5 org.fcitx.Fcitx5
+202 -177
View File
@@ -21,131 +21,136 @@
// installed instead of vanishing from the list. // installed instead of vanishing from the list.
// Root Menu // Root Menu
"apps": {"icon":"󰀻","label":"Apps","aliases":["app","applications"],"provider":"apps"}, "apps": {"icon":"󰀻","label":"应用","aliases":["app","applications"],"provider":"apps"},
"learn": {"icon":"󰧑","label":"Learn"}, "learn": {"icon":"󰧑","label":"学习"},
"trigger": {"icon":"󱓞","label":"Trigger"}, "trigger": {"icon":"󱓞","label":"触发"},
"style": {"icon":"","label":"Style"}, "style": {"icon":"","label":"风格"},
"setup": {"icon":"","label":"Setup","aliases":["settings"]}, "setup": {"icon":"","label":"设置","aliases":["settings"]},
"install": {"icon":"󰉉","label":"Install"}, "install": {"icon":"󰉉","label":"安装"},
"remove": {"icon":"󰭌","label":"Remove","aliases":["uninstall"]}, "remove": {"icon":"󰭌","label":"移除","aliases":["uninstall"]},
"update": {"icon":"","label":"Update","aliases":["restart","refresh"]}, "update": {"icon":"","label":"更新","aliases":["restart","refresh"]},
"about": {"icon":"","label":"About","action":"omarchy-launch-about"}, "about": {"icon":"","label":"关于","action":"omarchy-launch-about"},
"system": {"icon":"","label":"System","aliases":["power-menu"]}, "system": {"icon":"","label":"系统","aliases":["power-menu"]},
// System // System
"system.screensaver": {"icon":"󱄄","label":"Screensaver","action":"omarchy-launch-screensaver force"}, "system.screensaver": {"icon":"󱄄","label":"屏保","action":"omarchy-launch-screensaver force"},
"system.lock": {"icon":"","label":"Lock","action":"omarchy-system-lock"}, "system.lock": {"icon":"","label":"锁屏","action":"omarchy-system-lock"},
"system.suspend": {"icon":"󰒲","label":"Suspend","when":"! omarchy-toggle-enabled suspend-off","action":"systemctl suspend"}, "system.suspend": {"icon":"󰒲","label":"睡眠","when":"! omarchy-toggle-enabled suspend-off","action":"systemctl suspend"},
"system.hibernate": {"icon":"󰤁","label":"Hibernate","when":"omarchy-hibernation-available","action":"systemctl hibernate"}, "system.hibernate": {"icon":"󰤁","label":"休眠","when":"omarchy-hibernation-available","action":"systemctl hibernate"},
"system.logout": {"icon":"󰍃","label":"Logout","action":"omarchy-system-logout"}, "system.logout": {"icon":"󰍃","label":"注销","action":"omarchy-system-logout"},
"system.reboot": {"icon":"󰜉","label":"Reboot","action":"omarchy-system-reboot"}, "system.reboot": {"icon":"󰜉","label":"重启","action":"omarchy-system-reboot"},
"system.shutdown": {"icon":"󰐥","label":"Shutdown","action":"omarchy-system-shutdown"}, "system.shutdown": {"icon":"󰐥","label":"关机","action":"omarchy-system-shutdown"},
// Learn // Learn
"learn.keybindings": {"icon":"","label":"Keybindings","action":"omarchy-menu-keybindings"}, "learn.keybindings": {"icon":"","label":"快捷键","action":"omarchy-menu-keybindings"},
"learn.omarchy": {"icon":"","label":"Omarchy","action":"omarchy-launch-webapp 'https://omarchy.org/manual/'"}, "learn.omarchy": {"icon":"","label":"Omarchy 手册","action":"omarchy-launch-webapp 'https://omarchy.org/manual/'"},
"learn.hyprland": {"icon":"","label":"Hyprland","action":"omarchy-launch-webapp 'https://wiki.hypr.land/'"}, "learn.hyprland": {"icon":"","label":"Hyprland","action":"omarchy-launch-webapp 'https://wiki.hypr.land/'"},
"learn.arch": {"icon":"󰣇","label":"Arch","action":"omarchy-launch-webapp 'https://wiki.archlinux.org/title/Main_page'"}, "learn.arch": {"icon":"󰣇","label":"Arch","action":"omarchy-launch-webapp 'https://wiki.archlinux.org/title/Main_page'"},
"learn.neovim": {"icon":"","label":"Neovim","action":"omarchy-launch-webapp 'https://www.lazyvim.org/keymaps'"}, "learn.neovim": {"icon":"","label":"Neovim","action":"omarchy-launch-webapp 'https://www.lazyvim.org/keymaps'"},
"learn.bash": {"icon":"󱆃","label":"Bash","action":"omarchy-launch-webapp 'https://devhints.io/bash'"}, "learn.bash": {"icon":"󱆃","label":"Bash","action":"omarchy-launch-webapp 'https://devhints.io/bash'"},
"learn.tmux-keybindings": {"icon":"","label":"Tmux","action":"omarchy-menu-tmux-keybindings"}, "learn.tmux-keybindings": {"icon":"","label":"Tmux","action":"omarchy-menu-tmux-keybindings"},
"learn.herdr-keybindings": {"icon":"","label":"Herdr","action":"omarchy-menu-herdr-keybindings"}, "learn.herdr-keybindings": {"icon":"","label":"Herdr","action":"omarchy-menu-herdr-keybindings"},
"learn.community": {"icon":"󰙯","label":"Community","action":"omarchy-launch-discord-community"}, "learn.community": {"icon":"󰙯","label":"社区","action":"omarchy-launch-discord-community"},
// Trigger // Trigger
"trigger.emoji": {"icon":"","label":"Emoji","aliases":["emoji","emojis"],"action":"omarchy-menu-emoji"}, "trigger.emoji": {"icon":"","label":"表情","aliases":["emoji","emojis"],"action":"omarchy-menu-emoji"},
"trigger.reminder": {"icon":"󰢌","label":"Reminder","aliases":["reminder"]}, "trigger.reminder": {"icon":"󰢌","label":"提醒","aliases":["reminder"]},
"trigger.capture": {"icon":"","label":"Capture","aliases":["capture","screenshot","screenrecord","screen-record","screenrecording"]}, "trigger.capture": {"icon":"","label":"截取","aliases":["capture","screenshot","screenrecord","screen-record","screenrecording"]},
"trigger.capture.screenshot": {"icon":"","label":"Screenshot","action":"omarchy-capture-screenshot"}, "trigger.capture.screenshot": {"icon":"","label":"截图","action":"omarchy-capture-screenshot"},
"trigger.capture.screenrecord.stop": {"icon":"","label":"Stop Screenrecording","when":"pgrep -f '^gpu-screen-recorder'","action":"omarchy-capture-screenrecording --stop-recording"}, "trigger.capture.screenrecord.stop": {"icon":"","label":"停止录屏","when":"pgrep -f '^gpu-screen-recorder'","action":"omarchy-capture-screenrecording --stop-recording"},
"trigger.capture.screenrecord": {"icon":"","label":"Screenrecord"}, "trigger.capture.screenrecord": {"icon":"","label":"录屏"},
"trigger.capture.text": {"icon":"󰴑","label":"Text","action":"omarchy-capture-text"}, "trigger.capture.text": {"icon":"󰴑","label":"取字 OCR","action":"omarchy-capture-text"},
"trigger.capture.qr": {"icon":"󰐲","label":"QR Code","action":"omarchy-capture-qr"}, "trigger.capture.qr": {"icon":"󰐲","label":"二维码","action":"omarchy-capture-qr"},
"trigger.capture.color": {"icon":"󰃉","label":"Color","action":"pkill hyprpicker || hyprpicker -a"}, "trigger.capture.color": {"icon":"󰃉","label":"取色","action":"pkill hyprpicker || hyprpicker -a"},
"trigger.capture.screenrecord.no-audio": {"icon":"","label":"With no audio","action":"omarchy-capture-screenrecording"}, "trigger.capture.screenrecord.no-audio": {"icon":"","label":"无音频","action":"omarchy-capture-screenrecording"},
"trigger.capture.screenrecord.desktop-audio": {"icon":"","label":"With desktop audio","action":"omarchy-capture-screenrecording --with-desktop-audio"}, "trigger.capture.screenrecord.desktop-audio": {"icon":"","label":"含桌面音频","action":"omarchy-capture-screenrecording --with-desktop-audio"},
"trigger.capture.screenrecord.microphone": {"icon":"","label":"With desktop + microphone audio","action":"omarchy-capture-screenrecording --with-desktop-audio --with-microphone-audio"}, "trigger.capture.screenrecord.microphone": {"icon":"","label":"含桌面与麦克风音频","action":"omarchy-capture-screenrecording --with-desktop-audio --with-microphone-audio"},
"trigger.capture.screenrecord.webcam": {"icon":"","label":"With desktop + microphone audio + webcam","when":"omarchy-hw-webcam","action":"omarchy-capture-screenrecording-with-webcam"}, "trigger.capture.screenrecord.webcam": {"icon":"","label":"含桌面、麦克风与摄像头","when":"omarchy-hw-webcam","action":"omarchy-capture-screenrecording-with-webcam"},
"trigger.transcode": {"icon":"󰧸","label":"Transcode","action":"omarchy-transcode"}, "trigger.transcode": {"icon":"󰧸","label":"转码","action":"omarchy-transcode"},
"trigger.share": {"icon":"","label":"Share","aliases":["share"]}, "trigger.share": {"icon":"","label":"分享","aliases":["share"]},
"trigger.toggle": {"icon":"󰔎","label":"Toggle","aliases":["toggle","toggles"]}, "trigger.toggle": {"icon":"󰔎","label":"开关","aliases":["toggle","toggles"]},
"trigger.hardware": {"icon":"","label":"Hardware","aliases":["hardware","hw"]}, "trigger.hardware": {"icon":"","label":"硬件","aliases":["hardware","hw"]},
"trigger.tests": {"icon":"󰓅","label":"Speed Test"}, "trigger.tests": {"icon":"󰓅","label":"测速"},
"trigger.hardware.laptop-display": {"icon":"󰛧","label":"Laptop Display","when":"omarchy-hw-laptop","action":"omarchy-hyprland-monitor-internal toggle"}, "trigger.hardware.laptop-display": {"icon":"󰛧","label":"笔记本屏幕","when":"omarchy-hw-laptop","action":"omarchy-hyprland-monitor-internal toggle"},
"trigger.hardware.mirror-display": {"icon":"󰍹","label":"Mirror Display","when":"omarchy-hw-laptop","action":"omarchy-hyprland-monitor-internal-mirror toggle"}, "trigger.hardware.mirror-display": {"icon":"󰍹","label":"镜像显示","when":"omarchy-hw-laptop","action":"omarchy-hyprland-monitor-internal-mirror toggle"},
"trigger.hardware.hybrid-gpu": {"icon":"","label":"Hybrid GPU","when":"omarchy-hw-hybrid-gpu","action":"omarchy-launch-floating-terminal-with-presentation omarchy-toggle-hybrid-gpu"}, "trigger.hardware.hybrid-gpu": {"icon":"","label":"混合显卡","when":"omarchy-hw-hybrid-gpu","action":"omarchy-launch-floating-terminal-with-presentation omarchy-toggle-hybrid-gpu"},
"trigger.hardware.touchpad": {"icon":"󰟸","label":"Touchpad","when":"omarchy-hw-touchpad","action":"omarchy-toggle-touchpad"}, "trigger.hardware.touchpad": {"icon":"󰟸","label":"触控板","when":"omarchy-hw-touchpad","action":"omarchy-toggle-touchpad"},
"trigger.hardware.touchpad-haptics": {"icon":"󰌌","label":"Touchpad Haptics"}, "trigger.hardware.touchpad-haptics": {"icon":"󰌌","label":"触控板振动"},
"trigger.hardware.touchpad-haptics.low": {"icon":"󰌌","label":"low","when":"omarchy-hw-dell-xps-haptic-touchpad && omarchy-cmd-present dell-xps-touchpad-haptics","checked":"[[ \"$(dell-xps-touchpad-haptics get)\" == \"low\" ]]","action":"dell-xps-touchpad-haptics set low"}, "trigger.hardware.touchpad-haptics.low": {"icon":"󰌌","label":"","when":"omarchy-hw-dell-xps-haptic-touchpad && omarchy-cmd-present dell-xps-touchpad-haptics","checked":"[[ \"$(dell-xps-touchpad-haptics get)\" == \"low\" ]]","action":"dell-xps-touchpad-haptics set low"},
"trigger.hardware.touchpad-haptics.mid": {"icon":"󰌌","label":"mid","when":"omarchy-hw-dell-xps-haptic-touchpad && omarchy-cmd-present dell-xps-touchpad-haptics","checked":"[[ \"$(dell-xps-touchpad-haptics get)\" == \"mid\" ]]","action":"dell-xps-touchpad-haptics set mid"}, "trigger.hardware.touchpad-haptics.mid": {"icon":"󰌌","label":"","when":"omarchy-hw-dell-xps-haptic-touchpad && omarchy-cmd-present dell-xps-touchpad-haptics","checked":"[[ \"$(dell-xps-touchpad-haptics get)\" == \"mid\" ]]","action":"dell-xps-touchpad-haptics set mid"},
"trigger.hardware.touchpad-haptics.high": {"icon":"󰌌","label":"high","when":"omarchy-hw-dell-xps-haptic-touchpad && omarchy-cmd-present dell-xps-touchpad-haptics","checked":"[[ \"$(dell-xps-touchpad-haptics get)\" == \"high\" ]]","action":"dell-xps-touchpad-haptics set high"}, "trigger.hardware.touchpad-haptics.high": {"icon":"󰌌","label":"","when":"omarchy-hw-dell-xps-haptic-touchpad && omarchy-cmd-present dell-xps-touchpad-haptics","checked":"[[ \"$(dell-xps-touchpad-haptics get)\" == \"high\" ]]","action":"dell-xps-touchpad-haptics set high"},
"trigger.hardware.touchscreen": {"icon":"󰆽","label":"Touchscreen","when":"omarchy-hw-touchscreen","action":"omarchy-toggle-touchscreen"}, "trigger.hardware.touchscreen": {"icon":"󰆽","label":"触摸屏","when":"omarchy-hw-touchscreen","action":"omarchy-toggle-touchscreen"},
"trigger.reminder.set": {"icon":"󰢌","label":"Set one","aliases":["reminder-set","remind"],"action":"omarchy-reminder -i"}, "trigger.reminder.set": {"icon":"󰢌","label":"设一个提醒","aliases":["reminder-set","remind"],"action":"omarchy-reminder -i"},
"trigger.reminder.show": {"icon":"󰢌","label":"Show all","action":"omarchy-reminder show"}, "trigger.reminder.show": {"icon":"󰢌","label":"查看全部","action":"omarchy-reminder show"},
"trigger.reminder.clear": {"icon":"󰢌","label":"Clear all","action":"omarchy-reminder clear"}, "trigger.reminder.clear": {"icon":"󰢌","label":"清除全部","action":"omarchy-reminder clear"},
"trigger.share.clipboard": {"icon":"","label":"Clipboard","action":"omarchy-menu-share clipboard"}, "trigger.share.clipboard": {"icon":"","label":"剪贴板","action":"omarchy-menu-share clipboard"},
"trigger.share.file": {"icon":"","label":"File","action":"omarchy-menu-share file"}, "trigger.share.file": {"icon":"","label":"文件","action":"omarchy-menu-share file"},
"trigger.share.folder": {"icon":"","label":"Folder","action":"omarchy-menu-share folder"}, "trigger.share.folder": {"icon":"","label":"文件夹","action":"omarchy-menu-share folder"},
"trigger.share.receive": {"icon":"󰥦","label":"Receive","action":"uwsm-app -- localsend"}, "trigger.share.receive": {"icon":"󰥦","label":"接收","action":"uwsm-app -- localsend"},
"trigger.toggle.idle-lock": {"icon":"󰅶","label":"Stay Awake","action":"omarchy-toggle-idle"}, "trigger.toggle.idle-lock": {"icon":"󰅶","label":"保持唤醒","action":"omarchy-toggle-idle"},
"trigger.toggle.notifications": {"icon":"󰂛","label":"Notifications","action":"omarchy-toggle-notification-silencing"}, "trigger.toggle.notifications": {"icon":"󰂛","label":"通知","action":"omarchy-toggle-notification-silencing"},
"trigger.toggle.crash-capture": {"icon":"󱚡","label":"Crash Capture","action":"omarchy-toggle-crash-capture"}, "trigger.toggle.crash-capture": {"icon":"󱚡","label":"崩溃捕获","action":"omarchy-toggle-crash-capture"},
"trigger.toggle.screensaver": {"icon":"󱄄","label":"Screensaver","action":"omarchy-toggle-screensaver"}, "trigger.toggle.screensaver": {"icon":"󱄄","label":"屏保","action":"omarchy-toggle-screensaver"},
"trigger.toggle.nightlight": {"icon":"󰔎","label":"Nightlight","action":"omarchy-toggle-nightlight"}, "trigger.toggle.nightlight": {"icon":"󰔎","label":"夜间模式","action":"omarchy-toggle-nightlight"},
"trigger.toggle.top-bar": {"icon":"󰍜","label":"Menu Bar","action":"omarchy-toggle-bar"}, "trigger.toggle.top-bar": {"icon":"󰍜","label":"菜单栏","action":"omarchy-toggle-bar"},
"trigger.toggle.battery-percentage": {"icon":"󰁹","label":"Battery Percentage","when":"omarchy-hw-laptop","action":"omarchy-shell omarchy.power togglePercentage"}, "trigger.toggle.battery-percentage": {"icon":"󰁹","label":"电量百分比","when":"omarchy-hw-laptop","action":"omarchy-shell omarchy.power togglePercentage"},
"trigger.toggle.workspace-layout": {"icon":"󱂬","label":"Workspace Layout","action":"omarchy-hyprland-workspace-layout-toggle"}, "trigger.toggle.workspace-layout": {"icon":"󱂬","label":"工作区布局","action":"omarchy-hyprland-workspace-layout-toggle"},
"trigger.toggle.window-gaps": {"icon":"","label":"Window Gaps","action":"omarchy-hyprland-window-gaps-toggle"}, "trigger.toggle.window-gaps": {"icon":"","label":"窗口间距","action":"omarchy-hyprland-window-gaps-toggle"},
"trigger.toggle.one-window-ratio": {"icon":"","label":"1-Window Ratio","action":"omarchy-hyprland-window-single-square-aspect-toggle"}, "trigger.toggle.one-window-ratio": {"icon":"","label":"单窗口比例","action":"omarchy-hyprland-window-single-square-aspect-toggle"},
"trigger.tests.network-speedtest": {"icon":"󰓅","label":"Network Speed Test","action":"omarchy-shell shell summon omarchy.speedtest"}, "trigger.tests.network-speedtest": {"icon":"󰓅","label":"网络测速","action":"omarchy-shell shell summon omarchy.speedtest"},
"trigger.tests.disk-speedtest": {"icon":"󰋊","label":"Disk Speed Test","action":"omarchy-shell shell summon omarchy.disk-speedtest"}, "trigger.tests.disk-speedtest": {"icon":"󰋊","label":"磁盘测速","action":"omarchy-shell shell summon omarchy.disk-speedtest"},
// Style // Style
"style.theme": {"icon":"󰸌","label":"Theme","aliases":["theme","themes"],"action":"theme=$(omarchy-theme-switcher); [[ -n $theme ]] && omarchy-theme-set \"$theme\""}, "style.theme": {"icon":"󰸌","label":"主题","aliases":["theme","themes"],"action":"theme=$(omarchy-theme-switcher); [[ -n $theme ]] && omarchy-theme-set \"$theme\""},
"style.background": {"icon":"","label":"Background","aliases":["background","wallpaper"],"action":"background=$(omarchy-theme-bg-switcher); [[ -n $background ]] && omarchy-theme-bg-set \"$background\""}, "style.background": {"icon":"","label":"壁纸","aliases":["background","wallpaper"],"action":"background=$(omarchy-theme-bg-switcher); [[ -n $background ]] && omarchy-theme-bg-set \"$background\""},
"style.unlock": {"icon":"󰟵","label":"Unlock","aliases":["unlock"],"action":"unlock=$(omarchy-plymouth-switcher); if [[ $unlock == default ]]; then omarchy-launch-floating-terminal-with-presentation omarchy-plymouth-reset; elif [[ -n $unlock ]]; then omarchy-launch-floating-terminal-with-presentation \"omarchy-plymouth-set-by-theme '$unlock'\"; fi"}, "style.unlock": {"icon":"󰟵","label":"解锁画面","aliases":["unlock"],"action":"unlock=$(omarchy-plymouth-switcher); if [[ $unlock == default ]]; then omarchy-launch-floating-terminal-with-presentation omarchy-plymouth-reset; elif [[ -n $unlock ]]; then omarchy-launch-floating-terminal-with-presentation \"omarchy-plymouth-set-by-theme '$unlock'\"; fi"},
"style.font": {"icon":"","label":"Font","provider":"fonts"}, "style.font": {"icon":"","label":"字体","provider":"fonts"},
"style.bar": {"icon":"󰍜","label":"Menu Bar"}, "style.bar": {"icon":"󰍜","label":"菜单栏"},
"style.bar.position": {"icon":"","label":"Position"}, "style.bar.position": {"icon":"","label":"位置"},
"style.bar.transparency": {"icon":"󰂵","label":"Transparency","action":"omarchy-bar transparent toggle"}, "style.bar.transparency": {"icon":"󰂵","label":"透明","action":"omarchy-bar transparent toggle"},
"style.hyprland": {"icon":"","label":"Hyprland","action":"omarchy-launch-config-editor \"$HOME/.config/hypr/looknfeel.lua\""}, "style.hyprland": {"icon":"","label":"Hyprland","action":"omarchy-launch-config-editor \"$HOME/.config/hypr/looknfeel.lua\""},
"style.screensaver": {"icon":"󱄄","label":"Screensaver"}, "style.screensaver": {"icon":"󱄄","label":"屏保"},
"style.about": {"icon":"","label":"About"}, "style.about": {"icon":"","label":"关于页"},
"style.bar.position.top": {"icon":"󰁝","label":"Top","action":"omarchy-bar position top"}, "style.bar.position.top": {"icon":"󰁝","label":"顶部","action":"omarchy-bar position top"},
"style.bar.position.bottom": {"icon":"󰁅","label":"Bottom","action":"omarchy-bar position bottom"}, "style.bar.position.bottom": {"icon":"󰁅","label":"底部","action":"omarchy-bar position bottom"},
"style.bar.position.left": {"icon":"󰁍","label":"Left","action":"omarchy-bar position left"}, "style.bar.position.left": {"icon":"󰁍","label":"左侧","action":"omarchy-bar position left"},
"style.bar.position.right": {"icon":"󰁔","label":"Right","action":"omarchy-bar position right"}, "style.bar.position.right": {"icon":"󰁔","label":"右侧","action":"omarchy-bar position right"},
"style.about.text": {"icon":"","label":"Edit Text","action":"omarchy-branding-about text"}, "style.about.text": {"icon":"","label":"编辑文字","action":"omarchy-branding-about text"},
"style.about.image": {"icon":"","label":"Set From Image","action":"omarchy-branding-about image"}, "style.about.image": {"icon":"","label":"取自图片","action":"omarchy-branding-about image"},
"style.about.default": {"icon":"","label":"Restore Default","action":"omarchy-branding-about reset"}, "style.about.default": {"icon":"","label":"恢复默认","action":"omarchy-branding-about reset"},
"style.screensaver.text": {"icon":"","label":"Edit Text","action":"omarchy-branding-screensaver text"}, "style.screensaver.text": {"icon":"","label":"编辑文字","action":"omarchy-branding-screensaver text"},
"style.screensaver.image": {"icon":"","label":"Set From Image","action":"omarchy-branding-screensaver image"}, "style.screensaver.image": {"icon":"","label":"取自图片","action":"omarchy-branding-screensaver image"},
"style.screensaver.default": {"icon":"","label":"Restore Default","action":"omarchy-branding-screensaver reset"}, "style.screensaver.default": {"icon":"","label":"恢复默认","action":"omarchy-branding-screensaver reset"},
// Setup // Setup
"setup.monitors": {"icon":"󰍹","label":"Monitors","action":"omarchy-launch-config-editor \"$HOME/.config/hypr/monitors.lua\""}, "setup.monitors": {"icon":"󰍹","label":"显示器","action":"omarchy-launch-config-editor \"$HOME/.config/hypr/monitors.lua\""},
"setup.keybindings": {"icon":"","label":"Keybindings","when":"[[ -f ~/.config/hypr/bindings.lua ]]","action":"omarchy-launch-config-editor \"$HOME/.config/hypr/bindings.lua\""}, "setup.keybindings": {"icon":"","label":"快捷键","when":"[[ -f ~/.config/hypr/bindings.lua ]]","action":"omarchy-launch-config-editor \"$HOME/.config/hypr/bindings.lua\""},
"setup.input": {"icon":"","label":"Input","when":"[[ -f ~/.config/hypr/input.lua ]]","action":"omarchy-launch-config-editor \"$HOME/.config/hypr/input.lua\""}, "setup.input": {"icon":"","label":"输入设备","when":"[[ -f ~/.config/hypr/input.lua ]]","action":"omarchy-launch-config-editor \"$HOME/.config/hypr/input.lua\""},
"setup.network": {"icon":"󰛳","label":"Network","aliases":["network"]}, "setup.network": {"icon":"󰛳","label":"网络","aliases":["network"]},
"setup.network.dns": {"icon":"󰇖","label":"DNS","aliases":["dns"]}, "setup.network.dns": {"icon":"󰇖","label":"DNS","aliases":["dns"]},
"setup.network.dns.dhcp": {"icon":"󰩟","label":"DHCP","checked":"[[ \"$(omarchy-dns)\" == \"DHCP\" ]]","action":"omarchy-dns DHCP"}, "setup.network.dns.dhcp": {"icon":"󰩟","label":"DHCP","checked":"[[ \"$(omarchy-dns)\" == \"DHCP\" ]]","action":"omarchy-dns DHCP"},
"setup.network.dns.cloudflare": {"icon":"󰅟","label":"Cloudflare","checked":"[[ \"$(omarchy-dns)\" == \"Cloudflare\" ]]","action":"omarchy-dns Cloudflare"}, "setup.network.dns.cloudflare": {"icon":"󰅟","label":"Cloudflare","checked":"[[ \"$(omarchy-dns)\" == \"Cloudflare\" ]]","action":"omarchy-dns Cloudflare"},
"setup.network.dns.google": {"icon":"󰊭","label":"Google","checked":"[[ \"$(omarchy-dns)\" == \"Google\" ]]","action":"omarchy-dns Google"}, "setup.network.dns.google": {"icon":"󰊭","label":"Google","checked":"[[ \"$(omarchy-dns)\" == \"Google\" ]]","action":"omarchy-dns Google"},
"setup.network.dns.custom": {"icon":"","label":"Custom","checked":"[[ \"$(omarchy-dns)\" == \"Custom\" ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-dns Custom'"}, "setup.network.dns.custom": {"icon":"","label":"自定义","checked":"[[ \"$(omarchy-dns)\" == \"Custom\" ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-dns Custom'"},
"setup.network.qr": {"icon":"󰐲","label":"QR Code","aliases":["wifi-qr"],"when":"[[ $(omarchy-network-status) == wifi* ]]","action":"omarchy-shell shell summon omarchy.wifiqr"}, "setup.network.qr": {"icon":"󰐲","label":"二维码","aliases":["wifi-qr"],"when":"[[ $(omarchy-network-status) == wifi* ]]","action":"omarchy-shell shell summon omarchy.wifiqr"},
"setup.default": {"icon":"","label":"Defaults","aliases":["default","defaults"]}, "setup.default": {"icon":"","label":"默认程序","aliases":["default","defaults"]},
"setup.default.agent": {"icon":"󰚩","label":"Agent","title":"Default Agent"}, "setup.default.agent": {"icon":"󰚩","label":"Agent","title":"默认 Agent"},
"setup.default.agent.agy": {"icon":"󰫢","label":"Antigravity","checked":"[[ \"$(omarchy-default-agent)\" == \"agy\" ]]","action":"omarchy-default-agent agy"}, "setup.default.agent.agy": {"icon":"󰫢","label":"Antigravity","checked":"[[ \"$(omarchy-default-agent)\" == \"agy\" ]]","action":"omarchy-default-agent agy"},
"setup.default.agent.claude": {"icon":"󰛄","label":"Claude","checked":"[[ \"$(omarchy-default-agent)\" == \"claude\" ]]","action":"omarchy-default-agent claude"}, "setup.default.agent.claude": {"icon":"󰛄","label":"Claude","checked":"[[ \"$(omarchy-default-agent)\" == \"claude\" ]]","action":"omarchy-default-agent claude"},
"setup.default.agent.codex": {"icon":"","iconFont":"omarchy","label":"Codex","checked":"[[ \"$(omarchy-default-agent)\" == \"codex\" ]]","action":"omarchy-default-agent codex"}, "setup.default.agent.codex": {"icon":"","iconFont":"omarchy","label":"Codex","checked":"[[ \"$(omarchy-default-agent)\" == \"codex\" ]]","action":"omarchy-default-agent codex"},
"setup.default.agent.copilot": {"icon":"","label":"Copilot","checked":"[[ \"$(omarchy-default-agent)\" == \"copilot\" ]]","action":"omarchy-default-agent copilot"}, "setup.default.agent.copilot": {"icon":"","label":"Copilot","checked":"[[ \"$(omarchy-default-agent)\" == \"copilot\" ]]","action":"omarchy-default-agent copilot"},
"setup.default.agent.crush": {"icon":"󰋑","label":"Crush","checked":"[[ \"$(omarchy-default-agent)\" == \"crush\" ]]","action":"omarchy-default-agent crush"}, "setup.default.agent.crush": {"icon":"󰋑","label":"Crush","checked":"[[ \"$(omarchy-default-agent)\" == \"crush\" ]]","action":"omarchy-default-agent crush"},
"setup.default.agent.deepcode": {"icon":"󱚤","label":"Deep Code","checked":"[[ \"$(omarchy-default-agent)\" == \"deepcode\" ]]","action":"omarchy-default-agent deepcode"},
"setup.default.agent.dim": {"icon":"󱚤","label":"Dim Agent","checked":"[[ \"$(omarchy-default-agent)\" == \"dim\" ]]","action":"omarchy-default-agent dim"},
"setup.default.agent.dsh": {"icon":"󱚤","label":"DSH","checked":"[[ \"$(omarchy-default-agent)\" == \"dsh\" ]]","action":"omarchy-default-agent dsh"},
"setup.default.agent.grok": {"icon":"","iconFont":"omarchy","label":"Grok","checked":"[[ \"$(omarchy-default-agent)\" == \"grok\" ]]","action":"omarchy-default-agent grok"}, "setup.default.agent.grok": {"icon":"","iconFont":"omarchy","label":"Grok","checked":"[[ \"$(omarchy-default-agent)\" == \"grok\" ]]","action":"omarchy-default-agent grok"},
"setup.default.agent.kimi": {"icon":"󱚤","label":"Kimi Code","checked":"[[ \"$(omarchy-default-agent)\" == \"kimi\" ]]","action":"omarchy-default-agent kimi"},
"setup.default.agent.omp": {"icon":"","iconFont":"omarchy","label":"omp","checked":"[[ \"$(omarchy-default-agent)\" == \"omp\" ]]","action":"omarchy-default-agent omp"}, "setup.default.agent.omp": {"icon":"","iconFont":"omarchy","label":"omp","checked":"[[ \"$(omarchy-default-agent)\" == \"omp\" ]]","action":"omarchy-default-agent omp"},
"setup.default.agent.opencode": {"icon":"","iconFont":"omarchy","label":"OpenCode","checked":"[[ \"$(omarchy-default-agent)\" == \"opencode\" ]]","action":"omarchy-default-agent opencode"}, "setup.default.agent.opencode": {"icon":"","iconFont":"omarchy","label":"OpenCode","checked":"[[ \"$(omarchy-default-agent)\" == \"opencode\" ]]","action":"omarchy-default-agent opencode"},
"setup.default.agent.ori": {"icon":"","iconFont":"omarchy","label":"Ori","checked":"[[ \"$(omarchy-default-agent)\" == \"ori\" ]]","action":"omarchy-default-agent ori"}, "setup.default.agent.ori": {"icon":"","iconFont":"omarchy","label":"Ori","checked":"[[ \"$(omarchy-default-agent)\" == \"ori\" ]]","action":"omarchy-default-agent ori"},
"setup.default.agent.pi": {"icon":"","iconFont":"omarchy","label":"Pi","checked":"[[ \"$(omarchy-default-agent)\" == \"pi\" ]]","action":"omarchy-default-agent pi"}, "setup.default.agent.pi": {"icon":"","iconFont":"omarchy","label":"Pi","checked":"[[ \"$(omarchy-default-agent)\" == \"pi\" ]]","action":"omarchy-default-agent pi"},
"setup.default.browser": {"icon":"","label":"Browser","title":"Default Browser"}, "setup.default.agent.cn-hub": {"icon":"󱚤","label":"国产模型组合 (AI Hub)","action":"omarchy-launch-floating-terminal-with-presentation omarchy-cn-ai-setup"},
"setup.default.browser": {"icon":"","label":"浏览器","title":"默认浏览器"},
"setup.default.browser.chromium": {"icon":"","label":"Chromium","checked":"[[ \"$(omarchy-default-browser)\" == \"chromium\" ]]","action":"omarchy-default-browser chromium"}, "setup.default.browser.chromium": {"icon":"","label":"Chromium","checked":"[[ \"$(omarchy-default-browser)\" == \"chromium\" ]]","action":"omarchy-default-browser chromium"},
"setup.default.browser.chrome": {"icon":"󰊯","label":"Chrome","checked":"[[ \"$(omarchy-default-browser)\" == \"chrome\" ]]","action":"omarchy-default-browser chrome"}, "setup.default.browser.chrome": {"icon":"󰊯","label":"Chrome","checked":"[[ \"$(omarchy-default-browser)\" == \"chrome\" ]]","action":"omarchy-default-browser chrome"},
"setup.default.browser.brave": {"icon":"󰖟","label":"Brave","checked":"[[ \"$(omarchy-default-browser)\" == \"brave\" ]]","action":"omarchy-default-browser brave"}, "setup.default.browser.brave": {"icon":"󰖟","label":"Brave","checked":"[[ \"$(omarchy-default-browser)\" == \"brave\" ]]","action":"omarchy-default-browser brave"},
@@ -153,12 +158,12 @@
"setup.default.browser.edge": {"icon":"󰇩","label":"Edge","checked":"[[ \"$(omarchy-default-browser)\" == \"edge\" ]]","action":"omarchy-default-browser edge"}, "setup.default.browser.edge": {"icon":"󰇩","label":"Edge","checked":"[[ \"$(omarchy-default-browser)\" == \"edge\" ]]","action":"omarchy-default-browser edge"},
"setup.default.browser.firefox": {"icon":"","label":"Firefox","checked":"[[ \"$(omarchy-default-browser)\" == \"firefox\" ]]","action":"omarchy-default-browser firefox"}, "setup.default.browser.firefox": {"icon":"","label":"Firefox","checked":"[[ \"$(omarchy-default-browser)\" == \"firefox\" ]]","action":"omarchy-default-browser firefox"},
"setup.default.browser.zen": {"icon":"󰖟","label":"Zen","checked":"[[ \"$(omarchy-default-browser)\" == \"zen\" ]]","action":"omarchy-default-browser zen"}, "setup.default.browser.zen": {"icon":"󰖟","label":"Zen","checked":"[[ \"$(omarchy-default-browser)\" == \"zen\" ]]","action":"omarchy-default-browser zen"},
"setup.default.terminal": {"icon":"","label":"Terminal","title":"Default Terminal"}, "setup.default.terminal": {"icon":"","label":"终端","title":"默认终端"},
"setup.default.terminal.alacritty": {"icon":"","label":"Alacritty","checked":"[[ \"$(omarchy-default-terminal)\" == \"alacritty\" ]]","action":"omarchy-default-terminal alacritty"}, "setup.default.terminal.alacritty": {"icon":"","label":"Alacritty","checked":"[[ \"$(omarchy-default-terminal)\" == \"alacritty\" ]]","action":"omarchy-default-terminal alacritty"},
"setup.default.terminal.foot": {"icon":"","label":"Foot","checked":"[[ \"$(omarchy-default-terminal)\" == \"foot\" ]]","action":"omarchy-default-terminal foot"}, "setup.default.terminal.foot": {"icon":"","label":"Foot","checked":"[[ \"$(omarchy-default-terminal)\" == \"foot\" ]]","action":"omarchy-default-terminal foot"},
"setup.default.terminal.ghostty": {"icon":"","label":"Ghostty","checked":"[[ \"$(omarchy-default-terminal)\" == \"ghostty\" ]]","action":"omarchy-default-terminal ghostty"}, "setup.default.terminal.ghostty": {"icon":"","label":"Ghostty","checked":"[[ \"$(omarchy-default-terminal)\" == \"ghostty\" ]]","action":"omarchy-default-terminal ghostty"},
"setup.default.terminal.kitty": {"icon":"","label":"Kitty","checked":"[[ \"$(omarchy-default-terminal)\" == \"kitty\" ]]","action":"omarchy-default-terminal kitty"}, "setup.default.terminal.kitty": {"icon":"","label":"Kitty","checked":"[[ \"$(omarchy-default-terminal)\" == \"kitty\" ]]","action":"omarchy-default-terminal kitty"},
"setup.default.editor": {"icon":"","label":"Editor","title":"Default Editor"}, "setup.default.editor": {"icon":"","label":"编辑器","title":"默认编辑器"},
"setup.default.editor.neovim": {"icon":"","label":"Neovim","checked":"[[ \"$(omarchy-default-editor)\" == \"nvim\" ]]","action":"omarchy-default-editor nvim"}, "setup.default.editor.neovim": {"icon":"","label":"Neovim","checked":"[[ \"$(omarchy-default-editor)\" == \"nvim\" ]]","action":"omarchy-default-editor nvim"},
"setup.default.editor.vscode": {"icon":"","label":"VSCode","checked":"[[ \"$(omarchy-default-editor)\" == \"code\" ]]","action":"omarchy-default-editor code"}, "setup.default.editor.vscode": {"icon":"","label":"VSCode","checked":"[[ \"$(omarchy-default-editor)\" == \"code\" ]]","action":"omarchy-default-editor code"},
"setup.default.editor.cursor": {"icon":"","label":"Cursor","checked":"[[ \"$(omarchy-default-editor)\" == \"cursor\" ]]","action":"omarchy-default-editor cursor"}, "setup.default.editor.cursor": {"icon":"","label":"Cursor","checked":"[[ \"$(omarchy-default-editor)\" == \"cursor\" ]]","action":"omarchy-default-editor cursor"},
@@ -167,49 +172,49 @@
"setup.default.editor.helix": {"icon":"","label":"Helix","checked":"[[ \"$(omarchy-default-editor)\" == \"helix\" ]]","action":"omarchy-default-editor helix"}, "setup.default.editor.helix": {"icon":"","label":"Helix","checked":"[[ \"$(omarchy-default-editor)\" == \"helix\" ]]","action":"omarchy-default-editor helix"},
"setup.default.editor.vim": {"icon":"","label":"Vim","checked":"[[ \"$(omarchy-default-editor)\" == \"vim\" ]]","action":"omarchy-default-editor vim"}, "setup.default.editor.vim": {"icon":"","label":"Vim","checked":"[[ \"$(omarchy-default-editor)\" == \"vim\" ]]","action":"omarchy-default-editor vim"},
"setup.default.editor.emacs": {"icon":"","label":"Emacs","checked":"[[ \"$(omarchy-default-editor)\" == \"emacs\" ]]","action":"omarchy-default-editor emacs"}, "setup.default.editor.emacs": {"icon":"","label":"Emacs","checked":"[[ \"$(omarchy-default-editor)\" == \"emacs\" ]]","action":"omarchy-default-editor emacs"},
"setup.plugin": {"icon":"󰐱","label":"Plugins","aliases":["plugin","plugins"]}, "setup.plugin": {"icon":"󰐱","label":"插件","aliases":["plugin","plugins"]},
"setup.plugin.enable": {"icon":"󰄬","label":"Enable Plugin","action":"omarchy-menu-plugin enable"}, "setup.plugin.enable": {"icon":"󰄬","label":"启用插件","action":"omarchy-menu-plugin enable"},
"setup.plugin.disable": {"icon":"󰅖","label":"Disable Plugin","action":"omarchy-menu-plugin disable"}, "setup.plugin.disable": {"icon":"󰅖","label":"停用插件","action":"omarchy-menu-plugin disable"},
"setup.plugin.add": {"icon":"󰖟","label":"Add Plugin","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-plugin-add'"}, "setup.plugin.add": {"icon":"󰖟","label":"添加插件","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-plugin-add'"},
"setup.plugin.clone": {"icon":"󰆏","label":"Clone Plugin","action":"omarchy-menu-plugin clone"}, "setup.plugin.clone": {"icon":"󰆏","label":"克隆插件","action":"omarchy-menu-plugin clone"},
"setup.plugin.remove": {"icon":"󰭌","label":"Remove Plugin","when":"compgen -G \"$HOME/.config/omarchy/plugins/*/manifest.json\"","action":"omarchy-menu-plugin remove"}, "setup.plugin.remove": {"icon":"󰭌","label":"移除插件","when":"compgen -G \"$HOME/.config/omarchy/plugins/*/manifest.json\"","action":"omarchy-menu-plugin remove"},
"setup.security": {"icon":"","label":"Security"}, "setup.security": {"icon":"","label":"安全"},
"setup.config": {"icon":"","label":"Config"}, "setup.config": {"icon":"","label":"配置"},
"setup.security.fingerprint": {"icon":"󰈷","label":"Fingerprint","when":"omarchy-hw-fingerprint","action":"omarchy-launch-floating-terminal-with-presentation omarchy-setup-security-fingerprint"}, "setup.security.fingerprint": {"icon":"󰈷","label":"指纹","when":"omarchy-hw-fingerprint","action":"omarchy-launch-floating-terminal-with-presentation omarchy-setup-security-fingerprint"},
"setup.security.fido2": {"icon":"","label":"Fido2","action":"omarchy-launch-floating-terminal-with-presentation omarchy-setup-security-fido2"}, "setup.security.fido2": {"icon":"","label":"Fido2","action":"omarchy-launch-floating-terminal-with-presentation omarchy-setup-security-fido2"},
"setup.security.sshd": {"icon":"󰣀","label":"SSHD","action":"omarchy-launch-floating-terminal-with-presentation omarchy-setup-security-sshd"}, "setup.security.sshd": {"icon":"󰣀","label":"SSHD","action":"omarchy-launch-floating-terminal-with-presentation omarchy-setup-security-sshd"},
"setup.security.passwordless-sudo": {"icon":"󰟵","label":"Passwordless Sudo","action":"omarchy-launch-floating-terminal-with-presentation omarchy-sudo-passwordless"}, "setup.security.passwordless-sudo": {"icon":"󰟵","label":"免密 sudo","action":"omarchy-launch-floating-terminal-with-presentation omarchy-sudo-passwordless"},
"setup.security.sudoless-docker": {"icon":"󰡨","label":"Sudoless Docker","when":"omarchy-sudo-docker --configured","action":"omarchy-launch-floating-terminal-with-presentation omarchy-setup-security-sudoless-docker"}, "setup.security.sudoless-docker": {"icon":"󰡨","label":"免 sudo Docker","when":"omarchy-sudo-docker --configured","action":"omarchy-launch-floating-terminal-with-presentation omarchy-setup-security-sudoless-docker"},
"setup.config.hyprland": {"icon":"","label":"Hyprland","action":"omarchy-launch-config-editor \"$HOME/.config/hypr/hyprland.lua\""}, "setup.config.hyprland": {"icon":"","label":"Hyprland","action":"omarchy-launch-config-editor \"$HOME/.config/hypr/hyprland.lua\""},
"setup.config.hyprsunset": {"icon":"","label":"Hyprsunset","action":"omarchy-launch-config-editor ~/.config/hypr/hyprsunset.conf && omarchy-restart-hyprsunset"}, "setup.config.hyprsunset": {"icon":"","label":"Hyprsunset","action":"omarchy-launch-config-editor ~/.config/hypr/hyprsunset.conf && omarchy-restart-hyprsunset"},
"setup.config.xcompose": {"icon":"󰞅","label":"XCompose","action":"omarchy-launch-config-editor ~/.XCompose && omarchy-restart-xcompose"}, "setup.config.xcompose": {"icon":"󰞅","label":"XCompose","action":"omarchy-launch-config-editor ~/.XCompose && omarchy-restart-xcompose"},
"setup.direct-boot": {"icon":"","label":"Direct Boot","action":"omarchy-launch-floating-terminal-with-presentation omarchy-setup-direct-boot"}, "setup.direct-boot": {"icon":"","label":"直接启动","action":"omarchy-launch-floating-terminal-with-presentation omarchy-setup-direct-boot"},
"setup.reset": {"icon":"󰑓","label":"Reset Computer","when":"[[ $(findmnt -no FSTYPE /) == btrfs ]]","action":"omarchy-launch-floating-terminal-with-presentation omarchy-system-factory-reset"}, "setup.reset": {"icon":"󰑓","label":"恢复出厂","when":"[[ $(findmnt -no FSTYPE /) == btrfs ]]","action":"omarchy-launch-floating-terminal-with-presentation omarchy-system-factory-reset"},
// Install // Install
"install.package": {"icon":"󰣇","label":"Package","action":"xdg-terminal-exec --app-id=org.omarchy.terminal omarchy-pkg-install"}, "install.package": {"icon":"󰣇","label":"软件包","action":"xdg-terminal-exec --app-id=org.omarchy.terminal omarchy-pkg-install"},
"install.aur": {"icon":"󰣇","label":"AUR","action":"xdg-terminal-exec --app-id=org.omarchy.terminal omarchy-pkg-aur-install"}, "install.aur": {"icon":"󰣇","label":"AUR","action":"xdg-terminal-exec --app-id=org.omarchy.terminal omarchy-pkg-aur-install"},
"install.ai": {"icon":"󱚤","label":"AI"}, "install.ai": {"icon":"󱚤","label":"AI"},
"install.service": {"icon":"","label":"Service"}, "install.service": {"icon":"","label":"服务"},
"install.development": {"icon":"󰵮","label":"Development"}, "install.development": {"icon":"󰵮","label":"开发环境"},
"install.editor": {"icon":"","label":"Editor"}, "install.editor": {"icon":"","label":"编辑器"},
"install.style": {"icon":"","label":"Style"}, "install.style": {"icon":"","label":"风格"},
"install.style.theme": {"icon":"󰸌","label":"Theme","action":"omarchy-launch-floating-terminal-with-presentation omarchy-theme-install"}, "install.style.theme": {"icon":"󰸌","label":"主题","action":"omarchy-launch-floating-terminal-with-presentation omarchy-theme-install"},
"install.style.background": {"icon":"","label":"Background","action":"omarchy-theme-bg-install"}, "install.style.background": {"icon":"","label":"壁纸","action":"omarchy-theme-bg-install"},
"install.style.font": {"icon":"","label":"Font"}, "install.style.font": {"icon":"","label":"字体"},
"install.style.font.cascadia": {"icon":"","label":"Cascadia Mono","action":"omarchy-install-font 'Cascadia Mono' ttf-cascadia-mono-nerd 'CaskaydiaMono Nerd Font'"}, "install.style.font.cascadia": {"icon":"","label":"Cascadia Mono","action":"omarchy-install-font 'Cascadia Mono' ttf-cascadia-mono-nerd 'CaskaydiaMono Nerd Font'"},
"install.style.font.meslo": {"icon":"","label":"Meslo LG Mono","action":"omarchy-install-font 'Meslo LG Mono' ttf-meslo-nerd 'MesloLGL Nerd Font'"}, "install.style.font.meslo": {"icon":"","label":"Meslo LG Mono","action":"omarchy-install-font 'Meslo LG Mono' ttf-meslo-nerd 'MesloLGL Nerd Font'"},
"install.style.font.fira": {"icon":"","label":"Fira Code","action":"omarchy-install-font 'Fira Code' ttf-firacode-nerd 'FiraCode Nerd Font'"}, "install.style.font.fira": {"icon":"","label":"Fira Code","action":"omarchy-install-font 'Fira Code' ttf-firacode-nerd 'FiraCode Nerd Font'"},
"install.style.font.victor": {"icon":"","label":"Victor Code","action":"omarchy-install-font 'Victor Code' ttf-victor-mono-nerd 'VictorMono Nerd Font'"}, "install.style.font.victor": {"icon":"","label":"Victor Code","action":"omarchy-install-font 'Victor Code' ttf-victor-mono-nerd 'VictorMono Nerd Font'"},
"install.style.font.bitstream": {"icon":"","label":"Bitstream Vera Mono","action":"omarchy-install-font 'Bitstream Vera Code' ttf-bitstream-vera-mono-nerd 'BitstromWera Nerd Font'"}, "install.style.font.bitstream": {"icon":"","label":"Bitstream Vera Mono","action":"omarchy-install-font 'Bitstream Vera Code' ttf-bitstream-vera-mono-nerd 'BitstromWera Nerd Font'"},
"install.style.font.iosevka": {"icon":"","label":"Iosevka","action":"omarchy-install-font Iosevka ttf-iosevka-nerd 'Iosevka Nerd Font Mono'"}, "install.style.font.iosevka": {"icon":"","label":"Iosevka","action":"omarchy-install-font Iosevka ttf-iosevka-nerd 'Iosevka Nerd Font Mono'"},
"install.gaming": {"icon":"","label":"Gaming"}, "install.gaming": {"icon":"","label":"游戏"},
"install.browser": {"icon":"","label":"Browser"}, "install.browser": {"icon":"","label":"浏览器"},
"install.webapp": {"icon":"","label":"Web App","action":"omarchy-launch-floating-terminal-with-presentation omarchy-webapp-install"}, "install.webapp": {"icon":"","label":"网页应用","action":"omarchy-launch-floating-terminal-with-presentation omarchy-webapp-install"},
"install.terminal": {"icon":"","label":"Terminal"}, "install.terminal": {"icon":"","label":"终端"},
"install.tui": {"icon":"","label":"TUI","action":"omarchy-launch-floating-terminal-with-presentation omarchy-tui-install"}, "install.tui": {"icon":"","label":"TUI","action":"omarchy-launch-floating-terminal-with-presentation omarchy-tui-install"},
"install.windows": {"icon":"󰍲","label":"Windows","disabled":"[[ -f $HOME/.local/share/applications/windows-vm.desktop ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-windows-vm install'"}, "install.windows": {"icon":"󰍲","label":"Windows","disabled":"[[ -f $HOME/.local/share/applications/windows-vm.desktop ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-windows-vm install'"},
"install.preinstalls": {"icon":"󰏓","label":"Preinstalls","disabled":"[[ ! -f $HOME/.local/state/omarchy/preinstalls-removed ]]","action":"omarchy-launch-floating-terminal-with-presentation omarchy-install-preinstalls"}, "install.preinstalls": {"icon":"󰏓","label":"预装应用","disabled":"[[ ! -f $HOME/.local/state/omarchy/preinstalls-removed ]]","action":"omarchy-launch-floating-terminal-with-presentation omarchy-install-preinstalls"},
"install.browser.chrome": {"icon":"","label":"Chrome","disabled":"omarchy-pkg-present google-chrome","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-install-browser chrome'"}, "install.browser.chrome": {"icon":"","label":"Chrome","disabled":"omarchy-pkg-present google-chrome","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-install-browser chrome'"},
"install.browser.edge": {"icon":"󰇩","label":"Edge","disabled":"omarchy-pkg-present microsoft-edge-stable-bin","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-install-browser edge'"}, "install.browser.edge": {"icon":"󰇩","label":"Edge","disabled":"omarchy-pkg-present microsoft-edge-stable-bin","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-install-browser edge'"},
"install.browser.brave": {"icon":"","label":"Brave","disabled":"omarchy-pkg-present brave-bin","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-install-browser brave'"}, "install.browser.brave": {"icon":"","label":"Brave","disabled":"omarchy-pkg-present brave-bin","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-install-browser brave'"},
@@ -224,7 +229,7 @@
"install.service.nordvpn": {"icon":"󱇱","label":"NordVPN","disabled":"omarchy-pkg-present nordvpn-bin","action":"omarchy-launch-floating-terminal-with-presentation omarchy-install-service-nordvpn"}, "install.service.nordvpn": {"icon":"󱇱","label":"NordVPN","disabled":"omarchy-pkg-present nordvpn-bin","action":"omarchy-launch-floating-terminal-with-presentation omarchy-install-service-nordvpn"},
"install.service.once": {"icon":"󰏖","label":"ONCE","disabled":"omarchy-pkg-present once-bin","action":"omarchy-launch-floating-terminal-with-presentation omarchy-install-service-once"}, "install.service.once": {"icon":"󰏖","label":"ONCE","disabled":"omarchy-pkg-present once-bin","action":"omarchy-launch-floating-terminal-with-presentation omarchy-install-service-once"},
"install.service.bitwarden": {"icon":"󰟵","label":"Bitwarden","disabled":"omarchy-pkg-present bitwarden","action":"omarchy-install-and-launch Bitwarden 'bitwarden bitwarden-cli' bitwarden"}, "install.service.bitwarden": {"icon":"󰟵","label":"Bitwarden","disabled":"omarchy-pkg-present bitwarden","action":"omarchy-install-and-launch Bitwarden 'bitwarden bitwarden-cli' bitwarden"},
"install.service.chromium-account": {"icon":"","label":"Chromium Account","when":"[[ -f ~/.config/chromium-flags.conf ]]","disabled":"grep -q oauth2-client-id ~/.config/chromium-flags.conf","action":"omarchy-launch-floating-terminal-with-presentation omarchy-install-chromium-google-account"}, "install.service.chromium-account": {"icon":"","label":"Chromium 账号","when":"[[ -f ~/.config/chromium-flags.conf ]]","disabled":"grep -q oauth2-client-id ~/.config/chromium-flags.conf","action":"omarchy-launch-floating-terminal-with-presentation omarchy-install-chromium-google-account"},
"install.editor.vscode": {"icon":"","label":"VSCode","disabled":"omarchy-pkg-present visual-studio-code-bin","action":"omarchy-launch-floating-terminal-with-presentation omarchy-install-editor-vscode"}, "install.editor.vscode": {"icon":"","label":"VSCode","disabled":"omarchy-pkg-present visual-studio-code-bin","action":"omarchy-launch-floating-terminal-with-presentation omarchy-install-editor-vscode"},
"install.editor.cursor": {"icon":"","label":"Cursor","disabled":"omarchy-pkg-present cursor-bin","action":"omarchy-install-and-launch Cursor cursor-bin cursor"}, "install.editor.cursor": {"icon":"","label":"Cursor","disabled":"omarchy-pkg-present cursor-bin","action":"omarchy-install-and-launch Cursor cursor-bin cursor"},
"install.editor.zed": {"icon":"","label":"Zed","disabled":"omarchy-pkg-present zed","action":"omarchy-launch-floating-terminal-with-presentation omarchy-install-editor-zed"}, "install.editor.zed": {"icon":"","label":"Zed","disabled":"omarchy-pkg-present zed","action":"omarchy-launch-floating-terminal-with-presentation omarchy-install-editor-zed"},
@@ -237,23 +242,28 @@
"install.terminal.ghostty": {"icon":"","label":"Ghostty","disabled":"omarchy-pkg-present ghostty","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-install-terminal ghostty'"}, "install.terminal.ghostty": {"icon":"","label":"Ghostty","disabled":"omarchy-pkg-present ghostty","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-install-terminal ghostty'"},
"install.terminal.kitty": {"icon":"","label":"Kitty","disabled":"omarchy-pkg-present kitty","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-install-terminal kitty'"}, "install.terminal.kitty": {"icon":"","label":"Kitty","disabled":"omarchy-pkg-present kitty","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-install-terminal kitty'"},
"install.ai.chatgpt": {"icon":"","iconFont":"omarchy","label":"ChatGPT Desktop","disabled":"omarchy-pkg-present openai-codex-desktop","action":"omarchy-launch-floating-terminal-with-presentation omarchy-install-ai-chatgpt"}, "install.ai.chatgpt": {"icon":"","iconFont":"omarchy","label":"ChatGPT Desktop","disabled":"omarchy-pkg-present openai-codex-desktop","action":"omarchy-launch-floating-terminal-with-presentation omarchy-install-ai-chatgpt"},
"install.ai.dictation": {"icon":"","label":"Dictation","disabled":"omarchy-pkg-present voxtype-bin","action":"omarchy-launch-floating-terminal-with-presentation omarchy-voxtype-install"}, "install.ai.deep-code": {"icon":"󱚤","label":"Deep Code","disabled":"omarchy-cmd-present deepcode","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-mise-install npm:@vegamo/deepcode-cli deepcode && deepcode'"},
"install.ai.dictation": {"icon":"","label":"语音听写","disabled":"omarchy-pkg-present voxtype-bin","action":"omarchy-launch-floating-terminal-with-presentation omarchy-voxtype-install"},
"install.ai.dim": {"icon":"󱚤","label":"Dim Agent","disabled":"omarchy-cmd-present dim","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-mise-install npm:dimcode dim && dim'"},
"install.ai.dsh": {"icon":"󱚤","label":"DSH","disabled":"omarchy-cmd-present dsh","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-mise-install npm:@deepseek-ai/dsh dsh && dsh web'"},
"install.ai.grok-bot": {"icon":"","iconFont":"omarchy","label":"Grok Bot","disabled":"omarchy-pkg-present grok-bot","action":"omarchy-install-and-launch 'Grok Bot' grok-bot grok-bot"}, "install.ai.grok-bot": {"icon":"","iconFont":"omarchy","label":"Grok Bot","disabled":"omarchy-pkg-present grok-bot","action":"omarchy-install-and-launch 'Grok Bot' grok-bot grok-bot"},
"install.ai.kimi-code": {"icon":"󱚤","label":"Kimi Code","disabled":"omarchy-cmd-present kimi","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-kimi-install && kimi'"},
"install.ai.lm-studio": {"icon":"","iconFont":"omarchy","label":"LM Studio","disabled":"omarchy-pkg-present lmstudio-bin","action":"omarchy-install-app 'LM Studio' lmstudio-bin"}, "install.ai.lm-studio": {"icon":"","iconFont":"omarchy","label":"LM Studio","disabled":"omarchy-pkg-present lmstudio-bin","action":"omarchy-install-app 'LM Studio' lmstudio-bin"},
"install.ai.ollama": {"icon":"","iconFont":"omarchy","label":"Ollama","disabled":"omarchy-cmd-present ollama","action":"if omarchy-cmd-present nvidia-smi; then ollama_pkg=ollama-cuda; elif omarchy-cmd-present rocminfo; then ollama_pkg=ollama-rocm; else ollama_pkg=ollama; fi; omarchy-install-app Ollama \"$ollama_pkg\""}, "install.ai.ollama": {"icon":"","iconFont":"omarchy","label":"Ollama","disabled":"omarchy-cmd-present ollama","action":"if omarchy-cmd-present nvidia-smi; then ollama_pkg=ollama-cuda; elif omarchy-cmd-present rocminfo; then ollama_pkg=ollama-rocm; else ollama_pkg=ollama; fi; omarchy-install-app Ollama \"$ollama_pkg\""},
"install.ai.t3-code": {"icon":"","iconFont":"omarchy","label":"T3 Code","disabled":"omarchy-pkg-present t3code-bin","action":"omarchy-install-and-launch 'T3 Code' t3code-bin t3code"}, "install.ai.t3-code": {"icon":"","iconFont":"omarchy","label":"T3 Code","disabled":"omarchy-pkg-present t3code-bin","action":"omarchy-install-and-launch 'T3 Code' t3code-bin t3code"},
"install.ai.cn-hub": {"icon":"󱚤","label":"国产模型组合 (AI Hub)","action":"omarchy-launch-floating-terminal-with-presentation omarchy-cn-ai-setup"},
"install.gaming.steam": {"icon":"","label":"Steam","disabled":"omarchy-pkg-present steam","action":"omarchy-launch-floating-terminal-with-presentation omarchy-install-gaming-steam"}, "install.gaming.steam": {"icon":"","label":"Steam","disabled":"omarchy-pkg-present steam","action":"omarchy-launch-floating-terminal-with-presentation omarchy-install-gaming-steam"},
"install.gaming.retroarch": {"icon":"󰯉","label":"RetroArch","disabled":"omarchy-pkg-present retroarch","action":"omarchy-launch-floating-terminal-with-presentation omarchy-install-gaming-retroarch"}, "install.gaming.retroarch": {"icon":"󰯉","label":"RetroArch","disabled":"omarchy-pkg-present retroarch","action":"omarchy-launch-floating-terminal-with-presentation omarchy-install-gaming-retroarch"},
"install.gaming.minecraft": {"icon":"󰍳","label":"Minecraft","disabled":"omarchy-pkg-present minecraft-launcher","action":"omarchy-install-and-launch Minecraft minecraft-launcher minecraft-launcher"}, "install.gaming.minecraft": {"icon":"󰍳","label":"Minecraft","disabled":"omarchy-pkg-present minecraft-launcher","action":"omarchy-install-and-launch Minecraft minecraft-launcher minecraft-launcher"},
"install.gaming.geforce-now": {"icon":"󰢹","label":"NVIDIA GeForce NOW","disabled":"flatpak info com.nvidia.geforcenow","action":"omarchy-launch-floating-terminal-with-presentation omarchy-install-gaming-geforce-now"}, "install.gaming.geforce-now": {"icon":"󰢹","label":"NVIDIA GeForce NOW","disabled":"flatpak info com.nvidia.geforcenow","action":"omarchy-launch-floating-terminal-with-presentation omarchy-install-gaming-geforce-now"},
"install.gaming.xbox-cloud": {"icon":"","label":"Xbox Cloud Gaming","disabled":"[[ -f \"$HOME/.local/share/applications/Xbox Cloud Gaming.desktop\" ]]","action":"omarchy-launch-floating-terminal-with-presentation omarchy-install-gaming-xbox-cloud"}, "install.gaming.xbox-cloud": {"icon":"","label":"Xbox 云游戏","disabled":"[[ -f \"$HOME/.local/share/applications/Xbox Cloud Gaming.desktop\" ]]","action":"omarchy-launch-floating-terminal-with-presentation omarchy-install-gaming-xbox-cloud"},
"install.gaming.xbox-controllers": {"icon":"󰂯","label":"Xbox Controllers","disabled":"omarchy-pkg-present xpadneo-dkms","action":"omarchy-launch-floating-terminal-with-presentation omarchy-install-gaming-xbox-controllers"}, "install.gaming.xbox-controllers": {"icon":"󰂯","label":"Xbox 手柄","disabled":"omarchy-pkg-present xpadneo-dkms","action":"omarchy-launch-floating-terminal-with-presentation omarchy-install-gaming-xbox-controllers"},
"install.gaming.battlenet": {"icon":"","label":"Battle.net","disabled":"[[ -d $HOME/Games/battlenet ]]","action":"omarchy-launch-floating-terminal-with-presentation omarchy-install-gaming-battlenet"}, "install.gaming.battlenet": {"icon":"","label":"Battle.net","disabled":"[[ -d $HOME/Games/battlenet ]]","action":"omarchy-launch-floating-terminal-with-presentation omarchy-install-gaming-battlenet"},
"install.gaming.lutris": {"icon":"","label":"Lutris","disabled":"omarchy-pkg-present lutris","action":"omarchy-launch-floating-terminal-with-presentation omarchy-install-gaming-lutris"}, "install.gaming.lutris": {"icon":"","label":"Lutris","disabled":"omarchy-pkg-present lutris","action":"omarchy-launch-floating-terminal-with-presentation omarchy-install-gaming-lutris"},
"install.gaming.heroic": {"icon":"󱓟","label":"Heroic (Epic Games)","disabled":"omarchy-pkg-present heroic-games-launcher-bin","action":"omarchy-launch-floating-terminal-with-presentation omarchy-install-gaming-heroic"}, "install.gaming.heroic": {"icon":"󱓟","label":"Heroic (Epic Games)","disabled":"omarchy-pkg-present heroic-games-launcher-bin","action":"omarchy-launch-floating-terminal-with-presentation omarchy-install-gaming-heroic"},
"install.gaming.retro-launcher": {"icon":"󰯉","label":"RetroArch Game Launcher","action":"omarchy-games-retro-install"}, "install.gaming.retro-launcher": {"icon":"󰯉","label":"RetroArch 启动器","action":"omarchy-games-retro-install"},
"install.development.rails": {"icon":"󰫏","label":"Ruby on Rails","disabled":"[[ -d $HOME/.local/share/mise/installs/ruby ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-install-dev-env ruby'"}, "install.development.rails": {"icon":"󰫏","label":"Ruby on Rails","disabled":"[[ -d $HOME/.local/share/mise/installs/ruby ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-install-dev-env ruby'"},
"install.development.docker-dbs": {"icon":"","label":"Docker DB","action":"omarchy-launch-floating-terminal-with-presentation omarchy-install-docker-dbs"}, "install.development.docker-dbs": {"icon":"","label":"Docker 数据库","action":"omarchy-launch-floating-terminal-with-presentation omarchy-install-docker-dbs"},
"install.development.javascript": {"icon":"","label":"JavaScript"}, "install.development.javascript": {"icon":"","label":"JavaScript"},
"install.development.go": {"icon":"","label":"Go","disabled":"[[ -d $HOME/.local/share/mise/installs/go ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-install-dev-env go'"}, "install.development.go": {"icon":"","label":"Go","disabled":"[[ -d $HOME/.local/share/mise/installs/go ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-install-dev-env go'"},
"install.development.php": {"icon":"","label":"PHP"}, "install.development.php": {"icon":"","label":"PHP"},
@@ -276,22 +286,22 @@
"install.development.elixir.phoenix": {"icon":"","label":"Phoenix","disabled":"compgen -G \"$HOME/.mix/archives/phx_new*\"","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-install-dev-env phoenix'"}, "install.development.elixir.phoenix": {"icon":"","label":"Phoenix","disabled":"compgen -G \"$HOME/.mix/archives/phx_new*\"","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-install-dev-env phoenix'"},
// Remove // Remove
"remove.package": {"icon":"󰣇","label":"Package","action":"xdg-terminal-exec --app-id=org.omarchy.terminal omarchy-pkg-remove"}, "remove.package": {"icon":"󰣇","label":"软件包","action":"xdg-terminal-exec --app-id=org.omarchy.terminal omarchy-pkg-remove"},
"remove.ai": {"icon":"󱚤","label":"AI","title":"Remove"}, "remove.ai": {"icon":"󱚤","label":"AI","title":"移除"},
"remove.service": {"icon":"","label":"Services","title":"Remove"}, "remove.service": {"icon":"","label":"服务","title":"移除"},
"remove.development": {"icon":"󰵮","label":"Development","title":"Remove"}, "remove.development": {"icon":"󰵮","label":"开发环境","title":"移除"},
"remove.theme": {"icon":"󰸌","label":"Theme","action":"omarchy-theme-remove"}, "remove.theme": {"icon":"󰸌","label":"主题","action":"omarchy-theme-remove"},
"remove.gaming": {"icon":"","label":"Gaming","title":"Remove"}, "remove.gaming": {"icon":"","label":"游戏","title":"移除"},
"remove.browser": {"icon":"","label":"Browser","title":"Remove"}, "remove.browser": {"icon":"","label":"浏览器","title":"移除"},
"remove.webapp": {"icon":"","label":"Web App","when":"grep -qE '^Exec=.*(omarchy-launch-webapp|omarchy-webapp-handler)' $HOME/.local/share/applications/*.desktop","action":"omarchy-webapp-remove"}, "remove.webapp": {"icon":"","label":"网页应用","when":"grep -qE '^Exec=.*(omarchy-launch-webapp|omarchy-webapp-handler)' $HOME/.local/share/applications/*.desktop","action":"omarchy-webapp-remove"},
"remove.tui": {"icon":"","label":"TUI","when":"grep -qE '^Exec=.*(\\$TERMINAL|xdg-terminal-exec).*-e' $HOME/.local/share/applications/*.desktop","action":"omarchy-tui-remove"}, "remove.tui": {"icon":"","label":"TUI","when":"grep -qE '^Exec=.*(\\$TERMINAL|xdg-terminal-exec).*-e' $HOME/.local/share/applications/*.desktop","action":"omarchy-tui-remove"},
"remove.windows": {"icon":"󰍲","label":"Windows","when":"[[ -f $HOME/.local/share/applications/windows-vm.desktop ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-windows-vm remove'"}, "remove.windows": {"icon":"󰍲","label":"Windows","when":"[[ -f $HOME/.local/share/applications/windows-vm.desktop ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-windows-vm remove'"},
"remove.preinstalls": {"icon":"󰏓","label":"Preinstalls","when":"[[ ! -f $HOME/.local/state/omarchy/preinstalls-removed ]]","action":"omarchy-launch-floating-terminal-with-presentation omarchy-remove-preinstalls"}, "remove.preinstalls": {"icon":"󰏓","label":"预装应用","when":"[[ ! -f $HOME/.local/state/omarchy/preinstalls-removed ]]","action":"omarchy-launch-floating-terminal-with-presentation omarchy-remove-preinstalls"},
"remove.security": {"icon":"","label":"Security","title":"Remove"}, "remove.security": {"icon":"","label":"安全","title":"移除"},
"remove.security.fingerprint": {"icon":"󰈷","label":"Fingerprint","when":"omarchy-pkg-present fprintd","action":"omarchy-launch-floating-terminal-with-presentation omarchy-remove-security-fingerprint"}, "remove.security.fingerprint": {"icon":"󰈷","label":"指纹","when":"omarchy-pkg-present fprintd","action":"omarchy-launch-floating-terminal-with-presentation omarchy-remove-security-fingerprint"},
"remove.security.fido2": {"icon":"","label":"Fido2","when":"omarchy-pkg-present pam-u2f","action":"omarchy-launch-floating-terminal-with-presentation omarchy-remove-security-fido2"}, "remove.security.fido2": {"icon":"","label":"Fido2","when":"omarchy-pkg-present pam-u2f","action":"omarchy-launch-floating-terminal-with-presentation omarchy-remove-security-fido2"},
"remove.security.sshd": {"icon":"󰣀","label":"SSHD","when":"systemctl is-enabled --quiet sshd","action":"omarchy-launch-floating-terminal-with-presentation omarchy-remove-security-sshd"}, "remove.security.sshd": {"icon":"󰣀","label":"SSHD","when":"systemctl is-enabled --quiet sshd","action":"omarchy-launch-floating-terminal-with-presentation omarchy-remove-security-sshd"},
"remove.security.sudoless-docker": {"icon":"󰡨","label":"Sudoless Docker","when":"! omarchy-sudo-docker --configured","action":"omarchy-launch-floating-terminal-with-presentation omarchy-remove-security-sudoless-docker"}, "remove.security.sudoless-docker": {"icon":"󰡨","label":"免 sudo Docker","when":"! omarchy-sudo-docker --configured","action":"omarchy-launch-floating-terminal-with-presentation omarchy-remove-security-sudoless-docker"},
"remove.browser.chrome": {"icon":"","label":"Chrome","when":"omarchy-pkg-present google-chrome","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-remove-browser chrome'"}, "remove.browser.chrome": {"icon":"","label":"Chrome","when":"omarchy-pkg-present google-chrome","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-remove-browser chrome'"},
"remove.browser.edge": {"icon":"󰇩","label":"Edge","when":"omarchy-pkg-present microsoft-edge-stable-bin","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-remove-browser edge'"}, "remove.browser.edge": {"icon":"󰇩","label":"Edge","when":"omarchy-pkg-present microsoft-edge-stable-bin","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-remove-browser edge'"},
"remove.browser.brave": {"icon":"","label":"Brave","when":"omarchy-pkg-present brave-bin","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-remove-browser brave'"}, "remove.browser.brave": {"icon":"","label":"Brave","when":"omarchy-pkg-present brave-bin","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-remove-browser brave'"},
@@ -301,7 +311,7 @@
"remove.service.dropbox": {"icon":"","label":"Dropbox","when":"omarchy-pkg-present dropbox","action":"omarchy-launch-floating-terminal-with-presentation omarchy-remove-service-dropbox"}, "remove.service.dropbox": {"icon":"","label":"Dropbox","when":"omarchy-pkg-present dropbox","action":"omarchy-launch-floating-terminal-with-presentation omarchy-remove-service-dropbox"},
"remove.service.tailscale": {"icon":"","label":"Tailscale","when":"omarchy-pkg-present tailscale","action":"omarchy-launch-floating-terminal-with-presentation omarchy-remove-service-tailscale"}, "remove.service.tailscale": {"icon":"","label":"Tailscale","when":"omarchy-pkg-present tailscale","action":"omarchy-launch-floating-terminal-with-presentation omarchy-remove-service-tailscale"},
"remove.ai.chatgpt": {"icon":"","iconFont":"omarchy","label":"ChatGPT Desktop","when":"omarchy-pkg-present openai-codex-desktop","action":"omarchy-launch-floating-terminal-with-presentation omarchy-remove-ai-chatgpt"}, "remove.ai.chatgpt": {"icon":"","iconFont":"omarchy","label":"ChatGPT Desktop","when":"omarchy-pkg-present openai-codex-desktop","action":"omarchy-launch-floating-terminal-with-presentation omarchy-remove-ai-chatgpt"},
"remove.ai.dictation": {"icon":"","label":"Dictation","when":"omarchy-pkg-present voxtype-bin","action":"omarchy-launch-floating-terminal-with-presentation omarchy-voxtype-remove"}, "remove.ai.dictation": {"icon":"","label":"语音听写","when":"omarchy-pkg-present voxtype-bin","action":"omarchy-launch-floating-terminal-with-presentation omarchy-voxtype-remove"},
"remove.ai.grok-bot": {"icon":"","iconFont":"omarchy","label":"Grok Bot","when":"omarchy-pkg-present grok-bot","action":"omarchy-launch-floating-terminal-with-presentation omarchy-remove-ai-grok-bot"}, "remove.ai.grok-bot": {"icon":"","iconFont":"omarchy","label":"Grok Bot","when":"omarchy-pkg-present grok-bot","action":"omarchy-launch-floating-terminal-with-presentation omarchy-remove-ai-grok-bot"},
"remove.ai.lm-studio": {"icon":"","iconFont":"omarchy","label":"LM Studio","when":"omarchy-pkg-present lmstudio-bin","action":"omarchy-launch-floating-terminal-with-presentation omarchy-remove-ai-lm-studio"}, "remove.ai.lm-studio": {"icon":"","iconFont":"omarchy","label":"LM Studio","when":"omarchy-pkg-present lmstudio-bin","action":"omarchy-launch-floating-terminal-with-presentation omarchy-remove-ai-lm-studio"},
"remove.ai.ollama": {"icon":"","iconFont":"omarchy","label":"Ollama","when":"omarchy-pkg-present ollama","action":"omarchy-launch-floating-terminal-with-presentation omarchy-remove-ai-ollama"}, "remove.ai.ollama": {"icon":"","iconFont":"omarchy","label":"Ollama","when":"omarchy-pkg-present ollama","action":"omarchy-launch-floating-terminal-with-presentation omarchy-remove-ai-ollama"},
@@ -310,17 +320,17 @@
"remove.gaming.retroarch": {"icon":"","label":"RetroArch","when":"omarchy-pkg-present retroarch","action":"omarchy-launch-floating-terminal-with-presentation omarchy-remove-gaming-retroarch"}, "remove.gaming.retroarch": {"icon":"","label":"RetroArch","when":"omarchy-pkg-present retroarch","action":"omarchy-launch-floating-terminal-with-presentation omarchy-remove-gaming-retroarch"},
"remove.gaming.minecraft": {"icon":"󰍳","label":"Minecraft","when":"omarchy-pkg-present minecraft-launcher","action":"omarchy-launch-floating-terminal-with-presentation omarchy-remove-gaming-minecraft"}, "remove.gaming.minecraft": {"icon":"󰍳","label":"Minecraft","when":"omarchy-pkg-present minecraft-launcher","action":"omarchy-launch-floating-terminal-with-presentation omarchy-remove-gaming-minecraft"},
"remove.gaming.geforce-now": {"icon":"󰢹","label":"NVIDIA GeForce NOW","when":"flatpak info com.nvidia.geforcenow","action":"omarchy-launch-floating-terminal-with-presentation omarchy-remove-gaming-geforce-now"}, "remove.gaming.geforce-now": {"icon":"󰢹","label":"NVIDIA GeForce NOW","when":"flatpak info com.nvidia.geforcenow","action":"omarchy-launch-floating-terminal-with-presentation omarchy-remove-gaming-geforce-now"},
"remove.gaming.xbox-cloud": {"icon":"","label":"Xbox Cloud Gaming","when":"[[ -f \"$HOME/.local/share/applications/Xbox Cloud Gaming.desktop\" ]]","action":"omarchy-launch-floating-terminal-with-presentation omarchy-remove-gaming-xbox-cloud"}, "remove.gaming.xbox-cloud": {"icon":"","label":"Xbox 云游戏","when":"[[ -f \"$HOME/.local/share/applications/Xbox Cloud Gaming.desktop\" ]]","action":"omarchy-launch-floating-terminal-with-presentation omarchy-remove-gaming-xbox-cloud"},
"remove.gaming.xbox-controllers": {"icon":"󰖺","label":"Xbox Controllers (󰂯)","when":"omarchy-pkg-present xpadneo-dkms","action":"omarchy-launch-floating-terminal-with-presentation omarchy-remove-gaming-xbox-controllers"}, "remove.gaming.xbox-controllers": {"icon":"󰖺","label":"Xbox 手柄 (󰂯)","when":"omarchy-pkg-present xpadneo-dkms","action":"omarchy-launch-floating-terminal-with-presentation omarchy-remove-gaming-xbox-controllers"},
"remove.gaming.battlenet": {"icon":"","label":"Battle.net","when":"[[ -d $HOME/Games/battlenet ]]","action":"omarchy-launch-floating-terminal-with-presentation omarchy-remove-gaming-battlenet"}, "remove.gaming.battlenet": {"icon":"","label":"Battle.net","when":"[[ -d $HOME/Games/battlenet ]]","action":"omarchy-launch-floating-terminal-with-presentation omarchy-remove-gaming-battlenet"},
"remove.gaming.lutris": {"icon":"","label":"Lutris","when":"omarchy-pkg-present lutris","action":"omarchy-launch-floating-terminal-with-presentation omarchy-remove-gaming-lutris"}, "remove.gaming.lutris": {"icon":"","label":"Lutris","when":"omarchy-pkg-present lutris","action":"omarchy-launch-floating-terminal-with-presentation omarchy-remove-gaming-lutris"},
"remove.gaming.heroic": {"icon":"󱓟","label":"Heroic (Epic Games)","when":"omarchy-pkg-present heroic-games-launcher-bin","action":"omarchy-launch-floating-terminal-with-presentation omarchy-remove-gaming-heroic"}, "remove.gaming.heroic": {"icon":"󱓟","label":"Heroic (Epic Games)","when":"omarchy-pkg-present heroic-games-launcher-bin","action":"omarchy-launch-floating-terminal-with-presentation omarchy-remove-gaming-heroic"},
"remove.development.rails": {"icon":"󰫏","label":"Ruby on Rails","when":"[[ -d $HOME/.local/share/mise/installs/ruby ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-remove-dev-env ruby'"}, "remove.development.rails": {"icon":"󰫏","label":"Ruby on Rails","when":"[[ -d $HOME/.local/share/mise/installs/ruby ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-remove-dev-env ruby'"},
"remove.development.javascript": {"icon":"","label":"JavaScript","title":"Remove"}, "remove.development.javascript": {"icon":"","label":"JavaScript","title":"移除"},
"remove.development.go": {"icon":"","label":"Go","when":"[[ -d $HOME/.local/share/mise/installs/go ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-remove-dev-env go'"}, "remove.development.go": {"icon":"","label":"Go","when":"[[ -d $HOME/.local/share/mise/installs/go ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-remove-dev-env go'"},
"remove.development.php": {"icon":"","label":"PHP","title":"Remove"}, "remove.development.php": {"icon":"","label":"PHP","title":"移除"},
"remove.development.python": {"icon":"","label":"Python","when":"[[ -d $HOME/.local/share/mise/installs/python ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-remove-dev-env python'"}, "remove.development.python": {"icon":"","label":"Python","when":"[[ -d $HOME/.local/share/mise/installs/python ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-remove-dev-env python'"},
"remove.development.elixir": {"icon":"","label":"Elixir","title":"Remove"}, "remove.development.elixir": {"icon":"","label":"Elixir","title":"移除"},
"remove.development.zig": {"icon":"","label":"Zig","when":"[[ -d $HOME/.local/share/mise/installs/zig ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-remove-dev-env zig'"}, "remove.development.zig": {"icon":"","label":"Zig","when":"[[ -d $HOME/.local/share/mise/installs/zig ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-remove-dev-env zig'"},
"remove.development.rust": {"icon":"","label":"Rust","when":"[[ -d $HOME/.rustup ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-remove-dev-env rust'"}, "remove.development.rust": {"icon":"","label":"Rust","when":"[[ -d $HOME/.rustup ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-remove-dev-env rust'"},
"remove.development.java": {"icon":"","label":"Java","when":"[[ -d $HOME/.local/share/mise/installs/java ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-remove-dev-env java'"}, "remove.development.java": {"icon":"","label":"Java","when":"[[ -d $HOME/.local/share/mise/installs/java ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-remove-dev-env java'"},
@@ -339,16 +349,16 @@
// Update // Update
"update.omarchy": {"icon":"","iconFont":"omarchy","label":"Omarchy","action":"omarchy-launch-floating-terminal-with-presentation omarchy-update"}, "update.omarchy": {"icon":"","iconFont":"omarchy","label":"Omarchy","action":"omarchy-launch-floating-terminal-with-presentation omarchy-update"},
"update.channel": {"icon":"󰔫","label":"Channel"}, "update.channel": {"icon":"󰔫","label":"通道"},
"update.config": {"icon":"","label":"Config","title":"Reset to default"}, "update.config": {"icon":"","label":"配置","title":"重置为默认"},
"update.themes": {"icon":"󰸌","label":"Extra Themes","when":"omarchy-theme-extras","action":"omarchy-launch-floating-terminal-with-presentation omarchy-theme-update"}, "update.themes": {"icon":"󰸌","label":"附加主题","when":"omarchy-theme-extras","action":"omarchy-launch-floating-terminal-with-presentation omarchy-theme-update"},
"update.process": {"icon":"","label":"Process","title":"Restart"}, "update.process": {"icon":"","label":"进程","title":"重启"},
"update.hardware": {"icon":"󰇅","label":"Hardware","title":"Restart"}, "update.hardware": {"icon":"󰇅","label":"硬件","title":"重启"},
"update.firmware": {"icon":"","label":"Firmware","action":"omarchy-launch-floating-terminal-with-presentation omarchy-update-firmware"}, "update.firmware": {"icon":"","label":"固件","action":"omarchy-launch-floating-terminal-with-presentation omarchy-update-firmware"},
"update.password": {"icon":"","label":"Password"}, "update.password": {"icon":"","label":"密码"},
"update.timezone": {"icon":"","label":"Timezone","action":"omarchy-menu-timezone"}, "update.timezone": {"icon":"","label":"时区","action":"omarchy-menu-timezone"},
"update.time": {"icon":"","label":"Time","action":"omarchy-launch-floating-terminal-with-presentation omarchy-update-time"}, "update.time": {"icon":"","label":"时间","action":"omarchy-launch-floating-terminal-with-presentation omarchy-update-time"},
"update.channel.stable": {"icon":"🟢","label":"Stable","checked":"[[ \"$(omarchy-channel-current)\" == \"stable\" ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-channel-set stable'"}, "update.channel.stable": {"icon":"🟢","label":"稳定 Stable","checked":"[[ \"$(omarchy-channel-current)\" == \"stable\" ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-channel-set stable'"},
"update.channel.rc": {"icon":"🟡","label":"RC","checked":"[[ \"$(omarchy-channel-current)\" == \"rc\" ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-channel-set rc'"}, "update.channel.rc": {"icon":"🟡","label":"RC","checked":"[[ \"$(omarchy-channel-current)\" == \"rc\" ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-channel-set rc'"},
"update.channel.edge": {"icon":"🟠","label":"Edge","checked":"[[ \"$(omarchy-channel-current)\" == \"edge\" ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-channel-set edge'"}, "update.channel.edge": {"icon":"🟠","label":"Edge","checked":"[[ \"$(omarchy-channel-current)\" == \"edge\" ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-channel-set edge'"},
"update.channel.dev": {"icon":"🔴","label":"Dev","checked":"[[ \"$(omarchy-channel-current)\" == \"dev\" ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-channel-set dev'"}, "update.channel.dev": {"icon":"🔴","label":"Dev","checked":"[[ \"$(omarchy-channel-current)\" == \"dev\" ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-channel-set dev'"},
@@ -359,39 +369,54 @@
"update.config.plymouth": {"icon":"󱣴","label":"Plymouth","action":"omarchy-launch-floating-terminal-with-presentation omarchy-refresh-plymouth"}, "update.config.plymouth": {"icon":"󱣴","label":"Plymouth","action":"omarchy-launch-floating-terminal-with-presentation omarchy-refresh-plymouth"},
"update.config.tmux": {"icon":"","label":"Tmux","action":"omarchy-launch-floating-terminal-with-presentation omarchy-refresh-tmux"}, "update.config.tmux": {"icon":"","label":"Tmux","action":"omarchy-launch-floating-terminal-with-presentation omarchy-refresh-tmux"},
"update.config.shell": {"icon":"󰍜","label":"Shell","action":"omarchy-launch-floating-terminal-with-presentation omarchy-refresh-shell"}, "update.config.shell": {"icon":"󰍜","label":"Shell","action":"omarchy-launch-floating-terminal-with-presentation omarchy-refresh-shell"},
"update.hardware.audio": {"icon":"","label":"Audio","action":"omarchy-launch-floating-terminal-with-presentation omarchy-restart-audio"}, "update.hardware.audio": {"icon":"","label":"音频","action":"omarchy-launch-floating-terminal-with-presentation omarchy-restart-audio"},
"update.hardware.wifi": {"icon":"󱚾","label":"Wi-Fi","action":"omarchy-launch-floating-terminal-with-presentation omarchy-restart-wifi"}, "update.hardware.wifi": {"icon":"󱚾","label":"Wi-Fi","action":"omarchy-launch-floating-terminal-with-presentation omarchy-restart-wifi"},
"update.hardware.bluetooth": {"icon":"󰂯","label":"Bluetooth","action":"omarchy-launch-floating-terminal-with-presentation omarchy-restart-bluetooth"}, "update.hardware.bluetooth": {"icon":"󰂯","label":"蓝牙","action":"omarchy-launch-floating-terminal-with-presentation omarchy-restart-bluetooth"},
"update.hardware.trackpad": {"icon":"󰟸","label":"Trackpad","action":"omarchy-launch-floating-terminal-with-presentation omarchy-restart-trackpad"}, "update.hardware.trackpad": {"icon":"󰟸","label":"触控板","action":"omarchy-launch-floating-terminal-with-presentation omarchy-restart-trackpad"},
"update.password.drive": {"icon":"","label":"Drive Encryption","action":"omarchy-launch-floating-terminal-with-presentation omarchy-drive-password"}, "update.password.drive": {"icon":"","label":"磁盘加密","action":"omarchy-launch-floating-terminal-with-presentation omarchy-drive-password"},
"update.password.user": {"icon":"","label":"User","action":"omarchy-launch-floating-terminal-with-presentation passwd"}, "update.password.user": {"icon":"","label":"用户","action":"omarchy-launch-floating-terminal-with-presentation passwd"},
// OmarchyCN // OmarchyCN
"omarchycn": {"icon":"","label":"OmarchyCN"}, "omarchycn": {"icon":"","label":"OmarchyCN"},
"omarchycn.mirrors": {"icon":"󰇧","label":"镜像 Mirrors"}, "omarchycn.ai": {"icon":"󱚤","label":"AI Hub"},
"omarchycn.mirrors.china": {"icon":"","label":"中国镜像 China","checked":"[[ \"$(cat ~/.config/omarchycn/mirror-profile 2>/dev/null)\" == china ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-mirror-apply china'"}, "omarchycn.ai.setup": {"icon":"","label":"配置向导","action":"omarchy-launch-floating-terminal-with-presentation omarchy-cn-ai-setup"},
"omarchycn.mirrors.official": {"icon":"󰇩","label":"官方镜像 Official","checked":"[[ \"$(cat ~/.config/omarchycn/mirror-profile 2>/dev/null)\" == official ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-mirror-apply official'"}, "omarchycn.ai.profiles": {"icon":"","label":"配置列表","action":"omarchy-launch-floating-terminal-with-presentation omarchy-cn-ai-profile-list"},
"omarchycn.mirrors.benchmark": {"icon":"󰓅","label":"测速 Benchmark","action":"omarchy-launch-floating-terminal-with-presentation omarchy-cn-mirror-benchmark"}, "omarchycn.ai.test": {"icon":"󰙨","label":"连接测试","action":"omarchy-launch-floating-terminal-with-presentation omarchy-cn-ai-test"},
"omarchycn.mirrors.dev-china": {"icon":"","label":"开发工具国内源 Dev China","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-dev-mirror-apply china'"}, "omarchycn.ai.doctor": {"icon":"󰨮","label":"AI 诊断","action":"omarchy-launch-floating-terminal-with-presentation omarchy-cn-ai-doctor"},
"omarchycn.mirrors.dev-official": {"icon":"","label":"开发工具官方源 Dev Official","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-dev-mirror-apply official'"}, "omarchycn.apps": {"icon":"󰀻","label":"国内应用"},
"omarchycn.mirrors.restore": {"icon":"󰦛","label":"恢复 Restore","action":"omarchy-launch-floating-terminal-with-presentation omarchy-cn-mirror-restore"}, "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.chinese": {"icon":"󰗊","label":"中文环境 Chinese"}, "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.dingtalk": {"icon":"","label":"钉钉","disabled":"omarchy-pkg-present dingtalk-bin","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-app-install dingtalk'"},
"omarchycn.apps.wemeet": {"icon":"","label":"腾讯会议","disabled":"omarchy-pkg-present wemeet-bin","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-app-install wemeet'"},
"omarchycn.apps.wps": {"icon":"","label":"WPS Office","disabled":"omarchy-pkg-present wps-office-cn","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-app-install wps'"},
"omarchycn.apps.tencent-docs": {"icon":"","label":"腾讯文档","disabled":"[[ -f \"$HOME/.local/share/applications/腾讯文档.desktop\" ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-app-install tencent-docs'"},
"omarchycn.apps.yuque": {"icon":"","label":"语雀","disabled":"[[ -f \"$HOME/.local/share/applications/语雀.desktop\" ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-app-install yuque'"},
"omarchycn.apps.shimo": {"icon":"","label":"石墨文档","disabled":"[[ -f \"$HOME/.local/share/applications/石墨文档.desktop\" ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-app-install shimo'"},
"omarchycn.mirrors": {"icon":"󰇧","label":"镜像源"},
"omarchycn.mirrors.china": {"icon":"","label":"中国镜像","checked":"[[ \"$(cat ~/.config/omarchycn/mirror-profile 2>/dev/null)\" == china ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-mirror-apply china'"},
"omarchycn.mirrors.official": {"icon":"󰇩","label":"官方镜像","checked":"[[ \"$(cat ~/.config/omarchycn/mirror-profile 2>/dev/null)\" == official ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-mirror-apply official'"},
"omarchycn.mirrors.benchmark": {"icon":"󰓅","label":"测速","action":"omarchy-launch-floating-terminal-with-presentation omarchy-cn-mirror-benchmark"},
"omarchycn.mirrors.dev-china": {"icon":"","label":"开发工具国内源","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-dev-mirror-apply china'"},
"omarchycn.mirrors.dev-official": {"icon":"","label":"开发工具官方源","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-dev-mirror-apply official'"},
"omarchycn.mirrors.restore": {"icon":"󰦛","label":"恢复","action":"omarchy-launch-floating-terminal-with-presentation omarchy-cn-mirror-restore"},
"omarchycn.chinese": {"icon":"󰗊","label":"中文环境"},
"omarchycn.chinese.ime": {"icon":"󰌌","label":"输入法 Fcitx5+Rime","action":"omarchy-launch-floating-terminal-with-presentation omarchy-cn-ime-apply"}, "omarchycn.chinese.ime": {"icon":"󰌌","label":"输入法 Fcitx5+Rime","action":"omarchy-launch-floating-terminal-with-presentation omarchy-cn-ime-apply"},
"omarchycn.chinese.hotkey-ctrl": {"icon":"󰌏","label":"切换键 Ctrl+Space","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-ime-hotkey ctrl-space'"}, "omarchycn.chinese.hotkey-ctrl": {"icon":"󰌏","label":"切换键 Ctrl+Space","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-ime-hotkey ctrl-space'"},
"omarchycn.chinese.hotkey-super": {"icon":"󰌏","label":"切换键 Super+Space","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-ime-hotkey super-space'"}, "omarchycn.chinese.hotkey-super": {"icon":"󰌏","label":"切换键 Super+Space","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-ime-hotkey super-space'"},
"omarchycn.chinese.fonts": {"icon":"","label":"中文字体 Fonts","action":"omarchy-launch-floating-terminal-with-presentation omarchy-cn-font-apply"}, "omarchycn.chinese.fonts": {"icon":"","label":"中文字体","action":"omarchy-launch-floating-terminal-with-presentation omarchy-cn-font-apply"},
"omarchycn.chinese.locale": {"icon":"","label":"中文 Locale","action":"omarchy-launch-floating-terminal-with-presentation omarchy-cn-locale-apply"}, "omarchycn.chinese.locale": {"icon":"","label":"中文 Locale","action":"omarchy-launch-floating-terminal-with-presentation omarchy-cn-locale-apply"},
"omarchycn.display": {"icon":"󰍹","label":"显示缩放 Scale"}, "omarchycn.display": {"icon":"󰍹","label":"显示缩放"},
"omarchycn.display.s10": {"icon":"󰍹","label":"1.0","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-display-scale 1.0'"}, "omarchycn.display.s10": {"icon":"󰍹","label":"1.0","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-display-scale 1.0'"},
"omarchycn.display.s125": {"icon":"󰍹","label":"1.25","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-display-scale 1.25'"}, "omarchycn.display.s125": {"icon":"󰍹","label":"1.25","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-display-scale 1.25'"},
"omarchycn.display.s15": {"icon":"󰍹","label":"1.5","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-display-scale 1.5'"}, "omarchycn.display.s15": {"icon":"󰍹","label":"1.5","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-display-scale 1.5'"},
"omarchycn.display.s16": {"icon":"󰍹","label":"1.6","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-display-scale 1.6'"}, "omarchycn.display.s16": {"icon":"󰍹","label":"1.6","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-display-scale 1.6'"},
"omarchycn.display.s175": {"icon":"󰍹","label":"1.75","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-display-scale 1.75'"}, "omarchycn.display.s175": {"icon":"󰍹","label":"1.75","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-display-scale 1.75'"},
"omarchycn.display.s20": {"icon":"󰍹","label":"2.0","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-display-scale 2.0'"}, "omarchycn.display.s20": {"icon":"󰍹","label":"2.0","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-display-scale 2.0'"},
"omarchycn.diagnostics": {"icon":"󰨮","label":"诊断 Diagnostics"}, "omarchycn.diagnostics": {"icon":"󰨮","label":"诊断"},
"omarchycn.diagnostics.doctor": {"icon":"󰨮","label":"System Doctor","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":"镜像修复 Mirror Fix","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":"输入法状态 IME Status","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":"更新 Update","when":"[[ -f ~/.local/state/omarchycn/overlay-manifest ]]","action":"omarchy-launch-floating-terminal-with-presentation omarchy-cn-update"}, "omarchycn.update": {"icon":"","label":"更新","when":"[[ -f ~/.local/state/omarchycn/overlay-manifest ]]","action":"omarchy-launch-floating-terminal-with-presentation omarchy-cn-update"},
"omarchycn.about": {"icon":"","label":"关于 About","action":"omarchy-launch-floating-terminal-with-presentation omarchy-cn-status"}, "omarchycn.about": {"icon":"","label":"关于","action":"omarchy-launch-floating-terminal-with-presentation omarchy-cn-status"},
} }
+2
View File
@@ -27,4 +27,6 @@ Include = /etc/pacman.d/mirrorlist
[omarchy] [omarchy]
SigLevel = Optional TrustAll SigLevel = Optional TrustAll
# OmarchyCN mirror first (registry-signed db, key via cn/keys), upstream fallback
Server = https://git.zacharyzhang.com/api/packages/ZacharyZhang-NY/arch/omarchy/x86_64
Server = https://pkgs.omarchy.org/stable/$arch Server = https://pkgs.omarchy.org/stable/$arch
+1 -2
View File
@@ -207,8 +207,7 @@ It only does the things `/etc/skel` can't:
and `~/.config/gtk-3.0/bookmarks` (needs `$HOME` expansion). and `~/.config/gtk-3.0/bookmarks` (needs `$HOME` expansion).
- Hyprland's package-owned default input reads `XKBLAYOUT` / `XKBVARIANT` - Hyprland's package-owned default input reads `XKBLAYOUT` / `XKBVARIANT`
from `/etc/vconsole.conf`; no per-user Hyprland config rewrite is needed. from `/etc/vconsole.conf`; no per-user Hyprland config rewrite is needed.
- `xdg-settings set default-web-browser chromium.desktop` and - `xdg-settings set default-web-browser chromium.desktop` (XDG-aware path).
`xdg-mime default HEY.desktop x-scheme-handler/mailto` (XDG-aware paths).
- `omarchy-refresh-applications` (composes generated `.desktop` launchers). - `omarchy-refresh-applications` (composes generated `.desktop` launchers).
- Sources `install/user/all.sh` — theme, chromium, git, xcompose, mise, - Sources `install/user/all.sh` — theme, chromium, git, xcompose, mise,
keyring, per-user hardware quirks (asus mic/mixer, framework f13 audio, …). keyring, per-user hardware quirks (asus mic/mixer, framework f13 audio, …).
+10
View File
@@ -3,6 +3,16 @@
OmarchyCN 的 pacman 仓库托管在 Gitea Arch package registry,每个上传的包由 OmarchyCN 的 pacman 仓库托管在 Gitea Arch package registry,每个上传的包由
registry 密钥自动签名,数据库同源生成。 registry 密钥自动签名,数据库同源生成。
# [omarchy] 上游仓库镜像
上游 `pkgs.omarchy.org`Cloudflare 托管)的 stable 通道被完整镜像到同一 Gitea registry 的 `omarchy` 仓库。`packages/sync-omarchy-repo.sh` 按文件名对上游与镜像 db 做差集,缺失包转传、上游移除的按 name/version/arch 精确删除;`.gitea/workflows/pkg-repo-sync.yml` 每 6 小时调度一次(幂等,可手动 dispatch)。正常情况下镜像滞后不超过一个周期;调度失败或 runner 掉线时滞后会持续到下一次成功运行。注意 pacman 无法感知"陈旧":只要镜像可达,客户端就使用镜像的 db,看到的是滞后版本;只有镜像无法提供所请求的 db/包文件(宕机、404)时才回退到上游 Server。
客户端接线(`default/pacman/pacman-stable.conf`):`[omarchy]` 段镜像行在前、上游为兜底。镜像 db 由 registry 密钥签名,因此系统必须信任该公钥——安装期由 `install/post-install/pacman.sh` 导入,既有系统由 cn 迁移 `1787861071.sh` 处理。仅 stable 被镜像:Gitea 仓库名必须等于 pacman 段名(客户端固定请求 `omarchy.db`),edge/rc 通道保持上游直连。
`omarchy-refresh-pacman` 会用检出内模板覆写 `/etc/pacman.conf`:ISO/包安装系统的模板自带镜像行;overlay 系统的模板来自上游,覆写后镜像行丢失,用 `omarchycn doctor mirror --fix` 重新插入。
已知事实:上游仓库本身含 `omarchy`/`omarchy-dev` 包,当前版本(4.0.0.r1832)低于 cn 层自构建版本(r1955+)。常规 `pacman -Syu` 不会降级覆盖;但 `omarchy-refresh-pacman` 收尾运行的是 `pacman -Syyuu``-uu` 明确允许降级——在任何 cn 系统上执行都会把 `omarchy-dev` 降回上游版本、抹掉 cn 层(该风险先于本镜像存在,镜像只是如实转载上游内容)。若上游版本号超过 cn 构建,普通 `-Syu` 也会覆盖 cn 层——每次发布前需核对上游版本。
## 接入 ## 接入
```bash ```bash
+3 -3
View File
@@ -1,7 +1,6 @@
# Omarchy core package list pacstrapped by the ISO. # Omarchy core package list pacstrapped by the ISO.
# The ISO builder also reads this file when constructing the offline mirror. # The ISO builder also reads this file when constructing the offline mirror.
aether
alsa-utils alsa-utils
asdcontrol asdcontrol
avahi avahi
@@ -34,8 +33,11 @@ eza
fakeroot fakeroot
fastfetch fastfetch
fcitx5 fcitx5
fcitx5-chinese-addons
fcitx5-configtool
fcitx5-gtk fcitx5-gtk
fcitx5-qt fcitx5-qt
fcitx5-rime
fd fd
ffmpegthumbnailer ffmpegthumbnailer
fontconfig fontconfig
@@ -71,7 +73,6 @@ less
libsecret libsecret
libvips libvips
libyaml libyaml
libreoffice-fresh
llvm llvm
localsend localsend
lua51 lua51
@@ -90,7 +91,6 @@ noto-fonts-cjk
noto-fonts-emoji noto-fonts-emoji
nss-mdns nss-mdns
nvim nvim
obs-studio
obsidian obsidian
omacalc omacalc
omacut omacut
+4
View File
@@ -3,6 +3,10 @@
cp -f "$OMARCHY_PATH/default/pacman/pacman-${OMARCHY_MIRROR:-stable}.conf" /etc/pacman.conf cp -f "$OMARCHY_PATH/default/pacman/pacman-${OMARCHY_MIRROR:-stable}.conf" /etc/pacman.conf
cp -f "$OMARCHY_PATH/default/pacman/mirrorlist-${OMARCHY_MIRROR:-stable}" /etc/pacman.d/mirrorlist cp -f "$OMARCHY_PATH/default/pacman/mirrorlist-${OMARCHY_MIRROR:-stable}" /etc/pacman.d/mirrorlist
# The [omarchy] mirror db is signed by the OmarchyCN registry key
pacman-key --add "$OMARCHY_PATH/cn/keys/omarchycn-registry.asc"
pacman-key --lsign-key 74DCF57ACD812B24D959F146BD386048867B33B4
# omarchy-settings skips this override until cups-browsed is actually present # omarchy-settings skips this override until cups-browsed is actually present
# to avoid pacman creating cups-browsed.conf.pacnew during ISO package install. # to avoid pacman creating cups-browsed.conf.pacnew during ISO package install.
if [[ -f $OMARCHY_PATH/etc-overrides/cups-cups-browsed.conf && -d /etc/cups ]]; then if [[ -f $OMARCHY_PATH/etc-overrides/cups-cups-browsed.conf && -d /etc/cups ]]; then
+1
View File
@@ -2,6 +2,7 @@ run_logged "$OMARCHY_INSTALL/user/theme.sh"
run_logged "$OMARCHY_INSTALL/user/chromium.sh" run_logged "$OMARCHY_INSTALL/user/chromium.sh"
run_logged "$OMARCHY_INSTALL/user/git.sh" run_logged "$OMARCHY_INSTALL/user/git.sh"
run_logged "$OMARCHY_INSTALL/user/xcompose.sh" run_logged "$OMARCHY_INSTALL/user/xcompose.sh"
run_logged "$OMARCHY_INSTALL/user/cn-chinese.sh"
run_logged "$OMARCHY_INSTALL/user/mise-work.sh" run_logged "$OMARCHY_INSTALL/user/mise-work.sh"
run_logged "$OMARCHY_INSTALL/user/hardware/asus/fix-audio-mixer.sh" run_logged "$OMARCHY_INSTALL/user/hardware/asus/fix-audio-mixer.sh"
+14
View File
@@ -0,0 +1,14 @@
# Seed Chinese input and CJK font fallback on zh_CN systems.
grep -qs "^LANG=zh_CN" /etc/locale.conf || exit 0
if [[ ! -f ~/.config/fcitx5/profile ]]; then
mkdir -p ~/.config/fcitx5
cp "$OMARCHY_PATH/cn/fcitx5/profile" ~/.config/fcitx5/profile
fi
if [[ ! -f ~/.config/fontconfig/conf.d/64-omarchycn-cjk.conf ]]; then
mkdir -p ~/.config/fontconfig/conf.d
cp "$OMARCHY_PATH/cn/fontconfig/64-omarchycn-cjk.conf" ~/.config/fontconfig/conf.d/
fc-cache -f > /dev/null
fi
+2 -2
View File
@@ -3,7 +3,7 @@
set -e set -e
if omarchy-done ensure voxtype-install-invitation; then if omarchy-done ensure voxtype-install-invitation; then
omarchy-notification-send -u critical -g  "Install Dictation with Voxtype" \ omarchy-notification-send -u critical -g  "安装 Voxtype 语音听写" \
"Click to install voice dictation for Omarchy." \ "点击为 Omarchy 安装语音听写。" \
--exec omarchy-launch-floating-terminal-with-presentation omarchy-voxtype-install --exec omarchy-launch-floating-terminal-with-presentation omarchy-voxtype-install
fi fi
+2 -2
View File
@@ -5,7 +5,7 @@ set -e
# Omarchy ships no default agent, so invite once rather than picking one. An # Omarchy ships no default agent, so invite once rather than picking one. An
# agent already chosen means the invitation has nothing to offer. # agent already chosen means the invitation has nothing to offer.
if [[ -z $(omarchy-default-agent) ]] && omarchy-done ensure agent-setup-invitation; then if [[ -z $(omarchy-default-agent) ]] && omarchy-done ensure agent-setup-invitation; then
omarchy-notification-send -u critical -g 󰚩 "Set your default agent" \ omarchy-notification-send -u critical -g 󰚩 "设置默认 Agent" \
"Let your favorite agent help with Omarchy." \ "让你常用的 Agent 帮你使用 Omarchy" \
--exec omarchy menu summon setup.default.agent --exec omarchy menu summon setup.default.agent
fi fi
@@ -6,7 +6,7 @@ set -e
# PAM file is the last thing the setup writes on success). # PAM file is the last thing the setup writes on success).
if omarchy-hw-fingerprint && [[ ! -f /etc/pam.d/omarchy-lock-fingerprint ]] && if omarchy-hw-fingerprint && [[ ! -f /etc/pam.d/omarchy-lock-fingerprint ]] &&
omarchy-done ensure fingerprint-setup-invitation; then omarchy-done ensure fingerprint-setup-invitation; then
omarchy-notification-send -u critical -g 󰈷 "Setup Fingerprint Reader" \ omarchy-notification-send -u critical -g 󰈷 "设置指纹识别" \
"Enable sudo and unlocking with your fingerprint." \ "用指纹完成 sudo 与解锁。" \
--exec omarchy-launch-floating-terminal-with-presentation omarchy-setup-security-fingerprint --exec omarchy-launch-floating-terminal-with-presentation omarchy-setup-security-fingerprint
fi fi
+2 -2
View File
@@ -1,5 +1,5 @@
# Real newlines, not a literal \n: the card renders the body as it arrives, and # Real newlines, not a literal \n: the card renders the body as it arrives, and
# elides past three lines. # elides past three lines.
omarchy-notification-send -u critical -g  "Learn Keybindings" \ omarchy-notification-send -u critical -g  "学习快捷键" \
$'Super + K for cheatsheet.\nSuper + Space for Omarchy Menu.' \ $'Super + K 查看快捷键表。\nSuper + Space 打开 Omarchy 菜单。' \
--exec omarchy-menu-keybindings --exec omarchy-menu-keybindings
+2 -2
View File
@@ -1,10 +1,10 @@
notify_update() { notify_update() {
omarchy-notification-send -u critical -g  "Update System" "Click to update the system." \ omarchy-notification-send -u critical -g  "更新系统" "点击以更新系统。" \
--exec omarchy-launch-floating-terminal-with-presentation omarchy-update --exec omarchy-launch-floating-terminal-with-presentation omarchy-update
} }
notify_wifi() { notify_wifi() {
omarchy-notification-send -u critical -g 󰖩 "Setup Wi-Fi" "Click to configure the wireless network." \ omarchy-notification-send -u critical -g 󰖩 "设置 Wi-Fi" "点击以配置无线网络。" \
--exec omarchy-shell shell toggle omarchy.network --exec omarchy-shell shell toggle omarchy.network
} }
+1 -1
View File
@@ -1,6 +1,6 @@
# Welcome to Omarchy! # Welcome to Omarchy!
Omarchy is an [omakase](https://manuals.omamix.org/3/omacom/76/omakase-computing) Linux distribution based on [Arch](https://archlinux.org/), the tiling window manager [Hyprland](https://hypr.land/), and the desktop construction-kit [Quickshell](https://quickshell.org/). It ships with everything a modern, savvy computer user needs to be productive immediately. From [Neovim](https://neovim.io/) (btw) to Chromium, [Obsidian](https://obsidian.md/) to LibreOffice, and Kdenlive to OBS Studio. Hell, even a retro Winamp-style music player is there! Omarchy is an [omakase](https://manuals.omamix.org/3/omacom/76/omakase-computing) Linux distribution based on [Arch](https://archlinux.org/), the tiling window manager [Hyprland](https://hypr.land/), and the desktop construction-kit [Quickshell](https://quickshell.org/). It ships with everything a modern, savvy computer user needs to be productive immediately. From [Neovim](https://neovim.io/) (btw) to Chromium, [Obsidian](https://obsidian.md/) to Kdenlive. Hell, even a retro Winamp-style music player is there!
This isn't just a grab bag of preinstalled packages, though. It's a complete system designed with both aesthetics and productivity in mind. Because a _beautiful_ system is a _motivating_ system, and productivity has always been [downstream from motivation](https://world.hey.com/dhh/beautiful-motivations-6fef7c73). There's zero bloat here: Just everything I use. This isn't just a grab bag of preinstalled packages, though. It's a complete system designed with both aesthetics and productivity in mind. Because a _beautiful_ system is a _motivating_ system, and productivity has always been [downstream from motivation](https://world.hey.com/dhh/beautiful-motivations-6fef7c73). There's zero bloat here: Just everything I use.
-9
View File
@@ -107,21 +107,12 @@ You can see all the main keyboard bindings with `Super + K` (Tmux bindings with
| `Super + Shift + Alt + M` | Music (cliamp) | | `Super + Shift + Alt + M` | Music (cliamp) |
| `Super + Shift + /` | Password manager (1password) | | `Super + Shift + /` | Password manager (1password) |
| `Super + Shift + N` | Editor (Neovim) | | `Super + Shift + N` | Editor (Neovim) |
| `Super + Shift + C` | Calendar ([HEY](https://hey.com/)) |
| `Super + Shift + E` | Email ([HEY](https://hey.com/)) |
| `Super + Shift + Alt + E` | New email ([HEY](https://hey.com/)) |
| `Super + Shift + A` | AI (ChatGPT) | | `Super + Shift + A` | AI (ChatGPT) |
| `Super + Shift + Alt + A` | AI (Grok) | | `Super + Shift + Alt + A` | AI (Grok) |
| `Super + Shift + G` | Messenger (Signal) | | `Super + Shift + G` | Messenger (Signal) |
| `Super + Shift + P` | Google Photos |
| `Super + Shift + S` | Google Maps |
| `Super + Shift + Alt + G` | Messenger (WhatsApp) |
| `Super + Shift + Ctrl + G` | Messenger (Google) |
| `Super + Shift + D` | Docker (LazyDocker) | | `Super + Shift + D` | Docker (LazyDocker) |
| `Super + Shift + O` | Obsidian | | `Super + Shift + O` | Obsidian |
| `Super + Shift + W` | Writing (Omawrite) | | `Super + Shift + W` | Writing (Omawrite) |
| `Super + Shift + X` | X |
| `Super + Shift + Alt + X` | X Compose |
| `Super + Shift + Y` | YouTube | | `Super + Shift + Y` | YouTube |
Change/add bindings in `~/.config/hypr/bindings.lua`. Change/add bindings in `~/.config/hypr/bindings.lua`.
+1 -19
View File
@@ -30,12 +30,6 @@ You start Omawrite with `Super + Shift + W`.
You start Pinta via the application launcher (`Super + Space`). You start Pinta via the application launcher (`Super + Space`).
## Aether
[Aether](https://github.com/bjarneo/aether) is a theming application that can extract colors from a background image and turn them into a complete, cohesive theme. It's the easiest way to [make your own theme](43-making-your-own-theme.md).
You start Aether via the application launcher (`Super + Space`).
## LocalSend ## LocalSend
[LocalSend](https://localsend.org/) lets you send files to other devices on the same network running the app, like Apple's AirDrop. It's cross-platform, though, so you can send files to and from Windows, macOS, Android, iOS, and of course Linux. [LocalSend](https://localsend.org/) lets you send files to other devices on the same network running the app, like Apple's AirDrop. It's cross-platform, though, so you can send files to and from Windows, macOS, Android, iOS, and of course Linux.
@@ -53,12 +47,6 @@ You can also send straight from the file manager: right-click any selection in N
Omarchy's firewall is closed by default except for LocalSend's port, so this works out of the box on a fresh install. See [security](48-security.md). Omarchy's firewall is closed by default except for LocalSend's port, so this works out of the box on a fresh install. See [security](48-security.md).
## LibreOffice
[LibreOffice](https://www.libreoffice.org/) is a complete office package with word processor, spreadsheet, presentations, drawing application, and more. It's compatible with files from Microsoft Office, so this is a great way to be able to open those Word documents.
You start LibreOffice via the application launcher (`Super + Space`).
## Omacalc ## Omacalc
[Omacalc](https://github.com/omacom-io/omacalc) is Omarchy's own dead-simple calculator, which opens in a floating window. [Omacalc](https://github.com/omacom-io/omacalc) is Omarchy's own dead-simple calculator, which opens in a floating window.
@@ -77,15 +65,9 @@ You start Signal with `Super + Shift + G`. It's not part of the base install, so
You start mpv via the application launcher (`Super + Space`) or just double-click on a video in the file manager. You start mpv via the application launcher (`Super + Space`) or just double-click on a video in the file manager.
## OBS Studio
[OBS Studio](https://obsproject.com/) lets you record or stream video from multiple inputs. You can mix a screencast with a webcam with a microphone input. It's what was used to record the Omarchy screencasts.
You start OBS Studio via the application launcher (`Super + Space`).
## Kdenlive ## Kdenlive
[Kdenlive](https://kdenlive.org/) is an excellent video editor. Perfect for working on video that comes out of OBS Studio before sharing it. [Kdenlive](https://kdenlive.org/) is an excellent video editor. Perfect for editing your screen recordings before sharing them.
You start Kdenlive via the application launcher (`Super + Space`). You start Kdenlive via the application launcher (`Super + Space`).
-35
View File
@@ -14,18 +14,6 @@ When you're in a web app, you can copy the current URL to the clipboard using `S
By default, Omarchy already ships with an assortment of default apps: By default, Omarchy already ships with an assortment of default apps:
## HEY
[HEY](https://www.hey.com/) is an email and calendar service that serves as a great alternative to people tired of Gmail, Outlook, or Apple Mail. It's made by [37signals](https://37signals.com/) where Omarchy originated.
You can start HEY Email using `Super + Shift + E`, jump straight to composing a new email using `Super + Shift + Alt + E`, and start HEY Calendar using `Super + Shift + C`.
## Basecamp
[Basecamp](https://basecamp.com/) is a project management service that helps small teams move faster and make more progress. Instead of patching together a mishmash of Trello, Slack, Asana, Notion, or whatever, you can have it all in one place with Basecamp. It's made by [37signals](https://37signals.com/) where Omarchy originated.
You can start Basecamp using the application launcher (`Super + Space`)
## ChatGPT ## ChatGPT
[ChatGPT](https://chatgpt.com) is the most popular AI chat bot in the world. [ChatGPT](https://chatgpt.com) is the most popular AI chat bot in the world.
@@ -38,24 +26,6 @@ You can start ChatGPT using `Super + Shift + A`.
You can start Grok using `Super + Shift + Alt + A`. You can start Grok using `Super + Shift + Alt + A`.
## WhatsApp
[WhatsApp](https://www.whatsapp.com/) is one of the most popular messaging services in the world, and the web version is a great option for Linux.
You can start WhatsApp using `Super + Shift + Alt + G`.
## Google apps
Google Messages, Google Photos, Google Maps, and Google Contacts are all included as web apps too.
You can start Google Messages using `Super + Shift + Ctrl + G`, Google Photos using `Super + Shift + P`, and Google Maps using `Super + Shift + S`. Google Contacts is available through the app launcher (`Super + Space`).
## X
X is where news break.
You can start X using `Super + Shift + X` and go straight to writing a new post with `Super + Shift + Alt + X`.
## YouTube ## YouTube
[YouTube](https://youtube.com/) is the most popular video platform in the world. [YouTube](https://youtube.com/) is the most popular video platform in the world.
@@ -68,8 +38,3 @@ You can start YouTube using `Super + Shift + Y`.
You start Zoom using the application launcher (`Super + Space`). You start Zoom using the application launcher (`Super + Space`).
## Discord
[Discord](https://discord.com/) is where most gaming and open source communities hang out, including [Omarchy's own](https://discord.gg/tXFUdasqhY).
You start Discord using the application launcher (`Super + Space`).
+1 -1
View File
@@ -4,7 +4,7 @@ You can add your own themes to `~/.config/omarchy/themes`. Just copy one of the
The main file you have to tweak is `colors.toml`. That defines the color set that's then used to generate configurations for the terminal (Foot/Alacritty/Ghostty/Kitty), btop, Chromium, Hyprland, Neovim, Helix, VSCode, Obsidian, and the entire Omarchy shell (top bar, menu, notifications, OSD, and lock screen). The main file you have to tweak is `colors.toml`. That defines the color set that's then used to generate configurations for the terminal (Foot/Alacritty/Ghostty/Kitty), btop, Chromium, Hyprland, Neovim, Helix, VSCode, Obsidian, and the entire Omarchy shell (top bar, menu, notifications, OSD, and lock screen).
You can also use the included Aether application to create a new theme using a lovely GUI interface to play with colors and search for backgrounds. Just start it via the apps menu on `Super + Alt + Space`. You can also install the [Aether](https://github.com/bjarneo/aether) application (`omarchy-pkg-add aether`) to create a new theme using a lovely GUI interface to play with colors and search for backgrounds.
### What an installed theme can contain ### What an installed theme can contain
+1 -1
View File
@@ -66,7 +66,7 @@ Remember that you have built-in brightness control in Omarchy for the Apple Disp
### How do I get rid of all the extra software? ### How do I get rid of all the extra software?
If you don't want programs like Obsidian or LibreOffice or any of the other preinstalled stuff, you can very easily remove it. If you don't want programs like Obsidian or any of the other preinstalled stuff, you can very easily remove it.
Run _Remove > Package_ to see every package that's installed. Then you can select any package you'd like to remove with tab, and start removing everything you've selected with return. Run _Remove > Package_ to see every package that's installed. Then you can select any package you'd like to remove with tab, and start removing everything you've selected with return.
+77 -24
View File
@@ -47,15 +47,16 @@ index 16904f8..f1ec36e 100644
export OMARCHY_MIRROR="$(cat /root/omarchy_mirror)" export OMARCHY_MIRROR="$(cat /root/omarchy_mirror)"
if [[ -f /root/omarchy_iso_ref ]]; then if [[ -f /root/omarchy_iso_ref ]]; then
diff --git a/configs/airootfs/root/configurator b/configs/airootfs/root/configurator diff --git a/configs/airootfs/root/configurator b/configs/airootfs/root/configurator
index 4cd3db3..24a1bf8 100644 index 4cd3db3..96c507e 100644
--- a/configs/airootfs/root/configurator --- a/configs/airootfs/root/configurator
+++ b/configs/airootfs/root/configurator +++ b/configs/airootfs/root/configurator
@@ -9,6 +9,165 @@ OMARCHY_SETTINGS_PACKAGE="${OMARCHY_SETTINGS_PACKAGE:-omarchy-settings}" @@ -9,6 +9,167 @@ OMARCHY_SETTINGS_PACKAGE="${OMARCHY_SETTINGS_PACKAGE:-omarchy-settings}"
LOGO_PATH="$OMARCHY_PATH/logo.txt" LOGO_PATH="$OMARCHY_PATH/logo.txt"
+# Installer strings; the graphical console stage exports OMARCHY_INSTALL_LANG=zh +# Installer strings; the graphical console stage exports OMARCHY_INSTALL_LANG=zh
+if [[ ${OMARCHY_INSTALL_LANG:-} == zh ]]; then +if [[ ${OMARCHY_INSTALL_LANG:-} == zh ]]; then
+ SYS_LANG="zh_CN.UTF-8"
+ L_TAGLINE='华丽、现代、观点鲜明的 Linux —— 中国版' + L_TAGLINE='华丽、现代、观点鲜明的 Linux —— 中国版'
+ L_HINT='按回车开始安装' + L_HINT='按回车开始安装'
+ L_ABORTED='安装已中止' + L_ABORTED='安装已中止'
@@ -134,6 +135,7 @@ index 4cd3db3..24a1bf8 100644
+ L_DS_MKESP='在 %s 创建 ESP 文件系统' + L_DS_MKESP='在 %s 创建 ESP 文件系统'
+ L_DS_MOUNTESP='挂载 ESP' + L_DS_MOUNTESP='挂载 ESP'
+else +else
+ SYS_LANG="en_US.UTF-8"
+ L_TAGLINE='Beautiful, Modern & Opinionated Linux by DHH' + L_TAGLINE='Beautiful, Modern & Opinionated Linux by DHH'
+ L_HINT='Press Return to Start Install' + L_HINT='Press Return to Start Install'
+ L_ABORTED='Aborted installation' + L_ABORTED='Aborted installation'
@@ -216,7 +218,7 @@ index 4cd3db3..24a1bf8 100644
# The setup form — keyboard, account, hostname, and timezone questions, plus the # The setup form — keyboard, account, hostname, and timezone questions, plus the
# rules their answers are checked against — shared verbatim with the first-boot # rules their answers are checked against — shared verbatim with the first-boot
# owner setup that finishes a deferred install. build-iso.sh vendors it out of # owner setup that finishes a deferred install. build-iso.sh vendors it out of
@@ -122,12 +281,12 @@ greeter() { @@ -122,12 +283,12 @@ greeter() {
printf '\033[%d;1H' "$logo_row" printf '\033[%d;1H' "$logo_row"
gum style --foreground 2 --padding "0 0 0 $PADDING_LEFT" "$(<"$LOGO_PATH")" gum style --foreground 2 --padding "0 0 0 $PADDING_LEFT" "$(<"$LOGO_PATH")"
@@ -233,7 +235,7 @@ index 4cd3db3..24a1bf8 100644
printf '\033[%d;%dH\033[2m%s\033[0m' "$hint_row" "$((hpad + 1))" "$hint" printf '\033[%d;%dH\033[2m%s\033[0m' "$hint_row" "$((hpad + 1))" "$hint"
# ColorShift the logo: a green base (indexed color 2) with a cyan accent (6) # ColorShift the logo: a green base (indexed color 2) with a cyan accent (6)
@@ -176,9 +335,9 @@ greeter() { @@ -176,9 +337,9 @@ greeter() {
} }
abort() { abort() {
@@ -245,7 +247,7 @@ index 4cd3db3..24a1bf8 100644
exit 1 exit 1
} }
@@ -212,8 +371,8 @@ keyboard_form() { @@ -212,8 +373,8 @@ keyboard_form() {
while true; do while true; do
clear_logo clear_logo
echo echo
@@ -256,7 +258,7 @@ index 4cd3db3..24a1bf8 100644
echo echo
omarchy_prompt_keyboard && status=0 || status=$? omarchy_prompt_keyboard && status=0 || status=$?
@@ -245,11 +404,11 @@ keyboard_form() { @@ -245,11 +406,11 @@ keyboard_form() {
confirm_prepare_for_another_owner() { confirm_prepare_for_another_owner() {
clear_logo clear_logo
echo echo
@@ -272,7 +274,7 @@ index 4cd3db3..24a1bf8 100644
} }
# The user step. Deferred-provisioning installs skip it entirely — the machine's first owner # The user step. Deferred-provisioning installs skip it entirely — the machine's first owner
@@ -257,7 +416,7 @@ confirm_prepare_for_another_owner() { @@ -257,7 +418,7 @@ confirm_prepare_for_another_owner() {
# operator sets nothing user-specific. # operator sets nothing user-specific.
user_form() { user_form() {
@@ -281,7 +283,7 @@ index 4cd3db3..24a1bf8 100644
# Each prompt reports 0 (set), OMARCHY_FORM_BACK (Esc), or OMARCHY_FORM_SIGNAL # Each prompt reports 0 (set), OMARCHY_FORM_BACK (Esc), or OMARCHY_FORM_SIGNAL
# (Ctrl+C). Both non-zero cases unwind to user_step, which decides what they # (Ctrl+C). Both non-zero cases unwind to user_step, which decides what they
@@ -291,18 +450,18 @@ user_step() { @@ -291,18 +452,18 @@ user_step() {
fi fi
# Add manual padding since gum table -p doesn't respect padding # Add manual padding since gum table -p doesn't respect padding
@@ -309,7 +311,7 @@ index 4cd3db3..24a1bf8 100644
break break
else else
keyboard_form keyboard_form
@@ -504,11 +663,11 @@ print_dry_run_files() { @@ -504,11 +665,11 @@ print_dry_run_files() {
# action so users have a way to actually fix the situation. # action so users have a way to actually fix the situation.
not_enough_space() { not_enough_space() {
local available="${1:-0}" local available="${1:-0}"
@@ -325,7 +327,7 @@ index 4cd3db3..24a1bf8 100644
open_partition_tool open_partition_tool
fi fi
return 1 return 1
@@ -518,14 +677,14 @@ not_enough_space() { @@ -518,14 +679,14 @@ not_enough_space() {
# encryption confirm. Sets the globals run_partition_execute needs. Returns 1 # encryption confirm. Sets the globals run_partition_execute needs. Returns 1
# to fall back to the install-mode picker. # to fall back to the install-mode picker.
run_partition_decide() { run_partition_decide() {
@@ -345,7 +347,7 @@ index 4cd3db3..24a1bf8 100644
fi fi
# Omarchy always creates its own dedicated ESP in free space and never # Omarchy always creates its own dedicated ESP in free space and never
@@ -534,17 +693,17 @@ run_partition_decide() { @@ -534,17 +695,17 @@ run_partition_decide() {
# Windows ESP is far too small for our Unified Kernel Images, and a shared # Windows ESP is far too small for our Unified Kernel Images, and a shared
# ESP forces the install unencrypted. A separate Linux ESP keeps Windows # ESP forces the install unencrypted. A separate Linux ESP keeps Windows
# and Omarchy fully isolated and keeps LUKS on the table. # and Omarchy fully isolated and keeps LUKS on the table.
@@ -368,7 +370,7 @@ index 4cd3db3..24a1bf8 100644
partprobe "$disk" 2>/dev/null || true partprobe "$disk" 2>/dev/null || true
sleep 1 sleep 1
@@ -619,21 +778,21 @@ run_partition_decide() { @@ -619,21 +780,21 @@ run_partition_decide() {
while true; do while true; do
clear_logo clear_logo
echo echo
@@ -396,7 +398,7 @@ index 4cd3db3..24a1bf8 100644
confirm_status=$? confirm_status=$?
case $confirm_status in case $confirm_status in
@@ -691,9 +850,9 @@ run_partition_execute() { @@ -691,9 +852,9 @@ run_partition_execute() {
say "[dry] partition numbers are assigned by parted at creation, then read back" say "[dry] partition numbers are assigned by parted at creation, then read back"
say "[dry] encrypted=$encrypt_installation kernel=$kernel_choice" say "[dry] encrypted=$encrypt_installation kernel=$kernel_choice"
else else
@@ -408,7 +410,7 @@ index 4cd3db3..24a1bf8 100644
partprobe "$disk" 2>/dev/null || true partprobe "$disk" 2>/dev/null || true
sleep 1 sleep 1
fi fi
@@ -709,7 +868,7 @@ run_partition_execute() { @@ -709,7 +870,7 @@ run_partition_execute() {
disk_abort_hook "Could not create the root partition on $disk" disk_abort_hook "Could not create the root partition on $disk"
root_part_num="$created_partition_number" root_part_num="$created_partition_number"
@@ -417,7 +419,7 @@ index 4cd3db3..24a1bf8 100644
parted --script "$disk" set "$efi_part_num" esp on parted --script "$disk" set "$efi_part_num" esp on
efi_dev=$(partition_path "$disk" "$efi_part_num") efi_dev=$(partition_path "$disk" "$efi_part_num")
@@ -725,11 +884,11 @@ run_partition_execute() { @@ -725,11 +886,11 @@ run_partition_execute() {
# Both partitions are ours and brand new, but the space they occupy may # Both partitions are ours and brand new, but the space they occupy may
# carry signatures from whatever was deleted to free it. # carry signatures from whatever was deleted to free it.
@@ -432,7 +434,7 @@ index 4cd3db3..24a1bf8 100644
# Kept as pipes rather than routed through disk_step: the passphrase must # Kept as pipes rather than routed through disk_step: the passphrase must
# not become an argv the process table can show. Folding stderr into # not become an argv the process table can show. Folding stderr into
# stdout still lands any error in the install log. # stdout still lands any error in the install log.
@@ -746,31 +905,31 @@ run_partition_execute() { @@ -746,31 +907,31 @@ run_partition_execute() {
root_mapper="$root_partition_device" root_mapper="$root_partition_device"
fi fi
@@ -474,7 +476,28 @@ index 4cd3db3..24a1bf8 100644
# The orchestrator's first act is to verify this handoff. Check it here so # The orchestrator's first act is to verify this handoff. Check it here so
# a failure names the step that broke rather than surfacing later as # a failure names the step that broke rather than surfacing later as
@@ -862,7 +1021,7 @@ _EOF_ @@ -798,7 +959,10 @@ run_partition_execute() {
"auth_config": {},
"audio_config": { "audio": "pipewire" },
"bootloader_config": { "bootloader": "Limine", "uki": false, "removable": false },
- "custom_commands": [],
+ "custom_commands": [
+ "sed -i -e s/^#zh_CN.UTF-8/zh_CN.UTF-8/ -e s/^#en_US.UTF-8/en_US.UTF-8/ /etc/locale.gen",
+ "locale-gen"
+ ],
"omarchy_install": {
"mode": "protected",
"target_mount": "/mnt",
@@ -832,7 +996,7 @@ run_partition_execute() {
"locale_config": {
"kb_layout": "$keyboard",
"sys_enc": "UTF-8",
- "sys_lang": "en_US.UTF-8"
+ "sys_lang": "$SYS_LANG"
},
"mirror_config": {
"custom_repositories": [],
@@ -862,7 +1026,7 @@ _EOF_
} }
disk_form() { disk_form() {
@@ -483,7 +506,7 @@ index 4cd3db3..24a1bf8 100644
# Don't offer the install media as an option (Arch ISO mounts it here) # Don't offer the install media as an option (Arch ISO mounts it here)
local boot_source local boot_source
@@ -888,19 +1047,19 @@ disk_form() { @@ -888,19 +1052,19 @@ disk_form() {
fi fi
done <<<"$available_disks" done <<<"$available_disks"
@@ -508,7 +531,7 @@ index 4cd3db3..24a1bf8 100644
clear clear
cfdisk "$disk" || true cfdisk "$disk" || true
@@ -933,17 +1092,17 @@ requires_full_disk_install() { @@ -933,17 +1097,17 @@ requires_full_disk_install() {
} }
install_mode_form() { install_mode_form() {
@@ -531,7 +554,7 @@ index 4cd3db3..24a1bf8 100644
} }
confirm_disk_overwrite() { confirm_disk_overwrite() {
@@ -953,17 +1112,17 @@ confirm_disk_overwrite() { @@ -953,17 +1117,17 @@ confirm_disk_overwrite() {
while true; do while true; do
clear_logo clear_logo
echo echo
@@ -554,7 +577,7 @@ index 4cd3db3..24a1bf8 100644
confirm_status=$? confirm_status=$?
case $confirm_status in case $confirm_status in
@@ -1002,13 +1161,13 @@ select_installation() { @@ -1002,13 +1166,13 @@ select_installation() {
# With no free-space option to offer, a full-disk install is the only # With no free-space option to offer, a full-disk install is the only
# mode, so skip the picker and go straight to the overwrite confirm. # mode, so skip the picker and go straight to the overwrite confirm.
if $full_disk_only; then if $full_disk_only; then
@@ -570,7 +593,7 @@ index 4cd3db3..24a1bf8 100644
if confirm_disk_overwrite; then if confirm_disk_overwrite; then
install_target="full_disk" install_target="full_disk"
return 0 return 0
@@ -1017,13 +1176,13 @@ select_installation() { @@ -1017,13 +1181,13 @@ select_installation() {
# wants a different disk. # wants a different disk.
$full_disk_only && disk_form $full_disk_only && disk_form
;; ;;
@@ -586,8 +609,29 @@ index 4cd3db3..24a1bf8 100644
disk_form disk_form
;; ;;
esac esac
@@ -1136,7 +1300,10 @@ cat <<-_EOF_ >user_configuration.json
"auth_config": {},
"audio_config": { "audio": "pipewire" },
"bootloader_config": { "bootloader": "Limine", "uki": false, "removable": false },
- "custom_commands": [],
+ "custom_commands": [
+ "sed -i -e s/^#zh_CN.UTF-8/zh_CN.UTF-8/ -e s/^#en_US.UTF-8/en_US.UTF-8/ /etc/locale.gen",
+ "locale-gen"
+ ],
"omarchy_install": {
"mode": "full_disk",
"defer_provisioning": $defer_provisioning,
@@ -1221,7 +1388,7 @@ cat <<-_EOF_ >user_configuration.json
"locale_config": {
"kb_layout": "$keyboard",
"sys_enc": "UTF-8",
- "sys_lang": "en_US.UTF-8"
+ "sys_lang": "$SYS_LANG"
},
"mirror_config": {
"custom_repositories": [],
diff --git a/configs/airootfs/usr/local/bin/omarchy-install-dashboard b/configs/airootfs/usr/local/bin/omarchy-install-dashboard diff --git a/configs/airootfs/usr/local/bin/omarchy-install-dashboard b/configs/airootfs/usr/local/bin/omarchy-install-dashboard
index 91e960b..54d331d 100755 index 91e960b..9d45f6a 100755
--- a/configs/airootfs/usr/local/bin/omarchy-install-dashboard --- a/configs/airootfs/usr/local/bin/omarchy-install-dashboard
+++ b/configs/airootfs/usr/local/bin/omarchy-install-dashboard +++ b/configs/airootfs/usr/local/bin/omarchy-install-dashboard
@@ -53,6 +53,44 @@ export GUM_CONFIRM_UNSELECTED_BACKGROUND="${GUM_CONFIRM_UNSELECTED_BACKGROUND:-0 @@ -53,6 +53,44 @@ export GUM_CONFIRM_UNSELECTED_BACKGROUND="${GUM_CONFIRM_UNSELECTED_BACKGROUND:-0
@@ -603,7 +647,7 @@ index 91e960b..54d331d 100755
+ "用 LocalSend 与手机、电脑互传文件" + "用 LocalSend 与手机、电脑互传文件"
+ "菜单 Install > Web App 可把任意网站变成应用" + "菜单 Install > Web App 可把任意网站变成应用"
+ "Super + Return 打开终端,Super + Shift + Return 打开浏览器" + "Super + Return 打开终端,Super + Shift + Return 打开浏览器"
+ "图片用 Pinta,视频用 Kdenlive,文档用 LibreOffice" + "图片用 Pinta,视频剪辑用 Kdenlive"
+ "Super + Ctrl + Print 用 OCR 抓取屏幕文字" + "Super + Ctrl + Print 用 OCR 抓取屏幕文字"
+ "Print 截屏,Alt + Print 录屏" + "Print 截屏,Alt + Print 录屏"
+ "Super + Ctrl + R 设置提醒" + "Super + Ctrl + R 设置提醒"
@@ -635,6 +679,15 @@ index 91e960b..54d331d 100755
tips=( tips=(
"Super + Space opens the Omarchy menu for apps, settings, and more" "Super + Space opens the Omarchy menu for apps, settings, and more"
"Super + K shows all the key bindings" "Super + K shows all the key bindings"
@@ -61,7 +99,7 @@ tips=(
"Share files with phones and laptops using LocalSend"
"Turn any website into an app with Install > Web App in the menu"
"Super + Return opens a terminal, Super + Shift + Return the browser"
- "Edit images with Pinta, videos with Kdenlive, docs with LibreOffice"
+ "Edit images with Pinta and videos with Kdenlive"
"Super + Ctrl + Print grabs text off the screen with OCR"
"Print takes a screenshot, Alt + Print records the screen"
"Set a reminder with Super + Ctrl + R"
@@ -73,6 +111,23 @@ tips=( @@ -73,6 +111,23 @@ tips=(
"Super + Print picks a color from anywhere on screen" "Super + Print picks a color from anywhere on screen"
"Keep the system fresh with Update in the Omarchy menu" "Keep the system fresh with Update in the Omarchy menu"
+101
View File
@@ -0,0 +1,101 @@
#!/bin/bash
# Mirrors the upstream [omarchy] stable repo into the OmarchyCN Gitea Arch registry.
# Maintainer/CI script (pkg-repo-sync.yml); needs a package-write token, network.
set -euo pipefail
export LC_ALL=C
GITEA=${GITEA:-https://git.zacharyzhang.com}
OWNER=${OWNER:-ZacharyZhang-NY}
REPO=${REPO:-omarchy}
UPSTREAM=${UPSTREAM:-https://pkgs.omarchy.org/stable/x86_64}
: "${PKG_SYNC_TOKEN:?PKG_SYNC_TOKEN (Gitea package-write token) is required}"
registry="$GITEA/api/packages/$OWNER/arch"
mirror="$registry/$REPO/x86_64"
workdir=$(mktemp -d)
trap 'rm -rf "$workdir"' EXIT
# One "filename name version arch" line per package in a repo db (zstd or gzip tar)
db_entries() {
local db="$1" dir="$2" desc
mkdir -p "$dir"
tar --zstd -xf "$db" -C "$dir" 2>/dev/null || tar -xzf "$db" -C "$dir"
for desc in "$dir"/*/desc; do
[[ -f $desc ]] || continue
awk '
/^%FILENAME%$/ { getline; f = $0 }
/^%NAME%$/ { getline; n = $0 }
/^%VERSION%$/ { getline; v = $0 }
/^%ARCH%$/ { getline; a = $0 }
END {
if (f == "" || n == "" || v == "" || a == "") {
print "malformed desc: " FILENAME > "/dev/stderr"
exit 1
}
print f, n, v, a
}
' "$desc"
done
}
curl -sSf --retry 3 -o "$workdir/upstream.db" "$UPSTREAM/omarchy.db"
db_entries "$workdir/upstream.db" "$workdir/upstream" | sort > "$workdir/upstream.list"
# Only 404 means first sync; any other failure must not fake an empty mirror,
# which would skip deletions and report a bogus success
code=$(curl -sS --retry 3 -o "$workdir/mirror.db" -w '%{http_code}' "$mirror/$REPO.db" || true)
[[ -z $code ]] && code=000
case "$code" in
200)
db_entries "$workdir/mirror.db" "$workdir/mirror" | sort > "$workdir/mirror.list"
;;
404)
: > "$workdir/mirror.list"
;;
*)
echo "mirror db fetch failed (HTTP $code): $mirror/$REPO.db" >&2
exit 1
;;
esac
comm -23 "$workdir/upstream.list" "$workdir/mirror.list" > "$workdir/to-add.list"
comm -13 "$workdir/upstream.list" "$workdir/mirror.list" > "$workdir/to-remove.list"
echo "upstream: $(wc -l < "$workdir/upstream.list") packages," \
"mirror: $(wc -l < "$workdir/mirror.list")," \
"to add: $(wc -l < "$workdir/to-add.list")," \
"to remove: $(wc -l < "$workdir/to-remove.list")"
added=0
while read -r filename name version arch; do
echo "add: $filename"
curl -sSf --retry 3 -o "$workdir/pkg" "$UPSTREAM/$filename"
code=$(curl -sS --retry 2 -o "$workdir/put.out" -w '%{http_code}' -X PUT \
-H "Authorization: token $PKG_SYNC_TOKEN" \
--upload-file "$workdir/pkg" "$registry/$REPO")
case "$code" in
201) added=$((added + 1)) ;;
409) echo " already present (409)" ;;
*)
echo "upload of $filename failed (HTTP $code): $(head -c 300 "$workdir/put.out")" >&2
exit 1
;;
esac
rm -f "$workdir/pkg"
done < "$workdir/to-add.list"
removed=0
while read -r filename name version arch; do
echo "remove: $filename"
code=$(curl -sS --retry 2 -o "$workdir/del.out" -w '%{http_code}' -X DELETE \
-H "Authorization: token $PKG_SYNC_TOKEN" \
"$registry/$REPO/$name/$version/$arch")
if [[ $code != 2?? && $code != 404 ]]; then
echo "removal of $filename failed (HTTP $code): $(head -c 300 "$workdir/del.out")" >&2
exit 1
fi
removed=$((removed + 1))
done < "$workdir/to-remove.list"
echo "Sync complete: $added added, $removed removed"
@@ -1,32 +0,0 @@
#!/bin/bash
set -euo pipefail
source "$(dirname "${BASH_SOURCE[0]}")/base-test.sh"
require_command node
# A keyless unpacked extension gets a path-derived id, so its settings — and
# any shortcut registrations it may grow — would go stale if its load path or
# packaging ever changed. The pinned key keeps the id stable everywhere.
whatsapp_slim_id=$(node - <<'JS' "$ROOT/default/chromium/extensions/whatsapp-slim/manifest.json"
const crypto = require('crypto')
const fs = require('fs')
const manifest = JSON.parse(fs.readFileSync(process.argv[2], 'utf8'))
const hash = crypto.createHash('sha256').update(Buffer.from(manifest.key, 'base64')).digest()
const alphabet = 'abcdefghijklmnop'
let id = ''
for (const byte of hash.subarray(0, 16)) {
id += alphabet[byte >> 4]
id += alphabet[byte & 0x0f]
}
process.stdout.write(id)
JS
)
[[ $whatsapp_slim_id == "amhpgjbcfakkmkeojmoaoiochhifohdi" ]] ||
fail "whatsapp-slim extension manifest has the stable id" "$whatsapp_slim_id"
pass "whatsapp-slim extension manifest has the stable id"
+1 -1
View File
@@ -265,7 +265,7 @@ shell_json=$(cd "$ROOT" && jq -r '[.bar.layout.center[].id] | join(",")' config/
[[ $shell_json != *"omarchy.calendar"* ]] || fail "clock hosts the calendar instead of a second bar pill" "center: $shell_json" [[ $shell_json != *"omarchy.calendar"* ]] || fail "clock hosts the calendar instead of a second bar pill" "center: $shell_json"
pass "default bar layout includes the clock widget" pass "default bar layout includes the clock widget"
grep -q 'o.bind("SUPER + CTRL + ALT + D", "Calendar", "omarchy-shell shell toggle omarchy.clock")' \ grep -q 'o.bind("SUPER + CTRL + ALT + D", "日历", "omarchy-shell shell toggle omarchy.clock")' \
"$ROOT/default/hypr/bindings/utilities.lua" || "$ROOT/default/hypr/bindings/utilities.lua" ||
fail "SUPER+CTRL+ALT+D toggles the calendar panel" fail "SUPER+CTRL+ALT+D toggles the calendar panel"
pass "SUPER+CTRL+ALT+D toggles the calendar panel" pass "SUPER+CTRL+ALT+D toggles the calendar panel"
@@ -146,9 +146,9 @@ chmod +x "$stub_bin/voxtype"
bindings=$(PATH="$stub_bin:$PATH" list_bindings "$home") bindings=$(PATH="$stub_bin:$PATH" list_bindings "$home")
[[ -n $bindings ]] || fail "default bindings load for the conflict check" [[ -n $bindings ]] || fail "default bindings load for the conflict check"
grep -Fq $'SUPER + RETURN\tTerminal' <<<"$bindings" || fail "conflict check sees the essential bindings" grep -Fq $'SUPER + RETURN\t终端' <<<"$bindings" || fail "conflict check sees the essential bindings"
grep -Fq $'SUPER + SHIFT + A\tChatGPT' <<<"$bindings" || fail "conflict check sees the preinstalled bindings" grep -Fq $'SUPER + SHIFT + A\tChatGPT' <<<"$bindings" || fail "conflict check sees the preinstalled bindings"
grep -Fq $'F9\tStart dictation (push-to-talk)' <<<"$bindings" || fail "conflict check sees the Voxtype bindings" grep -Fq $'F9\t开始听写(按住说话)' <<<"$bindings" || fail "conflict check sees the Voxtype bindings"
pass "conflict check covers the full default binding set" pass "conflict check covers the full default binding set"
duplicates=$(duplicate_signatures <<<"$bindings") duplicates=$(duplicate_signatures <<<"$bindings")
+13 -13
View File
@@ -101,7 +101,7 @@ trap 'rm -rf "$tmpdir"' EXIT
fresh_home="$tmpdir/fresh-home" fresh_home="$tmpdir/fresh-home"
mkdir -p "$fresh_home" mkdir -p "$fresh_home"
fresh_output=$(run_application_bindings "$fresh_home") fresh_output=$(run_application_bindings "$fresh_home")
grep -Fq $'SUPER + RETURN Terminal' <<<"$fresh_output" || fail "default application bindings include essentials" grep -Fq $'SUPER + RETURN 终端' <<<"$fresh_output" || fail "default application bindings include essentials"
grep -Fq $'SUPER + SHIFT + A ChatGPT' <<<"$fresh_output" || fail "default application bindings include preinstalled web apps" grep -Fq $'SUPER + SHIFT + A ChatGPT' <<<"$fresh_output" || fail "default application bindings include preinstalled web apps"
pass "default application bindings load from package defaults" pass "default application bindings load from package defaults"
@@ -123,7 +123,7 @@ removed_home="$tmpdir/removed-home"
mkdir -p "$removed_home/.local/state/omarchy" mkdir -p "$removed_home/.local/state/omarchy"
touch "$removed_home/.local/state/omarchy/preinstalls-removed" touch "$removed_home/.local/state/omarchy/preinstalls-removed"
removed_output=$(run_application_bindings "$removed_home") removed_output=$(run_application_bindings "$removed_home")
grep -Fq $'SUPER + RETURN Terminal' <<<"$removed_output" || fail "preinstall removal keeps essential bindings" grep -Fq $'SUPER + RETURN 终端' <<<"$removed_output" || fail "preinstall removal keeps essential bindings"
if grep -Fq $'SUPER + SHIFT + A ChatGPT' <<<"$removed_output"; then if grep -Fq $'SUPER + SHIFT + A ChatGPT' <<<"$removed_output"; then
fail "preinstall removal skips preinstalled web app bindings" fail "preinstall removal skips preinstalled web app bindings"
fi fi
@@ -132,7 +132,7 @@ pass "preinstall removal flag skips optional application bindings"
variable_home="$tmpdir/variable-home" variable_home="$tmpdir/variable-home"
mkdir -p "$variable_home" mkdir -p "$variable_home"
variable_output=$(run_application_bindings "$variable_home" 'omarchy_preinstalled_bindings = false') variable_output=$(run_application_bindings "$variable_home" 'omarchy_preinstalled_bindings = false')
grep -Fq $'SUPER + RETURN Terminal' <<<"$variable_output" || fail "preinstalled binding variable keeps essential bindings" grep -Fq $'SUPER + RETURN 终端' <<<"$variable_output" || fail "preinstalled binding variable keeps essential bindings"
if grep -Fq $'SUPER + SHIFT + A ChatGPT' <<<"$variable_output"; then if grep -Fq $'SUPER + SHIFT + A ChatGPT' <<<"$variable_output"; then
fail "preinstalled binding variable skips optional application bindings" fail "preinstalled binding variable skips optional application bindings"
fi fi
@@ -150,17 +150,17 @@ mkdir -p "$voxtype_home" "$voxtype_bin"
touch "$voxtype_bin/voxtype" touch "$voxtype_bin/voxtype"
chmod +x "$voxtype_bin/voxtype" chmod +x "$voxtype_bin/voxtype"
voxtype_output=$(PATH="$voxtype_bin:$PATH" run_omarchy_bindings "$voxtype_home") voxtype_output=$(PATH="$voxtype_bin:$PATH" run_omarchy_bindings "$voxtype_home")
grep -Fq $'SUPER + CTRL + X Toggle dictation' <<<"$voxtype_output" || grep -Fq $'SUPER + CTRL + X 切换语音听写' <<<"$voxtype_output" ||
fail "installed Voxtype enables its toggle binding" fail "installed Voxtype enables its toggle binding"
grep -Fq $'F9 Start dictation (push-to-talk)' <<<"$voxtype_output" || grep -Fq $'F9 开始听写(按住说话)' <<<"$voxtype_output" ||
fail "installed Voxtype enables its push-to-talk binding" fail "installed Voxtype enables its push-to-talk binding"
grep -Fq $'F9 Stop dictation (push-to-talk)' <<<"$voxtype_output" || grep -Fq $'F9 停止听写(按住说话)' <<<"$voxtype_output" ||
fail "installed Voxtype enables its release binding" fail "installed Voxtype enables its release binding"
pass "installed Voxtype conditionally enables dictation bindings" pass "installed Voxtype conditionally enables dictation bindings"
voxtype_without_execute_output=$(PATH="$voxtype_bin:$PATH" run_omarchy_bindings \ voxtype_without_execute_output=$(PATH="$voxtype_bin:$PATH" run_omarchy_bindings \
"$voxtype_home" 'os.execute = function() return nil, "No child processes", 10 end') "$voxtype_home" 'os.execute = function() return nil, "No child processes", 10 end')
grep -Fq $'SUPER + CTRL + X Toggle dictation' <<<"$voxtype_without_execute_output" || grep -Fq $'SUPER + CTRL + X 切换语音听写' <<<"$voxtype_without_execute_output" ||
fail "Voxtype detection does not require spawning a subprocess" fail "Voxtype detection does not require spawning a subprocess"
pass "installed Voxtype detection works without os.execute" pass "installed Voxtype detection works without os.execute"
@@ -170,7 +170,7 @@ ln -s "$(command -v lua)" "$missing_bin/lua"
ln -s "$(command -v lspci)" "$missing_bin/lspci" ln -s "$(command -v lspci)" "$missing_bin/lspci"
ln -s "$(command -v sort)" "$missing_bin/sort" ln -s "$(command -v sort)" "$missing_bin/sort"
missing_voxtype_output=$(PATH="$missing_bin" run_omarchy_bindings "$voxtype_home") missing_voxtype_output=$(PATH="$missing_bin" run_omarchy_bindings "$voxtype_home")
if grep -Fq $'SUPER + CTRL + X Toggle dictation' <<<"$missing_voxtype_output"; then if grep -Fq $'SUPER + CTRL + X 切换语音听写' <<<"$missing_voxtype_output"; then
fail "missing Voxtype skips its bindings" fail "missing Voxtype skips its bindings"
fi fi
pass "missing Voxtype skips dictation bindings" pass "missing Voxtype skips dictation bindings"
@@ -180,13 +180,13 @@ pass "missing Voxtype skips dictation bindings"
scratchpad_home="$tmpdir/scratchpad-home" scratchpad_home="$tmpdir/scratchpad-home"
mkdir -p "$scratchpad_home" mkdir -p "$scratchpad_home"
scratchpad_output=$(run_omarchy_bindings "$scratchpad_home") scratchpad_output=$(run_omarchy_bindings "$scratchpad_home")
grep -Fqx $'SUPER + S Toggle scratchpad' <<<"$scratchpad_output" || grep -Fqx $'SUPER + S 切换便签区' <<<"$scratchpad_output" ||
fail "scratchpad keeps its existing toggle binding" fail "scratchpad keeps its existing toggle binding"
grep -Fqx $'SUPER + grave Toggle scratchpad' <<<"$scratchpad_output" || grep -Fqx $'SUPER + grave 切换便签区' <<<"$scratchpad_output" ||
fail "scratchpad supports a Quake-style toggle binding" fail "scratchpad supports a Quake-style toggle binding"
grep -Fqx $'SUPER + ALT + S Move window to scratchpad' <<<"$scratchpad_output" || grep -Fqx $'SUPER + ALT + S 窗口移入便签区' <<<"$scratchpad_output" ||
fail "scratchpad keeps its existing move binding" fail "scratchpad keeps its existing move binding"
grep -Fqx $'SUPER + SHIFT + grave Move window to scratchpad' <<<"$scratchpad_output" || grep -Fqx $'SUPER + SHIFT + grave 窗口移入便签区' <<<"$scratchpad_output" ||
fail "scratchpad supports a Quake-style move binding" fail "scratchpad supports a Quake-style move binding"
pass "scratchpad retains existing bindings and adds Grave shortcuts" pass "scratchpad retains existing bindings and adds Grave shortcuts"
@@ -197,7 +197,7 @@ panels_home="$tmpdir/panels-home"
mkdir -p "$panels_home" mkdir -p "$panels_home"
panels_output=$(run_omarchy_bindings "$panels_home") panels_output=$(run_omarchy_bindings "$panels_home")
for panel in 1 2 3 4 5 6 7 8 9; do for panel in 1 2 3 4 5 6 7 8 9; do
grep -Fqx "SUPER + CTRL + code:$((panel + 9))"$'\t'"Bar panel $panel" <<<"$panels_output" || grep -Fqx "SUPER + CTRL + code:$((panel + 9))"$'\t'"顶栏面板 $panel" <<<"$panels_output" ||
fail "bar panel hotkeys count the right section" "$panel" fail "bar panel hotkeys count the right section" "$panel"
done done
number_claims=$(cut -f1 <<<"$panels_output" | grep -cE '^SUPER \+ CTRL \+ code:1[0-9]$' || true) number_claims=$(cut -f1 <<<"$panels_output" | grep -cE '^SUPER \+ CTRL \+ code:1[0-9]$' || true)
+38 -38
View File
@@ -50,24 +50,24 @@ keybindings() {
# binds twice on purpose. The last bind carries the longest description Omarchy # binds twice on purpose. The last bind carries the longest description Omarchy
# ships, which is what puts a row closest to the width the menu allows. # ships, which is what puts a row closest to the width the menu allows.
stub_hyprctl <<BINDS stub_hyprctl <<BINDS
$(lua_bind 64 "SUPER + W" "Close window") $(lua_bind 64 "SUPER + W" "关闭窗口")
$(lua_bind 64 "SUPER + Q" "Close window") $(lua_bind 64 "SUPER + Q" "关闭窗口")
$(lua_bind 64 "SUPER + F" "Full screen") $(lua_bind 64 "SUPER + F" "全屏")
$(lua_bind 64 "SUPER + S" "Toggle scratchpad") $(lua_bind 64 "SUPER + S" "切换便签区")
$(lua_bind 64 "SUPER + grave" "Toggle scratchpad") $(lua_bind 64 "SUPER + grave" "切换便签区")
$(exec_bind 73 "SUPER SHIFT ALT + 0" "Move window silently to workspace 10" "true") $(exec_bind 73 "SUPER SHIFT ALT + 0" "窗口静默移到工作区 10" "true")
BINDS BINDS
rendered=$(keybindings) rendered=$(keybindings)
[[ -n $rendered ]] || fail "the keybindings menu renders with a stubbed Hyprland" [[ -n $rendered ]] || fail "the keybindings menu renders with a stubbed Hyprland"
grep -q 'SUPER + F *→ Full screen' <<<"$rendered" || grep -q 'SUPER + F *→ 全屏' <<<"$rendered" ||
fail "a chord with no alternative renders on its own" "$rendered" fail "a chord with no alternative renders on its own" "$rendered"
pass "the keybindings menu renders its entries" pass "the keybindings menu renders its entries"
(( $(grep -c '→ Close window$' <<<"$rendered") == 1 )) || (( $(grep -c '→ 关闭窗口$' <<<"$rendered") == 1 )) ||
fail "an alternative chord joins the row of the first one" "$rendered" fail "an alternative chord joins the row of the first one" "$rendered"
grep -q 'SUPER + W / SUPER + Q *→ Close window' <<<"$rendered" || grep -q 'SUPER + W / SUPER + Q *→ 关闭窗口' <<<"$rendered" ||
fail "a shared row names both chords" "$rendered" fail "a shared row names both chords" "$rendered"
pass "an alternative chord joins the row of the first one" pass "an alternative chord joins the row of the first one"
@@ -78,7 +78,7 @@ grep -q '^SUPER + W / SUPER + Q' <<<"$rendered" ||
pass "the chord declared first leads a shared row" pass "the chord declared first leads a shared row"
# Hyprland calls the key left of 1 "grave". Nobody reads their keyboard that way. # Hyprland calls the key left of 1 "grave". Nobody reads their keyboard that way.
grep -q 'SUPER + S / SUPER + ~ *→ Toggle scratchpad' <<<"$rendered" || grep -q 'SUPER + S / SUPER + ~ *→ 切换便签区' <<<"$rendered" ||
fail "the grave key reads as the symbol printed on it" "$rendered" fail "the grave key reads as the symbol printed on it" "$rendered"
! grep -q 'grave' <<<"$rendered" || ! grep -q 'grave' <<<"$rendered" ||
fail "no entry still says grave" "$rendered" fail "no entry still says grave" "$rendered"
@@ -101,14 +101,14 @@ pass "no entry outgrows the width the menu gives it"
# the entry: XF86Calculator alone belongs in the tail the menu keeps for media # the entry: XF86Calculator alone belongs in the tail the menu keeps for media
# keys, while the calculator itself sits in the body of the list. # keys, while the calculator itself sits in the body of the list.
stub_hyprctl <<BINDS stub_hyprctl <<BINDS
$(exec_bind 68 "SUPER CTRL + Q" "Calculator" "omacalc") $(exec_bind 68 "SUPER CTRL + Q" "计算器" "omacalc")
$(exec_bind 0 "XF86Calculator" "Calculator" "omacalc") $(exec_bind 0 "XF86Calculator" "计算器" "omacalc")
$(exec_bind 8 "ALT + TAB" "Reveal active window on top" "true") $(exec_bind 8 "ALT + TAB" "活动窗口置顶显示" "true")
BINDS BINDS
rendered=$(keybindings) rendered=$(keybindings)
(( $(grep -n '→ Calculator$' <<<"$rendered" | cut -d: -f1) < (( $(grep -n '→ 计算器$' <<<"$rendered" | cut -d: -f1) <
$(grep -n '→ Reveal active window on top$' <<<"$rendered" | cut -d: -f1) )) || $(grep -n '→ 活动窗口置顶显示$' <<<"$rendered" | cut -d: -f1) )) ||
fail "a shared chord does not change where its entry ranks" "$rendered" fail "a shared chord does not change where its entry ranks" "$rendered"
pass "a shared chord does not change where its entry ranks" pass "a shared chord does not change where its entry ranks"
@@ -121,51 +121,51 @@ bind
key: key:
keycode: 49 keycode: 49
catchall: false catchall: false
description: Toggle scratchpad description: 切换便签区
dispatcher: exec dispatcher: exec
arg: true arg: true
BINDS BINDS
rendered=$(keybindings) rendered=$(keybindings)
grep -q 'SUPER + ~ *→ Toggle scratchpad' <<<"$rendered" || grep -q 'SUPER + ~ *→ 切换便签区' <<<"$rendered" ||
fail "a keycode resolves to the symbol printed on the key too" "$rendered" fail "a keycode resolves to the symbol printed on the key too" "$rendered"
pass "a keycode resolves to the symbol printed on the key too" pass "a keycode resolves to the symbol printed on the key too"
# A chord refused for width opens a row of its own, and the next chord tries # A chord refused for width opens a row of its own, and the next chord tries
# that row rather than reaching back past it and printing out of order. # that row rather than reaching back past it and printing out of order.
stub_hyprctl <<BINDS stub_hyprctl <<BINDS
$(exec_bind 64 "SUPER + A" "Calculator" "omacalc") $(exec_bind 64 "SUPER + A" "计算器" "omacalc")
$(exec_bind 77 "SUPER SHIFT CTRL ALT + BACKSPACE" "Calculator" "omacalc") $(exec_bind 77 "SUPER SHIFT CTRL ALT + BACKSPACE" "计算器" "omacalc")
$(exec_bind 64 "SUPER + B" "Calculator" "omacalc") $(exec_bind 64 "SUPER + B" "计算器" "omacalc")
BINDS BINDS
rendered=$(keybindings) rendered=$(keybindings)
(( $(grep -c '→ Calculator$' <<<"$rendered") == 3 )) || (( $(grep -c '→ 计算器$' <<<"$rendered") == 3 )) ||
fail "a refused chord does not let the next one jump the queue" "$rendered" fail "a refused chord does not let the next one jump the queue" "$rendered"
pass "a refused chord does not let the next one jump the queue" pass "a refused chord does not let the next one jump the queue"
# Sharing a row is something Omarchy names an action for, not something two # Sharing a row is something Omarchy names an action for, not something two
# chords earn by looking alike. Alt + Tab and Shift + Alt + Tab both read # chords earn by looking alike. Alt + Tab and Shift + Alt + Tab both read
# "Reveal active window on top" and cycle opposite ways. # "活动窗口置顶显示" and cycle opposite ways.
stub_hyprctl <<BINDS stub_hyprctl <<BINDS
$(exec_bind 64 "SUPER + Y" "Zoom in" "omarchy-zoom in") $(exec_bind 64 "SUPER + Y" "放大" "omarchy-zoom in")
$(exec_bind 64 "SUPER + Z" "Zoom in" "omarchy-zoom in") $(exec_bind 64 "SUPER + Z" "放大" "omarchy-zoom in")
BINDS BINDS
rendered=$(keybindings) rendered=$(keybindings)
(( $(grep -c '→ Zoom in$' <<<"$rendered") == 2 )) || (( $(grep -c '→ 放大$' <<<"$rendered") == 2 )) ||
fail "an action Omarchy did not name keeps its chords on separate rows" "$rendered" fail "an action Omarchy did not name keeps its chords on separate rows" "$rendered"
pass "an action Omarchy did not name keeps its chords on separate rows" pass "an action Omarchy did not name keeps its chords on separate rows"
# Even a named action gives up the shared row rather than overrun the column: # Even a named action gives up the shared row rather than overrun the column:
# two rows in line beat one that juts out of it. # two rows in line beat one that juts out of it.
stub_hyprctl <<BINDS stub_hyprctl <<BINDS
$(exec_bind 73 "SUPER SHIFT ALT + BACKSPACE" "Calculator" "omacalc") $(exec_bind 73 "SUPER SHIFT ALT + BACKSPACE" "计算器" "omacalc")
$(exec_bind 69 "SUPER SHIFT CTRL + BACKSPACE" "Calculator" "omacalc") $(exec_bind 69 "SUPER SHIFT CTRL + BACKSPACE" "计算器" "omacalc")
BINDS BINDS
rendered=$(keybindings) rendered=$(keybindings)
(( $(grep -c '→ Calculator$' <<<"$rendered") == 2 )) || (( $(grep -c '→ 计算器$' <<<"$rendered") == 2 )) ||
fail "chords too wide to share a row stay on their own" "$rendered" fail "chords too wide to share a row stay on their own" "$rendered"
[[ $(awk -F '→' '{ print length($1) }' <<<"$rendered" | sort -u) == "36" ]] || [[ $(awk -F '→' '{ print length($1) }' <<<"$rendered" | sort -u) == "36" ]] ||
fail "chords too wide to share a row leave the column alone" "$rendered" fail "chords too wide to share a row leave the column alone" "$rendered"
@@ -174,24 +174,24 @@ pass "chords too wide to share a row stay on their own"
# A shared label is not a shared action. Two chords that merely read alike have # A shared label is not a shared action. Two chords that merely read alike have
# to stay apart, or the menu hides one of them behind the other. # to stay apart, or the menu hides one of them behind the other.
stub_hyprctl <<BINDS stub_hyprctl <<BINDS
$(lua_bind 64 "SUPER + W" "Close window") $(lua_bind 64 "SUPER + W" "关闭窗口")
$(exec_bind 64 "SUPER + X" "Close window" "omarchy-hyprland-window-close-all") $(exec_bind 64 "SUPER + X" "关闭窗口" "omarchy-hyprland-window-close-all")
BINDS BINDS
rendered=$(keybindings) rendered=$(keybindings)
(( $(grep -c '→ Close window$' <<<"$rendered") == 2 )) || (( $(grep -c '→ 关闭窗口$' <<<"$rendered") == 2 )) ||
fail "chords with the same label but different actions stay apart" "$rendered" fail "chords with the same label but different actions stay apart" "$rendered"
pass "chords with the same label but different actions stay apart" pass "chords with the same label but different actions stay apart"
# An unresolved Lua bind reports no dispatcher at all, so nothing says the two # An unresolved Lua bind reports no dispatcher at all, so nothing says the two
# chords run the same thing, whatever their label promises. # chords run the same thing, whatever their label promises.
stub_hyprctl <<BINDS stub_hyprctl <<BINDS
$(lua_bind 64 "SUPER + Y" "Close window") $(lua_bind 64 "SUPER + Y" "关闭窗口")
$(lua_bind 64 "SUPER + Z" "Close window") $(lua_bind 64 "SUPER + Z" "关闭窗口")
BINDS BINDS
rendered=$(keybindings) rendered=$(keybindings)
(( $(grep -c '→ Close window$' <<<"$rendered") == 2 )) || (( $(grep -c '→ 关闭窗口$' <<<"$rendered") == 2 )) ||
fail "chords whose dispatch is unknown stay apart" "$rendered" fail "chords whose dispatch is unknown stay apart" "$rendered"
pass "chords whose dispatch is unknown stay apart" pass "chords whose dispatch is unknown stay apart"
@@ -199,10 +199,10 @@ pass "chords whose dispatch is unknown stay apart"
# the script, so dropping an action from the list fails instead of shrinking # the script, so dropping an action from the list fails instead of shrinking
# what gets checked. # what gets checked.
expected_alternatives=( expected_alternatives=(
"Close window" "关闭窗口"
"Calculator" "计算器"
"Toggle scratchpad" "切换便签区"
"Move window to scratchpad" "窗口移入便签区"
) )
eval "$(sed -n '/^alternative_chord_actions()/,/^}/p' "$ROOT/bin/omarchy-menu-keybindings")" eval "$(sed -n '/^alternative_chord_actions()/,/^}/p' "$ROOT/bin/omarchy-menu-keybindings")"
+7 -3
View File
@@ -152,9 +152,13 @@ assert(
'menu ranks an app matching the query as a whole word above exact-labeled menu entries' 'menu ranks an app matching the query as a whole word above exact-labeled menu entries'
) )
assert( assert(
rankScore('style.font', 'font') < rankScore('apps.fontforge', 'font'), rankScore('style.font', '字体') < rankScore('apps.fontforge', '字体'),
'menu keeps a better-matching menu entry above a weaker app match' 'menu keeps a better-matching menu entry above a weaker app match'
) )
assert(
rankScore('style.font', 'font') < rankScore('style.background', 'font'),
'menu still reaches localized entries through their English leaf id'
)
// Routing: htop ships `Keywords=system;...`, which app rows carry as aliases. // Routing: htop ships `Keywords=system;...`, which app rows carry as aliases.
// An installed app must never capture a menu route (SUPER+ESCAPE opens the // An installed app must never capture a menu route (SUPER+ESCAPE opens the
@@ -244,7 +248,7 @@ assertDeepEqual(
defaultItems defaultItems
.filter(item => item.parent === 'setup.default.agent') .filter(item => item.parent === 'setup.default.agent')
.map(item => item.label), .map(item => item.label),
['Antigravity', 'Claude', 'Codex', 'Copilot', 'Crush', 'Grok', 'omp', 'OpenCode', 'Ori', 'Pi'], ['Antigravity', 'Claude', 'Codex', 'Copilot', 'Crush', 'Deep Code', 'Dim Agent', 'DSH', 'Grok', 'Kimi Code', 'omp', 'OpenCode', 'Ori', 'Pi', '国产模型组合 (AI Hub)'],
'menu sorts coding agents alphabetically' 'menu sorts coding agents alphabetically'
) )
const expectedDefaults = { const expectedDefaults = {
@@ -338,7 +342,7 @@ assertEqual(
) )
assertDeepEqual( assertDeepEqual(
defaultItems.filter(item => item.parent === 'setup.plugin').map(item => item.label), defaultItems.filter(item => item.parent === 'setup.plugin').map(item => item.label),
['Enable Plugin', 'Disable Plugin', 'Add Plugin', 'Clone Plugin', 'Remove Plugin'], ['启用插件', '停用插件', '添加插件', '克隆插件', '移除插件'],
'menu manages plugins from Setup > Plugins' 'menu manages plugins from Setup > Plugins'
) )
assert( assert(
+33 -3
View File
@@ -34,10 +34,15 @@ export PATH="$TEST_HOME/stubs:$PATH"
for reg in ai-providers ai-harnesses ai-compatibility; do for reg in ai-providers ai-harnesses ai-compatibility; do
jq -e . "$ROOT/cn/registry/$reg.json" > /dev/null || fail "$reg.json parses" jq -e . "$ROOT/cn/registry/$reg.json" > /dev/null || fail "$reg.json parses"
done done
for p in deepseek kimi zai; do for p in deepseek kimi zai minimax; do
jq -e --arg p "$p" '.providers[$p].endpoints.anthropic // .providers[$p].endpoints.openai' \ jq -e --arg p "$p" '.providers[$p].endpoints.anthropic // .providers[$p].endpoints.openai' \
"$ROOT/cn/registry/ai-providers.json" > /dev/null || fail "provider $p has an endpoint" "$ROOT/cn/registry/ai-providers.json" > /dev/null || fail "provider $p has an endpoint"
done done
jq -e '.providers.ollama | (.static_token == "ollama") and (.models_dynamic == true)
and (.endpoints.anthropic == "http://localhost:11434")' \
"$ROOT/cn/registry/ai-providers.json" > /dev/null || fail "ollama provider contract"
jq -e '.combos["claude-code"].ollama.adapter' \
"$ROOT/cn/registry/ai-compatibility.json" > /dev/null || fail "claude-code x ollama combo present"
pass "AI registries parse with P0 providers" pass "AI registries parse with P0 providers"
# Secret file backend roundtrip with 0600 # Secret file backend roundtrip with 0600
@@ -59,21 +64,37 @@ fi
if omarchy-cn-ai-profile-create bad codex deepseek "deepseek-v4-pro[1m]" > /dev/null 2>&1; then if omarchy-cn-ai-profile-create bad codex deepseek "deepseek-v4-pro[1m]" > /dev/null 2>&1; then
fail "codex rejects provider-namespace slug" fail "codex rejects provider-namespace slug"
fi fi
omarchy-cn-ai-profile-create loc claude-code ollama qwen3-coder > /dev/null ||
fail "dynamic-model provider accepts a runtime-listed model"
pass "profile validation enforces combos, protocols, and allowlists" pass "profile validation enforces combos, protocols, and allowlists"
# Static-token provider needs no stored secret; absent fields stay silent
source "$ROOT/cn/lib/ai.sh"
[[ $(cn_ai_resolve_key ollama) == "ollama" ]] || fail "ollama resolves its static token"
static_out=$(cn_ai_static_token deepseek || true)
[[ -z $static_out ]] || fail "absent static_token must print nothing" "$static_out"
pass "static token resolution: fixed ollama key, silent absent field"
# claude-code env render for all three providers, exact endpoints # claude-code env render for all three providers, exact endpoints
source "$ROOT/cn/lib/ai.sh" source "$ROOT/cn/lib/ai.sh"
declare -A bases=( declare -A bases=(
[deepseek]="https://api.deepseek.com/anthropic" [deepseek]="https://api.deepseek.com/anthropic"
[kimi]="https://api.kimi.com/coding/" [kimi]="https://api.kimi.com/coding/"
[zai]="https://api.z.ai/api/anthropic" [zai]="https://api.z.ai/api/anthropic"
[minimax]="https://api.minimaxi.com/anthropic"
) )
for p in deepseek kimi zai; do for p in deepseek kimi zai minimax; do
out=$(cn_ai_render_env claude-code "$p" test-model sk-x) out=$(cn_ai_render_env claude-code "$p" test-model sk-x)
grep -qF "ANTHROPIC_BASE_URL=${bases[$p]}" <<<"$out" || fail "claude-code $p base url" "$out" grep -qF "ANTHROPIC_BASE_URL=${bases[$p]}" <<<"$out" || fail "claude-code $p base url" "$out"
grep -q "ANTHROPIC_AUTH_TOKEN=sk-x" <<<"$out" || fail "claude-code $p auth token" grep -q "ANTHROPIC_AUTH_TOKEN=sk-x" <<<"$out" || fail "claude-code $p auth token"
grep -q "ANTHROPIC_API_KEY=sk-x" <<<"$out" || fail "claude-code $p api key" grep -q "ANTHROPIC_API_KEY=sk-x" <<<"$out" || fail "claude-code $p api key"
done done
out=$(cn_ai_render_env claude-code minimax "MiniMax-M3[1m]" sk-x)
grep -qF "ANTHROPIC_DEFAULT_HAIKU_MODEL=MiniMax-M3" <<<"$out" || fail "minimax haiku slot falls back to default-coding"
out=$(cn_ai_render_env claude-code ollama qwen3-coder "$(cn_ai_resolve_key ollama)")
grep -qF "ANTHROPIC_BASE_URL=http://localhost:11434" <<<"$out" || fail "ollama base url" "$out"
grep -q "ANTHROPIC_AUTH_TOKEN=ollama" <<<"$out" || fail "ollama static token rendered"
grep -qF "ANTHROPIC_DEFAULT_HAIKU_MODEL=qwen3-coder" <<<"$out" || fail "ollama haiku slot falls back to the chosen model"
out=$(cn_ai_render_env opencode deepseek test-model sk-x) out=$(cn_ai_render_env opencode deepseek test-model sk-x)
grep -q "DEEPSEEK_API_KEY=sk-x" <<<"$out" || fail "opencode deepseek env" grep -q "DEEPSEEK_API_KEY=sk-x" <<<"$out" || fail "opencode deepseek env"
if cn_ai_render_env opencode zai m k > /dev/null 2>&1; then if cn_ai_render_env opencode zai m k > /dev/null 2>&1; then
@@ -104,7 +125,7 @@ class H(http.server.BaseHTTPRequestHandler):
def do_POST(self): def do_POST(self):
body = self.rfile.read(int(self.headers.get("Content-Length", 0))) body = self.rfile.read(int(self.headers.get("Content-Length", 0)))
key = self.headers.get("x-api-key") or (self.headers.get("Authorization") or "").replace("Bearer ", "") key = self.headers.get("x-api-key") or (self.headers.get("Authorization") or "").replace("Bearer ", "")
if key != "sk-secret-1": if key not in ("sk-secret-1", "ollama"):
code = 401 code = 401
elif self.path == "/v1/messages" and b"messages" in body and self.headers.get("anthropic-version"): elif self.path == "/v1/messages" and b"messages" in body and self.headers.get("anthropic-version"):
code = 200 code = 200
@@ -128,6 +149,7 @@ done
OMARCHYCN_AI_TEST_BASE_URL="http://127.0.0.1:$port" omarchy-cn-ai-test good | grep -q "PASS" || fail "anthropic mock 200" OMARCHYCN_AI_TEST_BASE_URL="http://127.0.0.1:$port" omarchy-cn-ai-test good | grep -q "PASS" || fail "anthropic mock 200"
OMARCHYCN_AI_TEST_BASE_URL="http://127.0.0.1:$port" omarchy-cn-ai-test cdx | grep -q "PASS" || fail "codex responses mock 200" OMARCHYCN_AI_TEST_BASE_URL="http://127.0.0.1:$port" omarchy-cn-ai-test cdx | grep -q "PASS" || fail "codex responses mock 200"
OMARCHYCN_AI_TEST_BASE_URL="http://127.0.0.1:$port" omarchy-cn-ai-test loc | grep -q "PASS" || fail "ollama static-token mock 200"
echo "wrong-key" | omarchy-cn-ai-secret set deepseek > /dev/null echo "wrong-key" | omarchy-cn-ai-secret set deepseek > /dev/null
if OMARCHYCN_AI_TEST_BASE_URL="http://127.0.0.1:$port" omarchy-cn-ai-test good > /dev/null 2>&1; then if OMARCHYCN_AI_TEST_BASE_URL="http://127.0.0.1:$port" omarchy-cn-ai-test good > /dev/null 2>&1; then
fail "anthropic mock 401 fails the test" fail "anthropic mock 401 fails the test"
@@ -162,3 +184,11 @@ PATH="$restricted" omarchy-cn-ai-default good > /dev/null
[[ $(stat -c %a "$HOME/.claude/settings.json") == 600 ]] || fail "claude settings 0600" [[ $(stat -c %a "$HOME/.claude/settings.json") == 600 ]] || fail "claude settings 0600"
[[ -f $TEST_HOME/installer-ran ]] || fail "missing harness triggered installer" [[ -f $TEST_HOME/installer-ran ]] || fail "missing harness triggered installer"
pass "ai-default maps the profile onto the upstream agent entry" pass "ai-default maps the profile onto the upstream agent entry"
# ai-default with the static-token local provider writes the official contract
PATH="$restricted" omarchy-cn-ai-default loc > /dev/null
[[ $(jq -r '.env.ANTHROPIC_BASE_URL' "$HOME/.claude/settings.json") == "http://localhost:11434" ]] || fail "ollama ai-default base url"
[[ $(jq -r '.env.ANTHROPIC_AUTH_TOKEN' "$HOME/.claude/settings.json") == "ollama" ]] || fail "ollama ai-default static token"
[[ $(jq -r '.env.ANTHROPIC_DEFAULT_HAIKU_MODEL' "$HOME/.claude/settings.json") == "qwen3-coder" ]] || fail "ollama ai-default haiku fallback"
[[ $(jq -r '.env.KEEP' "$HOME/.claude/settings.json") == 1 ]] || fail "ollama ai-default preserves user env"
pass "ai-default renders the ollama static-token contract"
+29
View File
@@ -80,6 +80,35 @@ if missing or not weak_appends:
PYEOF PYEOF
pass "fontconfig priority file carries SC/JP/KR rules and weak fallback" pass "fontconfig priority file carries SC/JP/KR rules and weak fallback"
# [omarchy] mirror wiring: stable is mirror-first with upstream fallback
mapfile -t stable_servers < <(sed -n '/^\[omarchy\]/,$p' "$ROOT/default/pacman/pacman-stable.conf" | grep '^Server = ')
[[ ${stable_servers[0]:-} == "Server = https://git.zacharyzhang.com/api/packages/ZacharyZhang-NY/arch/omarchy/x86_64" ]] ||
fail "stable conf lists the OmarchyCN mirror first" "${stable_servers[0]:-none}"
[[ ${stable_servers[1]:-} == 'Server = https://pkgs.omarchy.org/stable/$arch' ]] ||
fail "stable conf keeps the upstream fallback second" "${stable_servers[1]:-none}"
for ch in edge rc; do
if grep -q git.zacharyzhang.com "$ROOT/default/pacman/pacman-$ch.conf"; then
fail "$ch conf must stay upstream-only (mirror carries stable only)"
fi
done
bash -n "$ROOT/cn/migrations/1787861071.sh" || fail "mirror migration parses"
grep -q "pacman-key --add" "$ROOT/install/post-install/pacman.sh" || fail "install imports the registry key"
pass "[omarchy] mirror wiring: stable mirror-first, edge/rc untouched, key import present"
# Mirror-line guard: comments and substrings must not count as present
tmpconf=$(mktemp)
printf 'Server = https://pkgs.omarchy.org/stable/$arch\n' > "$tmpconf"
(
source "$ROOT/cn/lib/mirror.sh"
OMARCHYCN_PACMAN_CONF=$tmpconf cn_mirror_omarchy_repo_ok && exit 1
printf '# Server = %s\n' "$CN_OMARCHY_MIRROR" >> "$tmpconf"
OMARCHYCN_PACMAN_CONF=$tmpconf cn_mirror_omarchy_repo_ok && exit 1
printf 'Server = %s\n' "$CN_OMARCHY_MIRROR" >> "$tmpconf"
OMARCHYCN_PACMAN_CONF=$tmpconf cn_mirror_omarchy_repo_ok
) || fail "omarchy repo guard exact-line semantics"
rm -f "$tmpconf"
pass "omarchy mirror guard ignores comments and matches only the exact line"
# 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");
+2 -2
View File
@@ -282,9 +282,9 @@ pass "webcam sizes stay distinct and inside a narrow region"
rm -f "$region_file" rm -f "$region_file"
grep -F 'o.bind("SUPER + ALT + code:34", "Make webcam overlay smaller", "omarchy-capture-webcam-resize smaller")' \ grep -F 'o.bind("SUPER + ALT + code:34", "缩小摄像头悬浮窗", "omarchy-capture-webcam-resize smaller")' \
"$ROOT/default/hypr/bindings/utilities.lua" >/dev/null || fail "webcam smaller hotkey is configured" "$ROOT/default/hypr/bindings/utilities.lua" >/dev/null || fail "webcam smaller hotkey is configured"
grep -F 'o.bind("SUPER + ALT + code:35", "Make webcam overlay larger", "omarchy-capture-webcam-resize larger")' \ grep -F 'o.bind("SUPER + ALT + code:35", "放大摄像头悬浮窗", "omarchy-capture-webcam-resize larger")' \
"$ROOT/default/hypr/bindings/utilities.lua" >/dev/null || fail "webcam larger hotkey is configured" "$ROOT/default/hypr/bindings/utilities.lua" >/dev/null || fail "webcam larger hotkey is configured"
pass "webcam resize hotkeys are configured" pass "webcam resize hotkeys are configured"
+1 -1
View File
@@ -129,7 +129,7 @@ pass "disk-space threshold includes the exact boundary"
rm -f "$snapshot_marker" "$gum_marker" rm -f "$snapshot_marker" "$gum_marker"
GUM_STATUS=0 TEST_AVAILABLE_BYTES=$((10 * 1024 * 1024 * 1024)) run_update >/dev/null GUM_STATUS=0 TEST_AVAILABLE_BYTES=$((10 * 1024 * 1024 * 1024)) run_update >/dev/null
grep -q "confirm Continue with update?" "$gum_marker" || grep -q "confirm 继续更新?" "$gum_marker" ||
fail "interactive update with enough space uses the normal confirmation prompt" fail "interactive update with enough space uses the normal confirmation prompt"
[[ -f $snapshot_marker ]] || fail "accepting the normal confirmation starts the update" [[ -f $snapshot_marker ]] || fail "accepting the normal confirmation starts the update"
pass "interactive update keeps the normal confirmation prompt when space is sufficient" pass "interactive update keeps the normal confirmation prompt when space is sufficient"
-30
View File
@@ -1,30 +0,0 @@
#!/bin/bash
source "$(dirname "${BASH_SOURCE[0]}")/base-test.sh"
require_command jq
require_command node
EXT_DIR="$ROOT/default/chromium/extensions/whatsapp-slim"
jq -e '
.content_scripts[0].js == ["system-theme.js"] and
.content_scripts[0].run_at == "document_start"
' "$EXT_DIR/manifest.json" >/dev/null || fail "WhatsApp enables system theming before startup"
mode=$(node - "$EXT_DIR/system-theme.js" <<'JS'
const fs = require("fs")
const values = new Map()
let reloaded = false
global.localStorage = {
getItem: key => values.get(key),
setItem: (key, value) => values.set(key, value),
}
global.location = { reload: () => { reloaded = true } }
eval(fs.readFileSync(process.argv[2], "utf8"))
process.stdout.write(`${values.get("system-theme-mode")}:${reloaded}`)
JS
)
[[ $mode == "true:true" ]] || fail "WhatsApp selects its system theme mode" "$mode"
pass "WhatsApp follows the system theme through its existing slim extension"