Author SHA1 Message Date
ZacharyZhang-NY 4505badecb Add Dim and Kimi Code to the agent roster and Install > AI
Both install through the lazy mise wrappers (npm:dimcode and
npm:@moonshot-ai/kimi-code), preinstalled on new machines and migrated onto
existing ones unless preinstalls were removed, and each gets a menu entry in
both places: under Setup > Defaults > Agent as a default-agent choice, and
under Install > AI for installing without changing the default. The launch
spellings come from each CLI's actual flags — bare dim is the TUI and `dim
exec` the one-shot, kimi runs full-auto as `kimi --auto` with `--prompt` as
its one-shot. The Install > AI entries are guarded by `mise where`, since the
preinstalled stub would otherwise read as installed. The menu marks are the
Kimi simpleicon and Dim's traced from its app icon, since upstream publishes
no monochrome SVG.
2026-08-31 23:13:42 -04:00
12 changed files with 65 additions and 314 deletions
+15 -1
View File
@@ -52,7 +52,8 @@ if omarchy-cmd-missing "$agent"; then
fi
# Agents launched from the keybinding or menu run unattended, so each one starts
# with its own spelling of "don't stop to ask". Pi and Ori have none to skip.
# with its own spelling of "don't stop to ask". Pi, Ori and Dim have none to
# skip.
case "$agent" in
opencode)
command=(opencode --auto)
@@ -78,10 +79,23 @@ claude)
command=(claude --permission-mode auto)
[[ -n ${prompt:-} ]] && command+=(-- "$prompt")
;;
dim)
# `dim exec` is the one-shot prompt form; interactive dim is the bare TUI.
if [[ -n ${prompt:-} ]]; then
command=(dim exec "$prompt")
else
command=(dim)
fi
;;
grok)
command=(grok --permission-mode bypassPermissions)
[[ -n ${prompt:-} ]] && command+=(-- "$prompt")
;;
kimi)
# --prompt is kimi's one-shot form, like `crush run`; --auto spares its questions.
command=(kimi --auto)
[[ -n ${prompt:-} ]] && command+=(--prompt "$prompt")
;;
codex)
command=(codex --approve-for-me)
[[ -n ${prompt:-} ]] && command+=(-- "$prompt")
+4 -2
View File
@@ -1,7 +1,7 @@
#!/bin/bash
# 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|dim|kimi]
# omarchy:examples=omarchy default agent | omarchy default agent codex | omarchy default agent claude
installing=false
@@ -31,11 +31,13 @@ ori | openrouter) agent="ori"; name="Ori"; agent_package="github:OpenRouterLabs/
claude | claude-code) agent="claude"; name="Claude Code" ;;
codex) agent="codex"; name="Codex" ;;
crush) agent="crush"; name="Crush" ;;
dim | dimcode | dim-agent) agent="dim"; name="Dim Agent"; agent_package="npm:dimcode" ;;
grok) agent="grok"; name="Grok"; agent_package="npm:@xai-official/grok" ;;
kimi | kimi-code) agent="kimi"; name="Kimi Code"; agent_package="npm:@moonshot-ai/kimi-code" ;;
agy | antigravity | antigravity-cli | gemini | gemini-cli) agent="agy"; name="Antigravity"; agent_package="antigravity-cli" ;;
copilot | github-copilot) agent="copilot"; name="GitHub Copilot" ;;
*)
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|dim|kimi>"
exit 1
;;
esac
+2 -1
View File
@@ -15,7 +15,8 @@ if gum confirm "Are you sure you want to remove all preinstalled web apps, TUI w
# Remove mise stubs
rm -f ~/.local/bin/codex ~/.local/bin/claude ~/.local/bin/agy ~/.local/bin/copilot \
~/.local/bin/gh ~/.local/bin/opencode ~/.local/bin/playwright ~/.local/bin/playwright-cli ~/.local/bin/pi \
~/.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 \
~/.local/bin/dim ~/.local/bin/kimi
omarchy-pkg-drop \
aether \
@@ -1,313 +1,6 @@
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<!-- CJK: give language-tagged text the Noto CJK variant that matches its
language. noto-fonts-cjk ships all five, Han glyph shapes differ between
them, and the generic assigns below would otherwise hand tagged CJK text
to families with no Han coverage, leaving the variant to a charset-scan
lottery. Chinese arrives under many tags (W3C recommends the zh-Hans and
zh-Hant script forms), so the tags are first folded onto one tag per
variant. Order is load-bearing: a bare zh and a bare zh-hant satisfy
the contains test of every one of their extensions, so both are pinned
by exact matches before the extension folds run. Cantonese under its
own primary tag folds to Hong Kong forms, except explicitly
Simplified Cantonese, which folds to SC. -->
<match target="pattern">
<test name="lang" compare="eq">
<string>zh</string>
</test>
<edit name="lang" mode="assign">
<string>zh-cn</string>
</edit>
</match>
<match target="pattern">
<test name="lang" compare="eq">
<string>zh-hant</string>
</test>
<edit name="lang" mode="assign">
<string>zh-tw</string>
</edit>
</match>
<match target="pattern">
<test name="lang" compare="contains">
<string>zh-hant-hk</string>
</test>
<edit name="lang" mode="assign">
<string>zh-hk</string>
</edit>
</match>
<match target="pattern">
<test name="lang" compare="contains">
<string>zh-hant-mo</string>
</test>
<edit name="lang" mode="assign">
<string>zh-hk</string>
</edit>
</match>
<match target="pattern">
<test name="lang" compare="contains">
<string>zh-hant</string>
</test>
<edit name="lang" mode="assign">
<string>zh-tw</string>
</edit>
</match>
<match target="pattern">
<test name="lang" compare="contains">
<string>zh-hans</string>
</test>
<edit name="lang" mode="assign">
<string>zh-cn</string>
</edit>
</match>
<match target="pattern">
<test name="lang" compare="contains">
<string>zh-sg</string>
</test>
<edit name="lang" mode="assign">
<string>zh-cn</string>
</edit>
</match>
<match target="pattern">
<test name="lang" compare="contains">
<string>zh-mo</string>
</test>
<edit name="lang" mode="assign">
<string>zh-hk</string>
</edit>
</match>
<match target="pattern">
<test name="lang" compare="eq">
<string>yue</string>
</test>
<edit name="lang" mode="assign">
<string>zh-hk</string>
</edit>
</match>
<match target="pattern">
<test name="lang" compare="contains">
<string>yue-hans</string>
</test>
<edit name="lang" mode="assign">
<string>zh-cn</string>
</edit>
</match>
<match target="pattern">
<test name="lang" compare="contains">
<string>yue-cn</string>
</test>
<edit name="lang" mode="assign">
<string>zh-cn</string>
</edit>
</match>
<match target="pattern">
<test name="lang" compare="contains">
<string>yue</string>
</test>
<edit name="lang" mode="assign">
<string>zh-hk</string>
</edit>
</match>
<!-- Each variant is then prepended for its tag, ahead of the assigns below
because these test the generic names those assigns replace. Unlike the
Arabic rule further down, these carry a family test, so the prepend
lands just ahead of the matched generic and a concrete family the app
asked for stays in front of the variant. -->
<match target="pattern">
<test name="lang" compare="contains">
<string>zh-cn</string>
</test>
<test name="family">
<string>sans-serif</string>
</test>
<edit name="family" mode="prepend" binding="strong">
<string>Noto Sans CJK SC</string>
</edit>
</match>
<match target="pattern">
<test name="lang" compare="contains">
<string>zh-cn</string>
</test>
<test name="family">
<string>serif</string>
</test>
<edit name="family" mode="prepend" binding="strong">
<string>Noto Serif CJK SC</string>
</edit>
</match>
<match target="pattern">
<test name="lang" compare="contains">
<string>zh-cn</string>
</test>
<test name="family">
<string>monospace</string>
</test>
<edit name="family" mode="prepend" binding="strong">
<string>Noto Sans Mono CJK SC</string>
</edit>
</match>
<match target="pattern">
<test name="lang" compare="contains">
<string>zh-hk</string>
</test>
<test name="family">
<string>sans-serif</string>
</test>
<edit name="family" mode="prepend" binding="strong">
<string>Noto Sans CJK HK</string>
</edit>
</match>
<match target="pattern">
<test name="lang" compare="contains">
<string>zh-hk</string>
</test>
<test name="family">
<string>serif</string>
</test>
<edit name="family" mode="prepend" binding="strong">
<string>Noto Serif CJK HK</string>
</edit>
</match>
<match target="pattern">
<test name="lang" compare="contains">
<string>zh-hk</string>
</test>
<test name="family">
<string>monospace</string>
</test>
<edit name="family" mode="prepend" binding="strong">
<string>Noto Sans Mono CJK HK</string>
</edit>
</match>
<match target="pattern">
<test name="lang" compare="contains">
<string>zh-tw</string>
</test>
<test name="family">
<string>sans-serif</string>
</test>
<edit name="family" mode="prepend" binding="strong">
<string>Noto Sans CJK TC</string>
</edit>
</match>
<match target="pattern">
<test name="lang" compare="contains">
<string>zh-tw</string>
</test>
<test name="family">
<string>serif</string>
</test>
<edit name="family" mode="prepend" binding="strong">
<string>Noto Serif CJK TC</string>
</edit>
</match>
<match target="pattern">
<test name="lang" compare="contains">
<string>zh-tw</string>
</test>
<test name="family">
<string>monospace</string>
</test>
<edit name="family" mode="prepend" binding="strong">
<string>Noto Sans Mono CJK TC</string>
</edit>
</match>
<match target="pattern">
<test name="lang" compare="contains">
<string>ja</string>
</test>
<test name="family">
<string>sans-serif</string>
</test>
<edit name="family" mode="prepend" binding="strong">
<string>Noto Sans CJK JP</string>
</edit>
</match>
<match target="pattern">
<test name="lang" compare="contains">
<string>ja</string>
</test>
<test name="family">
<string>serif</string>
</test>
<edit name="family" mode="prepend" binding="strong">
<string>Noto Serif CJK JP</string>
</edit>
</match>
<match target="pattern">
<test name="lang" compare="contains">
<string>ja</string>
</test>
<test name="family">
<string>monospace</string>
</test>
<edit name="family" mode="prepend" binding="strong">
<string>Noto Sans Mono CJK JP</string>
</edit>
</match>
<match target="pattern">
<test name="lang" compare="contains">
<string>ko</string>
</test>
<test name="family">
<string>sans-serif</string>
</test>
<edit name="family" mode="prepend" binding="strong">
<string>Noto Sans CJK KR</string>
</edit>
</match>
<match target="pattern">
<test name="lang" compare="contains">
<string>ko</string>
</test>
<test name="family">
<string>serif</string>
</test>
<edit name="family" mode="prepend" binding="strong">
<string>Noto Serif CJK KR</string>
</edit>
</match>
<match target="pattern">
<test name="lang" compare="contains">
<string>ko</string>
</test>
<test name="family">
<string>monospace</string>
</test>
<edit name="family" mode="prepend" binding="strong">
<string>Noto Sans Mono CJK KR</string>
</edit>
</match>
<match target="pattern">
<test name="family" qual="any">
<string>sans-serif</string>
+2
View File
@@ -12,6 +12,8 @@ The private-use glyphs in `omarchy.ttf` are:
- `U+E907` — Ollama, from <https://simpleicons.org/icons/ollama.svg>
- `U+E908` — T3 Code, traced from the app icon in <https://aur.archlinux.org/cgit/aur.git/plain/t3code-icon.png?h=t3code-bin>, since upstream publishes no monochrome SVG
- `U+E909` — Ori, from <https://openrouter.ai/brand/v2/openrouter-glyph-dark.svg>, OpenRouter's own mark: Ori ships no separate logo and its product page uses this one
- `U+E90A` — Dim Agent, traced from the app icon at <https://dimcode.dev/apple-touch-icon.png>, since upstream publishes no monochrome SVG
- `U+E90B` — Kimi Code, from <https://simpleicons.org/icons/kimi.svg>
The agent marks are monochrome so the menu can render them using the active
theme's foreground and selection colors.
Binary file not shown.
+4
View File
@@ -140,7 +140,9 @@
"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.crush": {"icon":"󰋑","label":"Crush","checked":"[[ \"$(omarchy-default-agent)\" == \"crush\" ]]","action":"omarchy-default-agent crush"},
"setup.default.agent.dim": {"icon":"","iconFont":"omarchy","label":"Dim Agent","checked":"[[ \"$(omarchy-default-agent)\" == \"dim\" ]]","action":"omarchy-default-agent dim"},
"setup.default.agent.grok": {"icon":"","iconFont":"omarchy","label":"Grok","checked":"[[ \"$(omarchy-default-agent)\" == \"grok\" ]]","action":"omarchy-default-agent grok"},
"setup.default.agent.kimi": {"icon":"","iconFont":"omarchy","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.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"},
@@ -238,7 +240,9 @@
"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.dictation": {"icon":"","label":"Dictation","disabled":"omarchy-pkg-present voxtype-bin","action":"omarchy-launch-floating-terminal-with-presentation omarchy-voxtype-install"},
"install.ai.dim": {"icon":"","iconFont":"omarchy","label":"Dim Agent","disabled":"mise where npm:dimcode &>/dev/null","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-mise-install npm:dimcode dim && dim'"},
"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":"","iconFont":"omarchy","label":"Kimi Code","disabled":"mise where npm:@moonshot-ai/kimi-code &>/dev/null","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-mise-install npm:@moonshot-ai/kimi-code kimi && 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.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"},
+2
View File
@@ -13,3 +13,5 @@ omarchy-mise-install npm:@kitlangton/ghui ghui
omarchy-mise-install aqua:modem-dev/hunk hunk
omarchy-mise-install github:basecamp/hey-cli hey
omarchy-mise-install github:OpenRouterLabs/ori-releases ori
omarchy-mise-install npm:dimcode dim
omarchy-mise-install npm:@moonshot-ai/kimi-code kimi
+2
View File
@@ -14,6 +14,8 @@ Omarchy treats AI coding agents as first-class citizens, but it doesn't pick a f
| `pi` | [Mario Zechner's Pi](https://github.com/badlogic/pi-mono) |
| `omp` | [Oh My Pi](https://github.com/can1357/oh-my-pi) |
| `ori` | [Ori](https://openrouter.ai/docs/guides/ori/harness), OpenRouter's harness |
| `dim` | [Dim Agent](https://dimcode.dev/) |
| `kimi` | [Kimi Code](https://moonshotai.github.io/kimi-code/) |
`ori` is the odd one out: it runs the other harnesses against OpenRouter's whole model catalog, so `ori claude`, `ori codex`, or `ori opencode` start those agents on whichever model you point them at, and `ori code` is Ori's own agent.
+6
View File
@@ -0,0 +1,6 @@
echo "Install dim and kimi via mise wrappers"
if [[ ! -f $HOME/.local/state/omarchy/preinstalls-removed ]]; then
omarchy-mise-install npm:dimcode dim
omarchy-mise-install npm:@moonshot-ai/kimi-code kimi
fi
+24 -1
View File
@@ -98,6 +98,8 @@ omp_package="github:can1357/oh-my-pi"
crush_package="crush"
agy_package="antigravity-cli"
ori_package="github:OpenRouterLabs/ori-releases"
dim_package="npm:dimcode"
kimi_package="npm:@moonshot-ai/kimi-code"
assert_lazy_stub() {
local package=$1
@@ -116,6 +118,8 @@ assert_lazy_stub "$grok_package" grok
assert_lazy_stub "$omp_package" omp
assert_lazy_stub "$crush_package" crush
assert_lazy_stub "$ori_package" ori
assert_lazy_stub "$dim_package" dim
assert_lazy_stub "$kimi_package" kimi
pass "custom agent lazy stubs preserve their mise packages"
source "$ROOT/install/user/mise.sh"
@@ -124,6 +128,8 @@ grep -Fx "$grok_package grok" "$stub_log" >/dev/null || fail "user setup creates
grep -Fx "$omp_package omp" "$stub_log" >/dev/null || fail "user setup creates the Oh My Pi lazy stub"
grep -Fx "$crush_package" "$stub_log" >/dev/null || fail "user setup creates the Crush lazy stub"
grep -Fx "$ori_package ori" "$stub_log" >/dev/null || fail "user setup creates the Ori lazy stub"
grep -Fx "$dim_package dim" "$stub_log" >/dev/null || fail "user setup creates the Dim Agent lazy stub"
grep -Fx "$kimi_package kimi" "$stub_log" >/dev/null || fail "user setup creates the Kimi Code lazy stub"
pass "user setup creates the custom agent lazy stubs"
: >"$stub_log"
@@ -134,6 +140,11 @@ grep -Fx "$omp_package omp" "$stub_log" >/dev/null || fail "Oh My Pi migration c
source "$ROOT/migrations/1787342993.sh" >/dev/null
grep -Fx "$ori_package ori" "$stub_log" >/dev/null || fail "Ori migration creates a working lazy stub"
: >"$stub_log"
source "$ROOT/migrations/1788204288.sh" >/dev/null
grep -Fx "$dim_package dim" "$stub_log" >/dev/null || fail "agent migration creates the Dim Agent lazy stub"
grep -Fx "$kimi_package kimi" "$stub_log" >/dev/null || fail "agent migration creates the Kimi Code lazy stub"
: >"$stub_log"
source "$ROOT/migrations/1785846769.sh" >/dev/null
grep -Fx "$omp_package omp" "$stub_log" >/dev/null || fail "agent migration repairs the Oh My Pi lazy stub"
@@ -216,6 +227,7 @@ touch "$test_home/.local/state/omarchy/preinstalls-removed"
source "$ROOT/migrations/1785617047.sh" >/dev/null
source "$ROOT/migrations/1785846769.sh" >/dev/null
source "$ROOT/migrations/1787342993.sh" >/dev/null
source "$ROOT/migrations/1788204288.sh" >/dev/null
[[ ! -s $stub_log ]] || fail "agent migrations respect the preinstall opt-out"
[[ ! -e $test_home/.local/bin/omp ]] || fail "agent migration removes the obsolete Oh My Pi wrapper after opt-out"
@@ -242,7 +254,7 @@ pass "agent migrations install working wrappers without overriding the preinstal
touch "$test_home/.local/bin/agy" "$test_home/.local/bin/ori"
omarchy-remove-preinstalls >/dev/null
for command in agy omp ori grok crush; do
for command in agy omp ori grok crush dim kimi; do
[[ ! -e $test_home/.local/bin/$command ]] || fail "Remove Preinstalls deletes the $command lazy stub"
done
pass "Remove Preinstalls deletes every optional agent lazy stub"
@@ -299,7 +311,12 @@ declare -A expected_agents=(
[claude-code]="claude"
[codex]="codex"
[crush]="crush"
[dim]="dim"
[dimcode]="dim"
[dim-agent]="dim"
[grok]="grok"
[kimi]="kimi"
[kimi-code]="kimi"
[agy]="agy"
[antigravity]="agy"
[antigravity-cli]="agy"
@@ -317,7 +334,9 @@ declare -A expected_packages=(
[claude]="claude"
[codex]="codex"
[crush]="$crush_package"
[dim]="$dim_package"
[grok]="$grok_package"
[kimi]="$kimi_package"
[agy]="$agy_package"
[copilot]="copilot"
)
@@ -461,7 +480,9 @@ assert_launch ori ori code --interactive --prompt "Review this project"
assert_launch claude claude --permission-mode auto -- "Review this project"
assert_launch codex codex --approve-for-me -- "Review this project"
assert_launch crush crush run "Review this project"
assert_launch dim dim exec "Review this project"
assert_launch grok grok --permission-mode bypassPermissions -- "Review this project"
assert_launch kimi kimi --auto --prompt "Review this project"
assert_launch agy agy --dangerously-skip-permissions --prompt-interactive "Review this project"
assert_launch copilot copilot --allow-all --interactive "Review this project"
pass "agent launcher adapts initial prompts for every supported agent"
@@ -473,7 +494,9 @@ assert_bypass ori ori code
assert_bypass claude claude --permission-mode auto
assert_bypass codex codex --approve-for-me
assert_bypass crush crush --yolo
assert_bypass dim dim
assert_bypass grok grok --permission-mode bypassPermissions
assert_bypass kimi kimi --auto
assert_bypass agy agy --dangerously-skip-permissions
assert_bypass copilot copilot --allow-all
pass "agent launcher skips permission prompts for every supported agent"
+4 -2
View File
@@ -226,6 +226,8 @@ const expectedAgents = {
grok: { icon: '\ue904', iconFont: 'omarchy', label: 'Grok' },
copilot: { icon: '', label: 'Copilot' },
crush: { icon: '󰋑', label: 'Crush' },
dim: { icon: '\ue90a', iconFont: 'omarchy', label: 'Dim Agent' },
kimi: { icon: '\ue90b', iconFont: 'omarchy', label: 'Kimi Code' },
}
assert(
Object.entries(expectedAgents).every(([agent, expected]) => {
@@ -244,7 +246,7 @@ assertDeepEqual(
defaultItems
.filter(item => item.parent === 'setup.default.agent')
.map(item => item.label),
['Antigravity', 'Claude', 'Codex', 'Copilot', 'Crush', 'Grok', 'omp', 'OpenCode', 'Ori', 'Pi'],
['Antigravity', 'Claude', 'Codex', 'Copilot', 'Crush', 'Dim Agent', 'Grok', 'Kimi Code', 'omp', 'OpenCode', 'Ori', 'Pi'],
'menu sorts coding agents alphabetically'
)
const expectedDefaults = {
@@ -636,5 +638,5 @@ assert(
JS
font_charset=$(fc-query --format='%{charset}' "$ROOT/default/fonts/omarchy/omarchy.ttf")
[[ $font_charset == *"e900-e909"* ]] || fail "Omarchy icon font includes every custom menu glyph"
[[ $font_charset == *"e900-e90b"* ]] || fail "Omarchy icon font includes every custom menu glyph"
pass "Omarchy icon font includes the official agent marks"