#!/usr/bin/env bash # hyclaude-desktop — configure Claude Desktop to use Tencent TokenHub as inference backend. # # Edits ~/Library/Application Support/Claude-3p/configLibrary/{_meta,}.json # and restarts Claude Desktop. macOS only. # # Usage: # hyclaude-desktop # configure to HY3 Preview and restart # hyclaude-desktop kimi # use kimi-k2.7-code # hyclaude-desktop deepseek # use deepseek-v4-pro # hyclaude-desktop glm # use glm-5.2 # hyclaude-desktop minimax # use minimax-m3 # hyclaude-desktop qwen # use qwen3.5-plus # hyclaude-desktop update # git pull # hyclaude-desktop -h # help # # Reads HY_API_KEY from env or ~/.zshrc & friends (else prompts). # Base URL: https://api.lkeap.cloud.tencent.com/plan/anthropic set -euo pipefail CONFIG_DIR="$HOME/Library/Application Support/Claude-3p/configLibrary" META="$CONFIG_DIR/_meta.json" ENTRY_NAME="hyclaude-desktop" AUTH_SCHEME="bearer" MAIN_MODEL="hy3-preview" FAST_MODEL="hy-mt2-lite" while [[ $# -gt 0 ]]; do case "$1" in -h|--help) sed -n '2,17p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;; update) SELF_DIR="$(cd "$(dirname "$0")" && pwd)" echo "hyclaude-desktop: pulling latest from $SELF_DIR ..." git -C "$SELF_DIR" pull && echo "hyclaude-desktop: updated." || { echo "git pull failed." >&2; exit 1; }; exit 0 ;; max|pro|code) MAIN_MODEL="hy3-preview"; FAST_MODEL="hy-mt2-lite"; shift ;; fast|flash|lite) MAIN_MODEL="hy-mt2-lite"; FAST_MODEL="hy-mt2-lite"; shift ;; kimi) MAIN_MODEL="kimi-k2.7-code"; FAST_MODEL="hy-mt2-lite"; shift ;; kimi-pro|kimi-k2) MAIN_MODEL="kimi-k2.6"; FAST_MODEL="kimi-k2.6"; shift ;; deepseek) MAIN_MODEL="deepseek-v4-pro"; FAST_MODEL="deepseek-v4-flash"; shift ;; deepseek-flash) MAIN_MODEL="deepseek-v4-flash"; FAST_MODEL="deepseek-v4-flash"; shift ;; glm) MAIN_MODEL="glm-5.2"; FAST_MODEL="glm-5.2"; shift ;; minimax) MAIN_MODEL="minimax-m3"; FAST_MODEL="minimax-m3"; shift ;; qwen) MAIN_MODEL="qwen3.5-plus"; FAST_MODEL="qwen3.5-plus"; shift ;; *) echo "hyclaude-desktop: unknown argument: $1" >&2; exit 2 ;; esac done preflight() { [[ "$(uname)" == "Darwin" ]] || { echo "macOS only." >&2; exit 1; } [[ -d "/Applications/Claude.app" ]] || { echo "Claude.app not found." >&2; exit 1; } [[ -x "/usr/bin/jq" ]] || { echo "jq not found." >&2; exit 1; } local ds="$HOME/Library/Application Support/Claude/developer_settings.json" if [[ ! -f "$ds" ]] || ! /usr/bin/jq -e '.allowDevTools==true' "$ds" >/dev/null 2>&1; then echo "hyclaude-desktop: Enable Developer Mode first (Help → Troubleshooting → Enable Developer Mode)" >&2; exit 1 fi } resolve_api_key() { if [[ -n "${HY_API_KEY:-}" ]]; then printf '%s' "$HY_API_KEY"; return 0; fi local rc found="" for rc in "$HOME/.zshrc" "$HOME/.bashrc" "$HOME/.bash_profile" "$HOME/.profile"; do [[ -r "$rc" ]] || continue found="$(grep -v '^[[:space:]]*#' "$rc" 2>/dev/null|grep -E '^[[:space:]]*export[[:space:]]+HY_API_KEY='|tail -1|sed -E 's/^[^=]*=//; s/^"(.*)"$/\1/; s/^'\''(.*)'\''$/\1/'||true)" if [[ -n "$found" ]]; then printf '%s' "$found"; return 0; fi done local key key="$(osascript 2>/dev/null <<'APPLESCRIPT'||true try;set theKey to text returned of (display dialog "HY API Key not found.\nPaste your Tencent TokenHub API Key:" default answer "" with hidden answer with title "hyclaude-desktop");return theKey;end try APPLESCRIPT )" if [[ -z "$key" ]]; then echo "hyclaude-desktop: no API Key provided. Aborting." >&2; exit 1; fi printf '%s' "$key" } confirm_or_abort() { echo; echo "About to: $1"; echo "Press Enter to continue, Ctrl-C to abort."; read -r _; } write_entry() { local uuid="$1"; local entry_path="$CONFIG_DIR/${uuid}.json"; local tmp="${entry_path}.tmp" local content content="$(jq -n --arg baseUrl "$BASE_URL" --arg apiKey "$HY_KEY" --arg auth "$AUTH_SCHEME" --arg main "$MAIN_MODEL" --arg fast "$FAST_MODEL" \ '{inferenceProvider:"gateway",inferenceGatewayBaseUrl:$baseUrl,inferenceGatewayApiKey:$apiKey,inferenceGatewayAuthScheme:$auth,unstableDisableModelVerification:true,inferenceModels:([{name:$main,supports1m:false}]+(if $fast!=$main then[{name:$fast,supports1m:false}]else[]end))}')" printf '%s' "$content" > "$tmp"; chmod 600 "$tmp"; mv "$tmp" "$entry_path" } ensure_meta_entry() { mkdir -p "$CONFIG_DIR" local existing_uuid="" if [[ -f "$META" ]]; then existing_uuid="$(jq -r --arg name "$ENTRY_NAME" '.entries[]?|select(.name==$name)|.id' "$META" 2>/dev/null|head -1)"; fi local uuid; if [[ -n "$existing_uuid" ]]; then uuid="$existing_uuid"; else uuid="$(uuidgen | tr 'A-Z' 'a-z')"; fi local tmp="${META}.tmp" content if [[ -f "$META" ]]; then content="$(jq --arg id "$uuid" --arg name "$ENTRY_NAME" '.appliedId=$id|.entries=((.entries//[])|map(select(.name!=$name))+[{id:$id,name:$name}])' "$META")" else content="$(jq -n --arg id "$uuid" --arg name "$ENTRY_NAME" '{appliedId:$id,entries:[{id:$id,name:$name}]}')"; fi printf '%s' "$content" > "$tmp"; chmod 600 "$tmp"; mv "$tmp" "$META"; printf '%s' "$uuid" } restart_claude() { killall Claude 2>/dev/null || true; sleep 1; open -a Claude; } BASE_URL="${HY_BASE_URL:-https://api.lkeap.cloud.tencent.com/plan/anthropic}" preflight; HY_KEY="$(resolve_api_key)" confirm_or_abort "configure Claude Desktop to use Tencent TokenHub ($BASE_URL, $MAIN_MODEL) and restart." UUID="$(ensure_meta_entry)"; write_entry "$UUID"; restart_claude cat <<'EOF' Done. Claude Desktop is restarting with Tencent TokenHub as the inference backend. Re-run hyclaude-desktop any time to refresh the gateway config. EOF