Metadata-Version: 2.4
Name: aweswitch
Version: 0.4.2
Summary: A tiny local launcher for switching AI agent runtime profiles.
Author: Peng
License-Expression: MPL-2.0
Keywords: ai,agent,claude,cli,profile
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: Utilities
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: click>=8.1
Dynamic: license-file

<div align="center">
  <img src="logo/hero.png" alt="aweswitch" width="860">
  <h1>aweswitch: Agent Profile Switcher <a href="https://github.com/Webioinfo01/aweskill"><img src="https://raw.githubusercontent.com/Webioinfo01/aweskill/main/logo/aweskill-badge2.svg" alt="aweskill companion"></a></h1>
  <p><strong>A tiny local launcher for switching AI agent runtime profiles.</strong></p>
<p><strong>One config, one command — works the same on Ubuntu, macOS, and Windows.</strong></p>
  <p>Start different agent sessions with different API endpoints, tokens, and models without rewriting global agent config.</p>
  <p>
    <strong>English</strong> ·
    <a href="./README_cn.md">简体中文</a> ·
    <a href="https://www.webioinfo.top/">Webioinfo</a>
  </p>
  <p>
    <a href="https://ko-fi.com/mugpeng"><img src="https://img.shields.io/badge/Ko--fi-Buy%20me%20a%20coffee-FF5E5B?style=flat-square&logo=ko-fi&logoColor=white" alt="Ko-fi"></a>
  </p>
  <p>
    <img src="https://img.shields.io/pypi/v/aweswitch?style=flat-square&color=7C3AED" alt="Version">
    <img src="https://img.shields.io/badge/python-%E2%89%A53.9-0EA5E9?style=flat-square" alt="Python">
    <img src="https://img.shields.io/badge/license-MPL--2.0-22C55E?style=flat-square" alt="License">
  </p>
  <p>
    <img src="https://img.shields.io/badge/status-beta-c96a3d?style=flat-square" alt="Status">
    <img src="https://img.shields.io/badge/provider-Claude_Code_%7C_Codex_%7C_OpenCode-7C3AED?style=flat-square" alt="Provider">
    <img src="https://img.shields.io/badge/install-pip-22C55E?style=flat-square" alt="pip install">
    <img src="https://img.shields.io/badge/platform-ubuntu%20%7C%20macOS%20%7C%20windows-334155?style=flat-square" alt="Platform">
    <img src="https://img.shields.io/pepy/dt/aweswitch?style=flat-square" alt="PyPI downloads">
    <img src="https://img.shields.io/github/stars/mugpeng/aweswitch?style=flat-square" alt="GitHub stars">
  </p>
</div>

> Run different agent profiles side by side without breaking sessions that are already open.

`aweswitch` reads profiles from `~/.config/aweswitch/config.json` and offers two modes:

- **Launch mode** (`aweswitch <profile>`) — starts a new agent session with isolated env. Each session gets its own API endpoint, token, and model. Different terminals can run different profiles simultaneously. Env is frozen at launch time.
- **Write mode** (`aweswitch apply <profile>`) — writes profile env into `~/.claude/settings.json`. Start Claude first, then run `aweswitch apply <profile>` in a new terminal (or let the aweswitch skill do it for you). Restart the session or use `/model` to pick the new model. Only one profile can be active at a time.

It is intentionally small. Today it supports Claude Code, Codex, and OpenCode profiles, plus official-login accounts (Claude Code / Codex OAuth).

## Support Tools

aweswitch is powered by three companion tools:

- **[aweskill](https://github.com/Webioinfo01/aweskill)** — CLI skill package manager for AI agents. Handles skill installation, updates, and projection across 47+ coding agents.
- **[aweshelf](https://github.com/Webioinfo01/aweshelf)** — Session bookmark manager for Claude Code and Codex. Bookmark, categorize, and restore sessions with aweswitch profiles.
- **[awerouter](https://github.com/mugpeng/awerouter)** — Smart LLM router: routes agents requests to flash (cheap) or pro (strong) providers based on structural signals.

aweswitch manages how you **launch** sessions; aweshelf manages how you **remember** them. Use `aweswitch -c` to auto-bookmark at launch, and `aweshelf resume` to restore with the same profile later.

## Install & Usage

### Let AI agent install and configure

If you are working in Claude Code, Codex, Cursor, or other coding agents, tell it:

```text
Read https://github.com/Webioinfo01/aweswitch/blob/main/README.ai.md and follow it to install and configure aweswitch.
```

The agent will install the `aweswitch` CLI, set up config, and help you add profiles. For ongoing profile management, it can also install the aweswitch skill via [aweskill](https://aweskill.webioinfo.top/).

**After setup, you can tell the agent things like:**

> "Write cc-glm to settings so I can switch with /model."
> "List all aweswitch profiles."
> "Add an AiHubMix codex profile."
> "Change the model in cc-glm to glm-5.2."

The agent can run `aweswitch apply`, `aweswitch config backup`, and `aweswitch config restore` directly, but will not run `aweswitch <profile>` (launch mode) — that would nest agents. To launch a profile, run it in your own terminal:

```bash
aweswitch cc-glm
```

<details>
<summary>Example: list configured profiles</summary>

![image-20260622102235441](assets/images/image-20260622102235441.png)

</details>

<details>
<summary>Example: apply profile and switch model</summary>

![image-20260622102200567](assets/images/image-20260622102200567.png)

</details>

### Manual install and usage

Install from PyPI:

```bash
pip3 install aweswitch
aweswitch --help
```

Create the default config:

```bash
aweswitch config init
```

Then open the config and align it with your real providers, models, and token variable names:

```bash
aweswitch config edit
```

Or add a new profile interactively:

```bash
aweswitch add
```

This prompts for a type — `api` (provider, profile name, and provider-specific fields) or `official` (interactive OAuth login / import of a Claude Code or Codex official account).

The default config shape splits profiles by kind (`api` for env-based API profiles, `accounts` for official logins) and then by provider. This is a reference config you can adapt:

```json
{
  "profiles": {
    "api": {
      "claude": {
        "cc-glm": {
          "env": {
            "ANTHROPIC_BASE_URL": "https://open.bigmodel.cn/api/anthropic",
            "ANTHROPIC_AUTH_TOKEN": "${GLM_ANTHROPIC_AUTH_TOKEN}",
            "ANTHROPIC_MODEL": "glm-5.1"
          }
        },
        "cc-xiaomi": {
          "env": {
            "ANTHROPIC_BASE_URL": "https://token-plan-sgp.xiaomimimo.com/anthropic",
            "ANTHROPIC_AUTH_TOKEN": "${XIAOMI_ANTHROPIC_AUTH_TOKEN}",
            "ANTHROPIC_MODEL": "mimo-v2.5-pro"
          }
        }
      },
      "codex": {
        "cx-openai": {
          "env": {
            "OPENAI_BASE_URL": "https://api.openai.com",
            "OPENAI_API_KEY": "${OPENAI_API_KEY}"
          }
        }
      },
      "opencode": {
        "oc-glm": {
          "env": {
            "OPENCODE_BASE_URL": "https://open.bigmodel.cn/api/coding/paas/v4",
            "OPENCODE_API_KEY": "${GLM_ANTHROPIC_AUTH_TOKEN}",
            "OPENCODE_NAME": "Zhipu GLM",
            "OPENCODE_MODEL": {
              "glm-5.1": "GLM-5.1",
              "glm-5.2": "GLM-5.2"
            }
          }
        }
      }
    },
    "accounts": {}
  }
}
```

Configs from before v0.4 (profiles grouped directly by provider) are migrated automatically on first load, with a `config.json.bak` backup written next to the config.

Configure the token variables referenced by your profiles:

```bash
# Claude / OpenCode profiles
export GLM_ANTHROPIC_AUTH_TOKEN="..."
export XIAOMI_ANTHROPIC_AUTH_TOKEN="..."

# Codex profiles
export OPENAI_API_KEY="..."
```

Put long-lived variables in your shell config file if you want them available in every shell — `~/.zshrc` on macOS, `~/.bashrc` or `~/.bash_profile` on bash, or `$PROFILE` on PowerShell.

Verify the configured profiles:

```bash
aweswitch list
aweswitch show cc-glm
```

Run a profile:

```bash
aweswitch cc-glm                      # Claude Code
aweswitch cx-openai                   # Codex
aweswitch oc-glm                      # OpenCode (default: first model)
aweswitch oc-glm glm-5.2              # OpenCode (specific model)
aweswitch cxo-work                    # Codex official account (see below)
```

Pass extra arguments through to the agent:

```bash
aweswitch cc-glm --dangerously-skip-permissions
aweswitch cx-openai --model o3
aweswitch oc-glm glm-5.1 --mini
```

Auto-bookmark sessions with [aweshelf](https://github.com/Webioinfo01/aweshelf):

```bash
aweswitch cc-glm -c backend -t "Fix auth bug"
```

See [aweshelf Integration](#aweshelf-integration) for details.

Useful config commands:

```bash
aweswitch config path
aweswitch config show
aweswitch config edit
```

#### aweswitch skill

Install the [aweswitch skill](https://github.com/Webioinfo01/aweswitch/blob/main/resources/skills/aweswitch/SKILL.md) via [aweskill](https://aweskill.webioinfo.top/) to let AI agents manage profiles with natural language:

- List, inspect, add, edit, and delete profiles
- Apply profiles to settings (`aweswitch apply`) or restore from backup (`aweswitch config restore`)
- Guide environment variable setup (e.g. adding tokens to `~/.zshrc` on macOS, `~/.bashrc` on bash, or `$PROFILE` on PowerShell)

After install, you can tell the agent things like "Add an AiHubMix codex profile", "Change the model in cc-glm to glm-5.2", or "List all profiles". The agent reads the config, makes changes, and verifies the result.

#### Launch mode — isolated sessions

Each invocation starts a new agent session with its own env. Different terminals can run different profiles at the same time.

```bash
aweswitch cc-glm                      # launch Claude Code profile
aweswitch cx-openai                   # launch Codex profile
aweswitch cc-glm --dangerously-skip-permissions   # pass extra arguments
aweswitch cc-glm -c backend -t "Fix auth bug"     # auto-bookmark with aweshelf
```

#### Write mode — persistent defaults (Claude only)

Writes profile env into `~/.claude/settings.json`. Start Claude first, then in a new terminal:

```bash
aweswitch apply cc-glm                # write to settings.json
aweswitch apply cc-glm --force        # overwrite existing backup
aweswitch config backup               # back up settings on demand and print the backup path
aweswitch config restore              # restore settings from default backup
aweswitch config restore <file>       # restore settings from an explicit backup file
```

Restart the session or use `/model` to pick the new model.

#### When to use which mode

| Scenario | Mode |
|---|---|
| Run multiple profiles side by side | Launch |
| Switch model with `/model` inside a session | Write |
| Quickly try different APIs | Launch |
| Set a persistent default profile | Write |

> **Note:** The two modes do not interfere with each other. `aweswitch cc-glm` does not read or modify settings.json. `aweswitch apply cc-glm` does not affect running sessions.
>
> `apply` only works with Claude profiles. OpenCode and Codex profiles are configured automatically when you launch them via `aweswitch <profile>`.

#### Config management

```bash
aweswitch add                         # add a profile or official account interactively
aweswitch list                        # list all profiles (api + account kinds)
aweswitch show cc-glm                 # inspect one profile (secrets redacted)
aweswitch config show                 # full config (secrets redacted)
aweswitch config edit                 # open config in editor
```

#### Official accounts — multiple Claude Code / Codex logins

Official-login accounts (OAuth) are saved as accounts and launched through a private per-account config dir, so several official accounts can run side by side without touching your global `~/.claude` or `~/.codex`:

```bash
aweswitch account login codex work    # run codex login and capture it as account "work"
aweswitch account add claude team-a   # import the currently logged-in claude account
aweswitch cxo-work                    # launch codex with the "work" account
aweswitch account sync codex work     # copy refreshed tokens back into the config
aweswitch account remove codex work --purge
```

`aweswitch add` → type `official` is the interactive route to the same two flows: it asks for provider, account name, and method (`login` runs the OAuth flow, `import` reads the current CLI login).

How it works:

- Launching an account sets `CODEX_HOME` (codex) or `CLAUDE_CONFIG_DIR` + `CLAUDE_CODE_DONT_USE_KEYCHAIN=1` (claude) to a private dir under `~/.config/aweswitch/accounts/<provider>/<name>/`. Credentials are opaque blobs stored in `config.json` and masked in `show` / `config show`; the config file is chmod 600 once it contains an account.
- The account dir is the source of truth once it exists — the CLI refreshes OAuth tokens there, and an existing credentials file is never overwritten by the stored blob. Run `aweswitch account sync` to refresh the config copy for backup/portability.
- On macOS, Claude Code keeps its login in the Keychain by default; `account login` / launches force file-based credentials inside the account dir so accounts stay isolated. `account add` reads `~/.claude/.credentials.json` and only works when that file exists — prefer `account login` on macOS.
- Accounts are launch-only: they don't participate in `apply` mode.

## Self-Update

aweswitch checks PyPI for newer versions in the background on each run. If an update is available, a reminder is printed to stderr after the session ends.

To update manually:

```bash
aweswitch self-update
```

To check without updating:

```bash
aweswitch self-update --check
```

To disable the background check:

```bash
export AWESWITCH_NO_UPDATE_CHECK=1
```

## aweshelf Integration

[aweshelf](https://github.com/Webioinfo01/aweshelf) is a session bookmark manager for Claude Code and Codex CLI. It lets you save, tag, search, and resume past coding sessions.

aweswitch integrates with aweshelf so you can bookmark a session at launch time, without a separate step:

```bash
aweswitch cc-glm -c backend -t "Fix auth bug"
```

### Options

| Flag | Description |
|------|-------------|
| `-c`, `--category` | Category to tag the bookmark with (e.g. `backend`, `research`, `infra`). |
| `-t`, `--title` | Custom bookmark title. If omitted, aweshelf uses the session's first message. |

Both options require aweshelf to be installed. If aweshelf is not found, they are ignored with a warning printed to stderr. Claude Code launches normally regardless.

> **Note**: launching multiple `aweswitch -c` sessions simultaneously in the same project may result in incorrect bookmark assignment. Sequential launches are safe — as long as the previous session's JSONL file has been created before starting the next one (typically a few seconds). See [CONTRIBUTING.md](./docs/CONTRIBUTING.md#known-limitation-concurrent-launch-race-condition) for details.

### Install aweshelf

```bash
pip3 install aweshelf
```

### What aweshelf does on its own

Even without aweswitch's `-c`/`-t` flags, aweshelf is useful independently:

```bash
aweshelf bookmark               # bookmark a session interactively
aweshelf bookmark --current     # bookmark the most recent session in this project
aweshelf list                   # list all bookmarks
aweshelf search "auth"          # full-text search across bookmarks
aweshelf resume BOOKMARK_ID     # resume a saved session
aweshelf browse                 # interactive TUI browser
```

See the [aweshelf README](https://github.com/Webioinfo01/aweshelf) for full documentation.

## FAQ

### Why aweswitch, and who is it for?

`aweswitch` is for people who use AI coding agents with more than one runtime endpoint, model, or token source and want a repeatable local command instead of editing settings by hand.

- **One local config file** at `~/.config/aweswitch/config.json`
- **Named agent profiles** such as `cc-glm`, `cc-gemini`, `cc-xiaomi`, `cx-openai`, or `oc-glm`
- **Side-by-side sessions** where different terminals can launch different API/model combinations
- **Runtime-only injection** through provider-specific arguments
- **No mutation of global agent config**, so already-open agent sessions keep working with the settings they started with
- **Token references** through shell variables or `~/.claude/settings.json`
- **Readable JSON** with `profiles.api` (env-based profiles) and `profiles.accounts` (official logins) grouping

### Where does aweswitch store profiles?

By default, profiles live in:

```bash
~/.config/aweswitch/config.json
```

You can override that path with `AWESWITCH_CONFIG`.

### Does aweswitch modify Claude settings?

**Launch mode** does not — it only reads the aweswitch config and passes runtime settings to the Claude Code process being launched. Already-running sessions are not affected.

**Write mode** does — `aweswitch apply <profile>` writes profile env into `~/.claude/settings.json`. An automatic backup is created on first write. Use `aweswitch config restore` to undo.

### Does aweswitch support Codex?

Yes. Codex profiles use `OPENAI_BASE_URL` and `OPENAI_API_KEY` in their `env` block, plus an optional `OPENAI_MODEL` to choose a model at launch. aweswitch injects the base URL and model via Codex's `-c` config overrides and the API key via environment variable, so no files are written to `~/.codex/`.

### Does aweswitch support OpenCode?

Yes. OpenCode profiles use `OPENCODE_BASE_URL`, `OPENCODE_API_KEY`, and `OPENCODE_MODEL` in their `env` block. On launch, aweswitch writes the provider entry to `~/.config/opencode/opencode.json` (using `{env:VAR}` syntax so the actual key is never stored on disk), then runs `opencode -m <provider>/<model>`.

The profile name (e.g. `oc-glm`) becomes the provider key in `opencode.json`. Models are specified at launch time: `aweswitch oc-glm glm-5.1`. If no model is given, the first one in the list is used.

Resuming a session (`-s <session-id>`) restores the model that session last used, and opencode ignores `-m` in that case — aweswitch warns when the two differ so you know to switch models inside the TUI (Tab) after it opens.

### Does aweswitch support official (OAuth) logins?

Yes — Claude Code and Codex official accounts are saved via `aweswitch account login` (or `account add` to import the current login) and launched like profiles: `aweswitch <account-name>`. Each account runs in its own config dir (`CODEX_HOME` / `CLAUDE_CONFIG_DIR`), so multiple official accounts work side by side. See [Official accounts](#official-accounts--multiple-claude-code--codex-logins).

### Does aweswitch support Hermes?

Not yet. The config format groups profiles by provider so future support can fit naturally.

## Similar Tools

### [cc-switch](https://github.com/farion1231/cc-switch)

`cc-switch` is an adjacent Claude Code switching tool. It is useful reference material for the same problem space: making Claude Code provider/model switching easier from the command line.

The key difference is that `aweswitch` avoids global config mutation. Many switching tools work by changing the agent's shared API/model settings; that can make already-open agent sessions unreliable because the global API endpoint changed underneath them. `aweswitch` keeps profiles in its own JSON file and injects settings only when launching a new process, so each session keeps the API and model it started with.

`aweswitch` currently takes a smaller Python-package approach: local JSON profiles, runtime-only injection (Claude Code `--settings`, Codex `-c` flags and env vars), secret redaction for inspection commands, and provider grouping that leaves room for future agent support.

## Profile Rules

- Profiles live under `profiles.api.<provider>.<profileName>`; official accounts under `profiles.accounts.<provider>.<accountName>`.
- Supported providers: `claude`, `codex`, `opencode` (accounts: `claude`, `codex`).
- Profile and account names must be unique across the whole `profiles` tree.
- `env` values only apply to the launched process.
- `${VAR_NAME}` values are expanded from the current shell environment.
- `show` and `config show` redact keys matching token, key, secret, password, or auth; account credential blobs are masked entirely.

### Claude Profiles

- Pass `env` through runtime `--settings '{"env": ...}'`.
- Set the model with `env.ANTHROPIC_MODEL`.
- Token values can also expand from `~/.claude/settings.json` when they are missing from the shell.

`ANTHROPIC_DEFAULT_HAIKU_MODEL`, `ANTHROPIC_DEFAULT_SONNET_MODEL`, and `ANTHROPIC_DEFAULT_OPUS_MODEL` are not configured by default. If you want Claude Code to use a lighter model for lightweight or background tasks, add `ANTHROPIC_DEFAULT_HAIKU_MODEL` to the profile:

```json
{
  "profiles": {
    "api": {
      "claude": {
        "cc-xiaomi": {
          "env": {
            "ANTHROPIC_BASE_URL": "https://token-plan-sgp.xiaomimimo.com/anthropic",
            "ANTHROPIC_AUTH_TOKEN": "${XIAOMI_ANTHROPIC_AUTH_TOKEN}",
            "ANTHROPIC_MODEL": "mimo-v2.5-pro",
            "ANTHROPIC_DEFAULT_HAIKU_MODEL": "mimo-v2.5"
          }
        }
      }
    }
  }
}
```

This keeps the main model on `mimo-v2.5-pro` while allowing Claude Code to use `mimo-v2.5` for lighter work.

### Codex Profiles

- Requires `OPENAI_BASE_URL` and `OPENAI_API_KEY` in `env`.
- Optionally set `OPENAI_MODEL` (dict, list, or comma-separated string) to pick a model at launch: `aweswitch <profile> [model]`. The first entry is the default; without the key, the profile only switches the API source and the first positional argument passes through to `codex` as usual.
- Base URL is injected via `-c model_providers.custom.base_url=...`, the model via `-c model=...` (no file writes).
- API key is injected via environment variable (no writes to `~/.codex/auth.json`).
- Extra arguments are passed through to the `codex` CLI.

Note that Codex has no model-tier system like Claude's OPUS/SONNET/HAIKU slots — only one model is active at a time, and `OPENAI_MODEL` selects it per launch. In practice, Codex works best with OpenAI's own models — using third-party providers as a relay is the common use case, while switching to entirely different model providers tends to give a poor experience.

```json
{
  "profiles": {
    "api": {
      "codex": {
        "cx-aihubmix": {
          "env": {
            "OPENAI_BASE_URL": "https://aihubmix.com/v1",
            "OPENAI_API_KEY": "${AIHUBMIX_OPENAI_KEY}"
          }
        }
      }
    }
  }
}
```

aweswitch does not write to `~/.codex/`. The base URL is passed via Codex's `-c` flag and the API key via environment variable. This keeps your global Codex config untouched.

To add a Codex profile interactively:

```bash
aweswitch add
# Provider: codex
# Profile name: cx-myprovider
# OPENAI_BASE_URL: https://myprovider.com/v1
# OPENAI_API_KEY env var name: MY_PROVIDER_KEY
```

### OpenCode Profiles

- Requires `OPENCODE_BASE_URL`, `OPENCODE_API_KEY`, and `OPENCODE_MODEL` in `env`.
- The profile name (e.g. `oc-glm`) is used as the provider key in `~/.config/opencode/opencode.json`.
- `OPENCODE_MODEL` supports three formats: dict, list, or comma-separated string.
- Model is specified as the first positional argument: `aweswitch oc-glm glm-5.1`.
- If no model is given, the first model in the list is used as default.
- Extra arguments are passed through to the `opencode` CLI.
- API key is written to `opencode.json` as `{env:VAR}` — the actual key is never stored on disk.

```json
{
  "profiles": {
    "api": {
      "opencode": {
        "oc-glm": {
          "env": {
            "OPENCODE_BASE_URL": "https://open.bigmodel.cn/api/coding/paas/v4",
            "OPENCODE_API_KEY": "${GLM_ANTHROPIC_AUTH_TOKEN}",
            "OPENCODE_NAME": "Zhipu GLM",
            "OPENCODE_MODEL": {
              "glm-5.1": "GLM-5.1",
              "glm-5.2": "GLM-5.2"
            }
          }
        }
      }
    }
  }
}
```

`OPENCODE_MODEL` formats:

| Format | Example | Model `name` in opencode.json |
|--------|---------|-------------------------------|
| Dict | `{"glm-5.1": "GLM-5.1"}` | Uses the value (`GLM-5.1`) |
| List | `["glm-5.1", "glm-5.2"]` | Uses the key (`glm-5.1`) |
| String | `"glm-5.1,glm-5.2"` | Uses the key (`glm-5.1`) |

`OPENCODE_NAME` (optional) sets the display name for the provider in `opencode.json`. Defaults to the profile name.

Launch:

```bash
aweswitch oc-glm                      # default: first model (glm-5.1)
aweswitch oc-glm glm-5.2              # specific model
aweswitch oc-glm glm-5.1 --mini       # pass extra args
```

On first launch, aweswitch writes the provider entry to `~/.config/opencode/opencode.json`. Subsequent launches reuse the existing entry and only add new models if needed.

To add an OpenCode profile interactively:

```bash
aweswitch add
# Provider: opencode
# Profile name: oc-myprovider
# OPENCODE_BASE_URL: https://myprovider.com/v1
# OPENCODE_API_KEY env var name: MY_API_KEY
# OPENCODE_MODEL: model-1,model-2
```

## Support

If aweswitch saves you time, consider supporting it:

- ⭐ Star the repo — it helps others find it.
- ☕ [Ko-fi](https://ko-fi.com/mugpeng) — buy me a coffee.
- 💬 WeChat — scan the QR code below.

<p align="center">
  <img src="assets/images/wechat-pay.jpg" alt="WeChat Pay" width="240">
</p>

> aweswitch is free and open source. Sponsors keep it maintained — thank you.

## Development

See [Contributing](./docs/CONTRIBUTING.md) for setup, testing, branching, and release workflow.

- [Contributing](./docs/CONTRIBUTING.md)
- [Changelog](./docs/CHANGELOG.md)
