claude-mode.ps1 was 2,407 lines. It is now 153: the help block, parameters, paths, the managed-key list, a loader, and the dispatch. The rest moved, verbatim, into eleven files under lib/ - providers, output, files, core, vault, switch, guards, health, catalogue, commands, menu - dot-sourced into the script's scope in their original order, with the same check as the bash split that every original line landed in exactly one file. Inside a module $PSScriptRoot is lib\, so the one path beside the main script (providers.json) now goes through $script:Here. install.ps1 ships lib\, clearing old modules first. The Windows suite parses every module and install.ps1 (36 checks, all green on Windows PowerShell 5.1); install.ps1 is parsed but never run, since it edits the real profile and User PATH. linux/bootstrap.sh and scripts/build-package.ps1 existed only to build and serve packages for the Arkylx Index. Both installers fetch the repository's own archive, so a push to master is the release; the two scripts, the dist/ ignore and their mentions in the docs are gone. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
claude-mode
Switch Claude Code between Anthropic, OpenRouter, Z.AI, a local LM Studio or Ollama server, and any custom Anthropic-compatible endpoint — system-wide, with named per-tier model presets.
One write to ~/.claude/settings.json covers the CLI, the VS Code extension and
the desktop app: restart Claude Code and it is on the new provider. API keys stay
out of that file. There is a Windows build (PowerShell 5.1, no dependencies) and a
POSIX port for Linux and macOS (bash 3.2+ and python3), with a theme-aware
terminal menu and an Omarchy bar widget.
claude-mode # interactive menu
claude-mode status # what the next `claude` launch will use
claude-mode anthropic # back to your subscription login
claude-mode openrouter # remote gateway, pay per token (preset: default)
claude-mode zai # Z.AI GLM coding plan (preset: zai)
claude-mode lmstudio # local LM Studio server (preset: lmstudio)
claude-mode ollama # local Ollama server (preset: ollama)
claude-mode custom # your own Anthropic-compatible URL (preset: custom)
Install
Windows (PowerShell 5.1+)
irm https://git.nebulm.com/smoido/claude-mode/raw/branch/master/install.ps1 | iex
Piped in like that there is no checkout, so the installer fetches the repository
archive to %TEMP% and installs from it. To pass switches (-Force,
-SkipKeyPrompt), download the file and run it; or clone the repository and run
.\install.ps1.
It installs to ~/.claude-mode/ (ACL: you only), puts claude-mode.cmd in
~/.local/bin (already on your User PATH, next to claude.exe), and adds a
marked block to ~/Documents/WindowsPowerShell/profile.ps1. If the profile does
not load: Set-ExecutionPolicy -Scope CurrentUser RemoteSigned.
Linux / macOS
curl -fsSL https://git.nebulm.com/smoido/claude-mode/raw/branch/master/linux/install.sh | bash
Or clone and run bash linux/install.sh (--skip-key-prompt to install without
storing a key). It installs to ~/.claude-mode/, symlinks
~/.local/bin/claude-mode, and adds the claude wrapper to ~/.bashrc /
~/.zshrc between markers. Keys go to the macOS Keychain, libsecret, pass, or a
0600 file that says plainly that it is not encrypted — whichever is available.
It runs on the bash 3.2 that macOS ships. Finding running sessions needs /proc,
so on macOS a switch says it cannot check for them instead of claiming there are
none; restart Claude Code yourself after switching there.
Omarchy bar widget
bash omarchy/install.sh # from a checkout
omarchy restart shell # after an upgrade - see below
The shell reloads the plugin when its files change, but keeps the old compiled panel alive through that reload, so an upgrade only shows after a shell restart. What the widget does: docs/bar-widget.md.
Upgrading
Re-run the installer. Scripts and providers.json are replaced; your presets are
kept unless you pass --force / -Force. The installers never touch
~/.claude/settings.json — only a switch does, and it backs the file up to
~/.claude-mode/backups/ first (the last 20 are kept).
First run
A shipped preset is a starting point, not a working configuration: no key is
stored, and its model ids are whatever was on the machine it was packaged on. So
the shipped presets are marked configured: false, and a switch to one asks for
setup first:
claude-mode setup openrouter # key, then a model per tier from OpenRouter's catalogue
claude-mode setup zai # key, then a GLM model per tier
claude-mode setup lmstudio # where the server is, whether it wants a key, one model for all tiers
claude-mode setup ollama # the same, for Ollama
claude-mode setup custom # the endpoint's address and key, then a model per tier
In a terminal, a switch that needs setup offers to run it there and then. Presets you build yourself never ask.
Commands
claude-mode interactive menu
claude-mode status active mode, preset, model map
claude-mode <mode> [preset] switch: anthropic, openrouter, zai, lmstudio, ollama, custom
claude-mode <mode> --yes ...without asking about running sessions
claude-mode <mode> --force ...even when preflight says it would not work
claude-mode setup <mode> first-run setup: key, server, models
claude-mode preflight <mode> [preset] would that switch work? (JSON, no switch)
claude-mode doctor check auth, endpoint, model ids, context window, stray env vars
claude-mode health rewrite health.json (machine-readable state)
claude-mode presets list presets (* = active)
claude-mode preset show <name>
claude-mode preset new <name> [from] copy a preset (default: `default`)
claude-mode preset new <name> --provider <p> [--blank]
copy that provider's default, or start empty
claude-mode preset set <name> <tier> <model-id>
claude-mode preset all <name> <model-id> point every tier at one model
claude-mode preset url <name> <base-url> point a preset at another server
claude-mode preset auth <name> none|key [ref]
claude-mode preset rename <name> <new-name>
claude-mode preset default [provider] [name|--clear]
which preset `claude-mode <provider>` picks
claude-mode preset rm <name>
claude-mode set-key [ref] [key] store a key (hidden prompt; [key] for scripts)
claude-mode models [filter] models from the active provider
claude-mode models --preset <name> [--refresh|--json]
claude-mode sessions [--stop|--restart|--dry-run]
running Claude Code sessions; close or reopen them
claude-mode repair-session [id] [--apply]
make a session resumable after a bad switch
claude-mode repair-session --ignore <id> | --unignore <id> | --ignored | --all [--max-age <days>]
claude-mode repair [--all] strip [1m] tags from cached model ids
zai also answers to z.ai and z-ai, and lmstudio to lm-studio. The
Windows build covers switching, status, presets, preset show|new|set|all|rm,
set-key, models, doctor and repair; everything else above is POSIX-only.
Providers
| mode | what it is | key |
|---|---|---|
anthropic |
your Claude subscription login — no gateway at all | your login |
openrouter |
remote gateway to most vendors' models, pay per token | required |
zai |
Z.AI's GLM coding plan on its Anthropic endpoint | required |
lmstudio |
an LM Studio server, local or anywhere on your network | optional |
ollama |
an Ollama server, local or anywhere on your network | optional |
custom |
any Anthropic-compatible endpoint: a LiteLLM or Vercel gateway, vLLM, a company proxy | optional |
Each provider has its quirks — OpenRouter's guardrail, LM Studio's model ids and chat templates, Ollama's server-side context window — and they are all in docs/providers.md, along with presets, context windows, and how to add a provider of your own (usually one JSON entry, no code).
Switching while Claude Code is running
A switch breaks the sessions already running: their key is re-fetched on a timer
and resolves to the new mode while their endpoint stays the old one. So a switch
asks first, and claude-mode sessions --restart reopens them on the new mode.
Worse, a session that takes even one reply from another provider can no longer be
resumed on Anthropic — claude-mode repair-session rolls it back to its last good
message, keeping the cut turns. The whole story: docs/live-sessions.md.
Troubleshooting
- Run
claude-mode doctorfirst. It checks the key, the helper, the endpoint, every tier's model id, the context window and stray environment variables. - "your apiKeyHelper script is failing" — usually a space in your home
directory in a
settings.jsonwritten by an old version (re-run the switch), or on Windows a key stored from an elevated shell (claude-mode set-key <ref>again, unelevated). Details in docs/design.md. - The session auto-compacts almost at once on a gateway — the preset's
contextTokens; see context windows. - LM Studio spams "Unable to generate parser for this template" — the model's chat template; see LM Studio.
- Ollama loses track of long conversations — its server context defaults to 4096 tokens; see Ollama.
- A switch is refused —
claude-mode preflight <mode>says why, and what fixes it; the checks are listed in docs/design.md.
Documentation
| docs/providers.md | presets, defaults, context windows, every provider, adding one |
| docs/live-sessions.md | what a switch does to running sessions, and repairing them |
| docs/bar-widget.md | the Omarchy bar widget and its panel |
| docs/design.md | why it works the way it does |
| docs/architecture.md | how the pieces fit, and where to change what |
| docs/development.md | tests, conventions, releasing |
| CHANGELOG.md | what changed, by version |
Uninstall
claude-mode anthropic # clean settings.json first
rm -rf ~/.claude-mode ~/.local/bin/claude-mode
# then delete the block between the >>> claude-mode >>> markers in ~/.bashrc / ~/.zshrc
On Windows, claude-mode anthropic, then remove ~\.claude-mode and
~\.local\bin\claude-mode.cmd, and delete the marked block in profile.ps1. For
the bar widget, remove ~/.config/omarchy/plugins/smoido.claude-mode and its
{"id": "smoido.claude-mode"} entry in ~/.config/omarchy/shell.json.
Licence
MIT.