Initial Claude launcher profiles
This commit is contained in:
commit
7fd845235c
7 changed files with 258 additions and 0 deletions
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
config/profiles.yml
|
||||
*.log
|
||||
.DS_Store
|
||||
|
||||
66
README.md
Normal file
66
README.md
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
# claude-launcher-profiles
|
||||
|
||||
Portable Claude Code launcher profiles for Anthropic Pro and OpenRouter models.
|
||||
|
||||
## Ziel
|
||||
|
||||
Claude Code über einfache Profile starten:
|
||||
|
||||
- `claude-pro`
|
||||
- `claude-glm`
|
||||
- `claude-kimi`
|
||||
- `claude-free`
|
||||
- `claude-profile <name>`
|
||||
|
||||
Die eigentliche Konfiguration liegt in einer YAML-Datei.
|
||||
|
||||
## Voraussetzungen
|
||||
|
||||
- `claude` installiert
|
||||
- funktionierendes Claude-Pro-Login für das `pro`-Profil
|
||||
- `bash`
|
||||
- `yq` zum Parsen der YAML-Datei
|
||||
|
||||
Beispiel Debian/Ubuntu:
|
||||
|
||||
```bash
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y yq
|
||||
```
|
||||
|
||||
## Setup
|
||||
|
||||
```bash
|
||||
git clone https://kitux.de/forgejo/dschlueter/claude-launcher-profiles.git
|
||||
cd claude-launcher-profiles
|
||||
|
||||
cp config/profiles.example.yml config/profiles.yml
|
||||
$EDITOR config/profiles.yml
|
||||
|
||||
chmod +x bin/claude-profile bin/install-claude-profiles lib/profiles.sh
|
||||
./bin/install-claude-profiles
|
||||
source ~/.bashrc
|
||||
```
|
||||
|
||||
## Nutzung
|
||||
|
||||
```bash
|
||||
claude-pro
|
||||
claude-glm
|
||||
claude-kimi
|
||||
claude-free
|
||||
```
|
||||
|
||||
Oder generisch:
|
||||
|
||||
```bash
|
||||
claude-profile pro
|
||||
claude-profile glm
|
||||
claude-profile kimi
|
||||
```
|
||||
|
||||
## Sicherheit
|
||||
|
||||
`config/profiles.yml` enthält echte Keys und wird nicht committed.
|
||||
Nur `config/profiles.example.yml` gehört ins Repo.
|
||||
|
||||
15
bin/claude-profile
Executable file
15
bin/claude-profile
Executable file
|
|
@ -0,0 +1,15 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
# shellcheck source=/dev/null
|
||||
source "$SCRIPT_DIR/../lib/profiles.sh"
|
||||
|
||||
PROFILE="${1:-}"
|
||||
if [[ -z "$PROFILE" ]]; then
|
||||
echo "Usage: claude-profile <profile>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
launch_profile "$PROFILE"
|
||||
|
||||
24
bin/install-claude-profiles
Executable file
24
bin/install-claude-profiles
Executable file
|
|
@ -0,0 +1,24 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
TARGET_DIR="$HOME/src"
|
||||
TARGET_REPO="$TARGET_DIR/claude-launcher-profiles"
|
||||
BASHRC="$HOME/.bashrc"
|
||||
ALIAS_LINE="source $TARGET_REPO/shell/aliases.sh"
|
||||
|
||||
mkdir -p "$TARGET_DIR"
|
||||
|
||||
if [[ "$REPO_DIR" != "$TARGET_REPO" ]]; then
|
||||
if [[ ! -e "$TARGET_REPO" ]]; then
|
||||
ln -s "$REPO_DIR" "$TARGET_REPO"
|
||||
fi
|
||||
fi
|
||||
|
||||
if ! grep -Fq "$ALIAS_LINE" "$BASHRC" 2>/dev/null; then
|
||||
printf '\n# claude-launcher-profiles\n%s\n' "$ALIAS_LINE" >> "$BASHRC"
|
||||
fi
|
||||
|
||||
echo "Installed. Run: source ~/.bashrc"
|
||||
|
||||
23
config/profiles.example.yml
Normal file
23
config/profiles.example.yml
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
defaults:
|
||||
claude_cmd: "claude"
|
||||
openrouter_base_url: "https://openrouter.ai/api"
|
||||
|
||||
profiles:
|
||||
pro:
|
||||
mode: "pro"
|
||||
|
||||
glm:
|
||||
mode: "openrouter"
|
||||
openrouter_api_key: "REPLACE_ME"
|
||||
model: "z-ai/glm-5.2"
|
||||
|
||||
kimi:
|
||||
mode: "openrouter"
|
||||
openrouter_api_key: "REPLACE_ME"
|
||||
model: "moonshotai/kimi-k2.7-code"
|
||||
|
||||
free:
|
||||
mode: "openrouter"
|
||||
openrouter_api_key: "REPLACE_ME"
|
||||
model: "openrouter/free"
|
||||
|
||||
121
lib/profiles.sh
Executable file
121
lib/profiles.sh
Executable file
|
|
@ -0,0 +1,121 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
repo_root() {
|
||||
local script_dir
|
||||
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
printf '%s\n' "$script_dir"
|
||||
}
|
||||
|
||||
config_file() {
|
||||
printf '%s/config/profiles.yml\n' "$(repo_root)"
|
||||
}
|
||||
|
||||
require_yq() {
|
||||
command -v yq >/dev/null 2>&1 || {
|
||||
echo "Error: yq is required but not installed." >&2
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
require_config() {
|
||||
local cfg
|
||||
cfg="$(config_file)"
|
||||
[[ -f "$cfg" ]] || {
|
||||
echo "Error: missing config file: $cfg" >&2
|
||||
echo "Create it from config/profiles.example.yml" >&2
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
cfg_get() {
|
||||
local expr="$1"
|
||||
yq -r "$expr // \"\"" "$(config_file)"
|
||||
}
|
||||
|
||||
profile_exists() {
|
||||
local profile="$1"
|
||||
[[ "$(cfg_get ".profiles.${profile}.mode")" != "" ]]
|
||||
}
|
||||
|
||||
clear_claude_env() {
|
||||
unset OPENROUTER_API_KEY
|
||||
unset ANTHROPIC_BASE_URL
|
||||
unset ANTHROPIC_AUTH_TOKEN
|
||||
unset ANTHROPIC_API_KEY
|
||||
unset ANTHROPIC_MODEL
|
||||
unset ANTHROPIC_DEFAULT_OPUS_MODEL
|
||||
unset ANTHROPIC_DEFAULT_SONNET_MODEL
|
||||
unset ANTHROPIC_DEFAULT_HAIKU_MODEL
|
||||
unset CLAUDE_CODE_SUBAGENT_MODEL
|
||||
}
|
||||
|
||||
resolve_env_ref() {
|
||||
local value="$1"
|
||||
|
||||
if [[ "$value" =~ ^\$[A-Za-z_][A-Za-z0-9_]*$ ]]; then
|
||||
local var_name="${value:1}"
|
||||
printf '%s\n' "${!var_name:-}"
|
||||
else
|
||||
printf '%s\n' "$value"
|
||||
fi
|
||||
}
|
||||
|
||||
launch_profile() {
|
||||
local profile="$1"
|
||||
local mode claude_cmd base_url api_key model
|
||||
|
||||
require_yq
|
||||
require_config
|
||||
|
||||
profile_exists "$profile" || {
|
||||
echo "Error: profile '$profile' not found in $(config_file)" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
claude_cmd="$(cfg_get '.defaults.claude_cmd')"
|
||||
[[ -n "$claude_cmd" ]] || claude_cmd="claude"
|
||||
|
||||
mode="$(cfg_get ".profiles.${profile}.mode")"
|
||||
|
||||
clear_claude_env
|
||||
|
||||
case "$mode" in
|
||||
pro)
|
||||
echo "Claude Pro profile active"
|
||||
exec "$claude_cmd"
|
||||
;;
|
||||
openrouter)
|
||||
base_url="$(cfg_get '.defaults.openrouter_base_url')"
|
||||
[[ -n "$base_url" ]] || base_url="https://openrouter.ai/api"
|
||||
|
||||
api_key="$(cfg_get ".profiles.${profile}.openrouter_api_key")"
|
||||
api_key="$(resolve_env_ref "$api_key")"
|
||||
model="$(cfg_get ".profiles.${profile}.model")"
|
||||
|
||||
[[ -n "$api_key" && "$api_key" != "REPLACE_ME" ]] || {
|
||||
echo "Error: openrouter_api_key missing for profile '$profile'" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
[[ -n "$model" ]] || {
|
||||
echo "Error: model missing for profile '$profile'" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
export OPENROUTER_API_KEY="$api_key"
|
||||
export ANTHROPIC_BASE_URL="$base_url"
|
||||
export ANTHROPIC_AUTH_TOKEN="$OPENROUTER_API_KEY"
|
||||
export ANTHROPIC_API_KEY=""
|
||||
export ANTHROPIC_MODEL="$model"
|
||||
|
||||
echo "OpenRouter profile active: $profile -> $model"
|
||||
exec "$claude_cmd"
|
||||
;;
|
||||
*)
|
||||
echo "Error: unsupported mode '$mode' for profile '$profile'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
5
shell/aliases.sh
Executable file
5
shell/aliases.sh
Executable file
|
|
@ -0,0 +1,5 @@
|
|||
alias claude-pro="$HOME/src/claude-launcher-profiles/bin/claude-profile pro"
|
||||
alias claude-glm="$HOME/src/claude-launcher-profiles/bin/claude-profile glm"
|
||||
alias claude-kimi="$HOME/src/claude-launcher-profiles/bin/claude-profile kimi"
|
||||
alias claude-free="$HOME/src/claude-launcher-profiles/bin/claude-profile free"
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue