{"repo": "agents365-ai/dsclaude", "files": {"mmclaude": {"c07db31916dca8077b9124f5c098258f9607b016": {"t": 1785595132.83843, "n": 4454, "h": "19167c0f60f9c088", "c": "#!/usr/bin/env bash\n# shellcheck disable=SC2034 # variables consumed by lib/common.sh\n# mmclaude — launch Claude Code on Xiaomi MiMo's Anthropic-compatible API.\n#\n# Follows the official MiMo \"Claude Code 配置\" guide:\n# - Pay-as-you-go : https://api.xiaomimimo.com/anthropic (sk-... keys)\n# - Token Plan : https://token-plan-cn.xiaomimimo.com/anthropic (tp-... keys)\n# (Token Plan subscribers may receive a custom subdomain — override\n# the base URL via MIMO_BASE_URL.)\n#\n# Reads MIMO_API_KEY from the environment first, then falls back to\n# ~/.zshrc / ~/.bashrc / ~/.bash_profile / ~/.profile if not already exported.\n#\n# Quick start (no install needed):\n# chmod +x mmclaude\n# ./mmclaude\n#\n# Optional — make it globally available:\n# sudo mv mmclaude /usr/local/bin/ && sudo chmod +x /usr/local/bin/mmclaude\n#\n# Use:\n# mmclaude # start on mimo-v2.5-pro (MiMo default)\n# mmclaude fast # start on mimo-v2.5 (cheaper / faster flash tier)\n# mmclaude long # request max context window\n# mmclaude effort max # set reasoning effort (low|medium|high|xhigh|max)\n# mmclaude update # git pull latest from this repo\n# mmclaude --help # any remaining flag is forwarded to claude\n#\n# Optional env overrides:\n# MIMO_MODEL=mimo-v2.5-pro # main model\n# MIMO_FLASH_MODEL=mimo-v2.5 # flash / haiku / subagent tier\n# MIMO_BASE_URL=https://.../anthropic # custom Anthropic-compatible base URL\n# MIMO_CTX=1048576 # max context tokens (defaults to 1M with `long`)\n# MIMO_OUTPUT=8000 # cap output tokens\n# MIMO_EFFORT=max # CLAUDE_CODE_EFFORT_LEVEL\n#\n# In-session switch:\n# /model mimo-v2.5 # switch to the flash tier\n# /model mimo-v2.5-pro # switch back to pro\n#\nset -euo pipefail\n\n# Resolve symlink to find the real script directory.\n_SELF=\"$0\"\nif [ -L \"$_SELF\" ]; then\n _LINK=\"$(readlink \"$_SELF\")\"\n case \"$_LINK\" in\n /*) _SELF=\"$_LINK\" ;;\n *) _SELF=\"$(cd \"$(dirname \"$_SELF\")\" && pwd)/$_LINK\" ;;\n esac\nfi\nSELF_DIR=\"$(cd \"$(dirname \"$_SELF\")\" && pwd)\"\nif [ -f \"$SELF_DIR/lib/common.sh\" ]; then source \"$SELF_DIR/lib/common.sh\"\nelif [ -f \"$SELF_DIR/../lib/common.sh\" ]; then source \"$SELF_DIR/../lib/common.sh\"\nelse echo \"mmclaude: cannot find lib/common.sh. Reinstall or cd to repo.\" >&2; exit 1; fi\n\ncheck_version \"mmclaude\" \"$@\"\n\nPRO_MODEL=\"${MIMO_MODEL:-mimo-v2.5-pro}\"\nFLASH_MODEL=\"${MIMO_FLASH_MODEL:-mimo-v2.5}\"\n\n# Handle the update subcommand before the API-key check so it works key-less.\nif [ $# -gt 0 ] && [ \"$1\" = \"update\" ]; then\n do_update \"mmclaude\" \"MMCLAUDE_HOME\"\nfi\n\nAPI_KEY=\"$(resolve_api_key \"MIMO_API_KEY\")\"\nif [ -z \"$API_KEY\" ]; then\n echo \"❌ MIMO_API_KEY not found.\" >&2\n echo \" Add one line to ~/.zshrc or ~/.bashrc:\" >&2\n echo \" export MIMO_API_KEY=sk-xxxxxxxxxxxxxxxxxx # pay-as-you-go\" >&2\n echo \" export MIMO_API_KEY=tp-xxxxxxxxxxxxxxxxxx # Token Plan\" >&2\n exit 1\nfi\n\n# Auto-detect the base URL from the key prefix; MIMO_BASE_URL env always wins.\nBASE_URL=\"${MIMO_BASE_URL:-}\"\nif [ -z \"$BASE_URL\" ]; then\n case \"$API_KEY\" in\n tp-*) BASE_URL=\"https://token-plan-cn.xiaomimimo.com/anthropic\" ;;\n *) BASE_URL=\"https://api.xiaomimimo.com/anthropic\" ;;\n esac\nfi\n\nLONG_CTX=0\nEFFORT=\"${MIMO_EFFORT:-}\"\n\n# Positional alias: `fast`/`flash` runs the flash tier as the main model.\nMAIN_MODEL=\"$PRO_MODEL\"\nwhile [ $# -gt 0 ]; do\n case \"$1\" in\n fast|flash) MAIN_MODEL=\"$FLASH_MODEL\"; shift ;;\n long) LONG_CTX=1; shift ;;\n effort)\n case \"${2:-}\" in\n low|medium|high|xhigh|max) EFFORT=\"$2\"; shift 2 ;;\n *) echo \"mmclaude: invalid effort level '${2:-}'. Use: low medium high xhigh max\" >&2; exit 1 ;;\n esac\n ;;\n --) shift; break ;;\n *) break ;;\n esac\ndone\n\n# Surface the other model in Claude Code's /model picker for mid-session switching.\nif [ \"$MAIN_MODEL\" = \"$PRO_MODEL\" ]; then\n OTHER_MODEL=\"$FLASH_MODEL\"\n OTHER_DESC=\"MiMo v2.5 — fast / cheap haiku tier\"\nelse\n OTHER_MODEL=\"$PRO_MODEL\"\n OTHER_DESC=\"MiMo v2.5 Pro — full reasoning\"\nfi\n\nexport_anthropic_base\n# Subagents run on the cheaper flash tier.\nexport CLAUDE_CODE_SUBAGENT_MODEL=\"$FLASH_MODEL\"\nset_custom_model \"$OTHER_MODEL\" \"$MAIN_MODEL\" \"$OTHER_DESC\"\n\nCTX=\"${MIMO_CTX:-}\"\nOUTPUT_CAP=\"${MIMO_OUTPUT:-}\"\napply_context_and_effort\n\nshow_banner_and_launch \"MiMo\" \"$@\"\n"}}, "mmclaude.ps1": {"c07db31916dca8077b9124f5c098258f9607b016": {"t": 1785595140.657529, "n": 9815, "h": "3104e1025c7c8863", "c": "#!/usr/bin/env pwsh\n# mmclaude.ps1 — launch Claude Code on Xiaomi MiMo's Anthropic-compatible API (Windows port).\n#\n# Windows companion to the macOS/Linux bash script `mmclaude`. Same env vars,\n# same model picker — different shell.\n#\n# Follows the official MiMo \"Claude Code 配置\" guide:\n# - Pay-as-you-go : https://api.xiaomimimo.com/anthropic (sk-... keys)\n# - Token Plan : https://token-plan-cn.xiaomimimo.com/anthropic (tp-... keys)\n#\n# Reads MIMO_API_KEY from the process env first, then User/Machine env vars.\n# The base URL is auto-detected from the key prefix (tp-* → Token Plan, else\n# pay-as-you-go); override with $env:MIMO_BASE_URL.\n#\n# Quick start (from the mmclaude directory):\n# pwsh -File .\\mmclaude.ps1\n#\n# Three invocation rules that matter on Windows:\n# 1. Use `pwsh`, not `powershell`. PowerShell 5.1 ships with Windows but its\n# legacy console host breaks Ink-based CLIs (claude exits silently after\n# the first keystroke). This script refuses to run on PS < 7.\n# Install once: winget install Microsoft.PowerShell\n# 2. Use `-File`, not `-Command` / `&`. `-File` runs the script in a clean\n# arg-parsing mode; `-Command` re-tokenizes the line and mangles paths.\n# 3. Allow local scripts to run (one-time, current user only):\n# Set-ExecutionPolicy -Scope CurrentUser RemoteSigned\n#\n# Launching from a shortcut, Run dialog, or another shell:\n# Start-Process pwsh -ArgumentList '-NoExit', '-File',\n# 'C:\\Users\\\\Desktop\\mmclaude\\mmclaude.ps1'\n# (`-NoExit` keeps the window open if the launching context doesn't have one.)\n#\n# Optional — make it globally available (one-time, from this dir):\n# $bin = \"$env:USERPROFILE\\bin\"; New-Item -ItemType Directory -Force $bin | Out-Null\n# Copy-Item .\\mmclaude.ps1 $bin\\mmclaude.ps1\n# # then add $bin to PATH and run: pwsh -File mmclaude.ps1\n#\n# Use:\n# pwsh -File ./mmclaude.ps1 # mimo-v2.5-pro (MiMo default)\n# pwsh -File ./mmclaude.ps1 fast # run the flash tier (mimo-v2.5) as main\n# pwsh -File ./mmclaude.ps1 long # request max context window\n# pwsh -File ./mmclaude.ps1 effort max # set effort (low|medium|high|xhigh|max)\n# pwsh -File ./mmclaude.ps1 update # git pull latest from this repo\n# pwsh -File ./mmclaude.ps1 --help # any remaining flag is forwarded to claude\n#\n# Optional env overrides (take precedence over positional aliases):\n# $env:MIMO_MODEL = 'mimo-v2.5-pro' # main model\n# $env:MIMO_FLASH_MODEL = 'mimo-v2.5' # flash / haiku / subagent tier\n# $env:MIMO_BASE_URL = 'https://.../anthropic' # custom base URL\n# $env:MIMO_CTX = '1048576' # max context tokens\n# $env:MIMO_OUTPUT = '8000' # cap output tokens\n# $env:MIMO_EFFORT = 'max' # CLAUDE_CODE_EFFORT_LEVEL\n#\n# In-session switch:\n# /model mimo-v2.5 # switch to the flash tier\n# /model mimo-v2.5-pro # switch back to the main model\n#\n# Requires: PowerShell 7+ (`winget install Microsoft.PowerShell`), Claude Code\n# CLI on PATH (`npm i -g @anthropic-ai/claude-code`), MiMo API key.\n\n[CmdletBinding()]\nparam(\n [Parameter(ValueFromRemainingArguments = $true)]\n [string[]]$Rest\n)\n\n$ErrorActionPreference = 'Stop'\n\n# ---- PowerShell version guard ----------------------------------------------\n# Windows PowerShell 5.1 ships with a legacy console host whose raw-mode TTY\n# breaks Ink (the React-for-CLI framework Claude Code uses): the welcome\n# screen renders, then the first keystroke causes claude to exit silently.\n# PowerShell 7+ uses ConPTY and works correctly. Refuse early with a clear\n# message rather than letting the user debug the silent-exit symptom.\nif ($PSVersionTable.PSVersion.Major -lt 7) {\n Write-Error @\"\nmmclaude.ps1: PowerShell 7+ required (you're on $($PSVersionTable.PSVersion)).\n\nWindows PowerShell 5.1 cannot host claude's interactive UI — the first\nkeystroke causes claude to exit. Install PowerShell 7 once:\n\n winget install Microsoft.PowerShell\n\nThen re-run with:\n\n pwsh -File .\\mmclaude.ps1\n\"@\n exit 1\n}\n\n# ---- Self-update -----------------------------------------------------------\n\nfunction Invoke-MmclaudeUpdate {\n $repo = $null\n $selfDir = Split-Path -Parent $PSCommandPath\n if (Test-Path (Join-Path $selfDir '.git')) {\n $repo = $selfDir\n }\n if (-not $repo -and $env:MMCLAUDE_HOME) {\n $repo = $env:MMCLAUDE_HOME\n }\n if (-not $repo) {\n $candidate = Join-Path $env:USERPROFILE 'github\\xxclaude'\n if (Test-Path (Join-Path $candidate '.git')) { $repo = $candidate }\n }\n if (-not $repo) {\n Write-Error @'\nmmclaude: cannot find the xxclaude repo for self-update.\n Set $env:MMCLAUDE_HOME = 'C:\\path\\to\\xxclaude' or cd into the repo and run pwsh -File ./mmclaude.ps1 update\n'@\n exit 1\n }\n Write-Host \"mmclaude: pulling latest from $repo ...\"\n git -C $repo pull\n if ($LASTEXITCODE -ne 0) {\n Write-Error 'mmclaude: git pull failed. Check network or resolve conflicts manually.'\n exit 1\n }\n Write-Host 'mmclaude: updated.'\n exit 0\n}\n\n# ---- API key resolution ----------------------------------------------------\n\nfunction Resolve-ApiKey {\n if ($env:MIMO_API_KEY) { return $env:MIMO_API_KEY }\n foreach ($scope in 'User', 'Machine') {\n $v = [Environment]::GetEnvironmentVariable('MIMO_API_KEY', $scope)\n if ($v) { return $v }\n }\n Write-Error @'\nMIMO_API_KEY not found.\n Set it persistently (User scope, takes effect in new shells):\n setx MIMO_API_KEY \"sk-xxxxxxxxxxxxxxxxxx\" # or tp-... for Token Plan\n Or for the current shell only:\n $env:MIMO_API_KEY = 'sk-xxxxxxxxxxxxxxxxxx'\n'@\n exit 1\n}\n\n# ---- Arg parsing -----------------------------------------------------------\n\n$WantFlash = $false\n$LongCtx = $false\n$Effort = if ($env:MIMO_EFFORT) { $env:MIMO_EFFORT } else { '' }\n\n$remaining = @()\n$rest = @($Rest)\n$i = 0\n:argloop while ($i -lt $rest.Count) {\n $a = $rest[$i]\n switch -CaseSensitive ($a) {\n 'update' { Invoke-MmclaudeUpdate }\n 'fast' { $WantFlash = $true; $i++; break }\n 'flash' { $WantFlash = $true; $i++; break }\n 'long' { $LongCtx = $true; $i++; break }\n 'effort' {\n $i++; if ($i -lt $rest.Count) { $l=$rest[$i]; if ($l -in 'low','medium','high','xhigh','max'){$Effort=$l;$i++;break}else{Write-Error \"mmclaude: invalid effort level '$l'. Use: low medium high xhigh max\";exit 1}}else{Write-Error \"mmclaude: 'effort' requires a level: low medium high xhigh max\";exit 1}\n }\n '--' {\n $i++\n if ($i -lt $rest.Count) { $remaining += $rest[$i..($rest.Count - 1)] }\n break argloop\n }\n default {\n $remaining += $rest[$i..($rest.Count - 1)]\n break argloop\n }\n }\n}\n\n$apiKey = Resolve-ApiKey\n\n# Auto-detect the base URL from the key prefix; MIMO_BASE_URL always wins.\n$baseUrl = if ($env:MIMO_BASE_URL) {\n $env:MIMO_BASE_URL\n} elseif ($apiKey -like 'tp-*') {\n 'https://token-plan-cn.xiaomimimo.com/anthropic'\n} else {\n 'https://api.xiaomimimo.com/anthropic'\n}\n\n$proModel = if ($env:MIMO_MODEL) { $env:MIMO_MODEL } else { 'mimo-v2.5-pro' }\n$flashModel = if ($env:MIMO_FLASH_MODEL) { $env:MIMO_FLASH_MODEL } else { 'mimo-v2.5' }\n\n$mainModel = if ($WantFlash) { $flashModel } else { $proModel }\n\n# Pick the \"other\" model to surface in Claude Code's /model picker.\nif ($mainModel -eq $proModel) {\n $otherModel = $flashModel\n $otherDesc = 'MiMo v2.5 — fast / cheap haiku tier'\n} else {\n $otherModel = $proModel\n $otherDesc = 'MiMo v2.5 Pro — full reasoning'\n}\n\n# ---- Export env for claude -------------------------------------------------\n\n# MiMo docs warn that lingering official Anthropic credentials shadow\n# ANTHROPIC_AUTH_TOKEN and make Claude Code hit api.anthropic.com instead.\n$env:ANTHROPIC_API_KEY = $null\n\n$env:ANTHROPIC_BASE_URL = $baseUrl\n$env:ANTHROPIC_AUTH_TOKEN = $apiKey\n$env:ANTHROPIC_MODEL = $mainModel\n$env:ANTHROPIC_DEFAULT_OPUS_MODEL = $mainModel\n$env:ANTHROPIC_DEFAULT_SONNET_MODEL = $mainModel\n$env:ANTHROPIC_DEFAULT_HAIKU_MODEL = $flashModel\n# Subagents run on the cheaper flash tier.\n$env:CLAUDE_CODE_SUBAGENT_MODEL = $flashModel\n\n# Expose the other MiMo model inside the /model picker (skip when identical).\nif ($otherModel -ne $mainModel) {\n $env:ANTHROPIC_CUSTOM_MODEL_OPTION = $otherModel\n $env:ANTHROPIC_CUSTOM_MODEL_OPTION_NAME = $otherModel\n $env:ANTHROPIC_CUSTOM_MODEL_OPTION_DESCRIPTION = $otherDesc\n}\n\n# ---- Effort level ----------------------------------------------------------\nif ($Effort) { $env:CLAUDE_CODE_EFFORT_LEVEL = $Effort }\n# ---- Context window --------------------------------------------------------\n$ctx = if ($env:MIMO_CTX) { $env:MIMO_CTX } elseif ($LongCtx) { '1048576' } else { '' }\nif ($ctx) { $env:CLAUDE_CODE_MAX_CONTEXT_TOKENS = $ctx; $env:DISABLE_COMPACT = '1' }\n# ---- Output cap ------------------------------------------------------------\nif ($env:MIMO_OUTPUT) { $env:CLAUDE_CODE_MAX_OUTPUT_TOKENS = $env:MIMO_OUTPUT }\n\n# ---- Launch ----------------------------------------------------------------\n\nif (-not (Get-Command claude -ErrorAction SilentlyContinue)) {\n Write-Error @'\nmmclaude: `claude` CLI not found on PATH.\n Install Claude Code: npm install -g @anthropic-ai/claude-code\n Then re-run this script.\n'@\n exit 1\n}\n\n$banner = \"🚀 Claude Code on MiMo → $mainModel ($baseUrl)\"\nif ($ctx) { $banner += \" | ctx=$ctx\" }\nif ($Effort) { $banner += \" | effort=$Effort\" }\nif ($otherModel -ne $mainModel) { $banner += ' (switch mid-session via /model)' }\nWrite-Host $banner\n\n& claude @remaining\nexit $LASTEXITCODE\n"}}, "xclaude": {"c07db31916dca8077b9124f5c098258f9607b016": {"t": 1785595188.9795377, "n": 9065, "h": "d43238ea81783fad", "c": "#!/usr/bin/env bash\n# shellcheck disable=SC2034 # variables consumed by lib/common.sh\n# xclaude — auto-detect your API key and launch the right backend for Claude Code.\n#\n# Checks env vars and shell rc files for a known API key, then delegates to the\n# matching launcher. No need to remember which script name maps to which provider.\n#\n# Supported providers (checked in order):\n# DEEPSEEK_API_KEY → dsclaude (DeepSeek)\n# MIMO_API_KEY → mmclaude (Xiaomi MiMo)\n# DASHSCOPE_API_KEY → qwclaude (Bailian Qwen, pay-as-you-go)\n# DASHSCOPE_CP_API_KEY → qwclaude (Bailian Qwen, Coding Plan)\n# DASHSCOPE_TP_API_KEY → qwclaude (Bailian Qwen, Token Plan)\n# GLM_API_KEY → glmclaude (ZhipuAI GLM)\n# KIMI_API_KEY → kmclaude (Moonshot Kimi)\n# ARK_API_KEY → arkclaude (Volcengine Ark)\n# LONGCAT_API_KEY → lcclaude (Meituan LongCat)\n# MINIMAX_API_KEY → mxclaude (MiniMax)\n# HY_API_KEY → hyclaude (Tencent TokenHub)\n# SF_API_KEY → sfclaude (SiliconFlow)\n#\n# Quick start:\n# chmod +x xclaude && ./xclaude\n#\n# All args are forwarded to the underlying launcher, so everything works:\n# xclaude fast long effort max # fast model, 1M context, max effort\n# xclaude kimi # on TokenHub → kimi-k2.7-code; on Ark → same\n# xclaude --help # forwarded to claude\n#\n# If multiple keys are set, the first found wins (with a notice).\n# Set XCLAUDE_PREFER=dsclaude|... to force a specific provider.\n\nset -euo pipefail\n\n# Resolve symlink to find the real script directory.\n_SELF=\"$0\"\nif [ -L \"$_SELF\" ]; then\n _LINK=\"$(readlink \"$_SELF\")\"\n case \"$_LINK\" in\n /*) _SELF=\"$_LINK\" ;;\n *) _SELF=\"$(cd \"$(dirname \"$_SELF\")\" && pwd)/$_LINK\" ;;\n esac\nfi\nSELF_DIR=\"$(cd \"$(dirname \"$_SELF\")\" && pwd)\"\nif [ -f \"$SELF_DIR/lib/common.sh\" ]; then source \"$SELF_DIR/lib/common.sh\"\nelif [ -f \"$SELF_DIR/../lib/common.sh\" ]; then source \"$SELF_DIR/../lib/common.sh\"\nelse echo \"xclaude: cannot find lib/common.sh. Reinstall or cd to repo.\" >&2; exit 1; fi\n\ncheck_version \"xclaude\" \"$@\"\n\n# ---- Ensure claude is available (called before each exec path) ----------------\n_ensure_claude() {\n if command -v claude >/dev/null 2>&1; then return 0; fi\n echo \"xclaude: 'claude' not found in PATH.\" >&2\n echo \" Install Claude Code: npm install -g @anthropic-ai/claude-code\" >&2\n echo \" Docs: https://docs.anthropic.com/en/docs/claude-code/overview\" >&2\n exit 1\n}\n\n# ---- Resolve the repo directory (for finding launcher scripts) ---------------\nREPO=\"$(find_repo \"XCLAUDE_HOME\")\"\nif [ -z \"$REPO\" ]; then\n echo \"xclaude: cannot find the xxclaude repo.\" >&2\n echo \" Set XCLAUDE_HOME=/path/to/xxclaude or cd into the repo and run ./xclaude\" >&2\n exit 1\nfi\n\n# ---- Extract an API key from env or shell rc files --------------------------\n# Uses the shared extract_key_from_file which skips commented-out lines.\nget_key() {\n local var=\"$1\"\n # 1) Env var.\n if [ -n \"${!var:-}\" ]; then printf '%s' \"${!var}\"; return 0; fi\n # 2) Shell rc files (via shared extract_key_from_file).\n local f candidate\n for f in \"$HOME/.zshrc\" \"$HOME/.bashrc\" \"$HOME/.bash_profile\" \"$HOME/.profile\"; do\n candidate=\"$(extract_key_from_file \"$f\" \"$var\" || true)\"\n if [ -n \"${candidate:-}\" ]; then printf '%s' \"$candidate\"; return 0; fi\n done\n return 1\n}\n\n# ---- Provider registry (key_var → launcher_name, label) ---------------------\n# Order matters: first match wins when multiple keys are set.\nPROVIDERS=(\n \"DEEPSEEK_API_KEY:dsclaude:DeepSeek\"\n \"MIMO_API_KEY:mmclaude:Xiaomi MiMo\"\n \"DASHSCOPE_API_KEY:qwclaude:Bailian Qwen payg\"\n \"DASHSCOPE_CP_API_KEY:qwclaude:Bailian Qwen CodingPlan\"\n \"DASHSCOPE_TP_API_KEY:qwclaude:Bailian Qwen TokenPlan\"\n \"GLM_API_KEY:glmclaude:ZhipuAI GLM\"\n \"KIMI_API_KEY:kmclaude:Moonshot Kimi\"\n \"ARK_API_KEY:arkclaude:Volcengine Ark\"\n \"LONGCAT_API_KEY:lcclaude:Meituan LongCat\"\n \"MINIMAX_API_KEY:mxclaude:MiniMax\"\n \"HY_API_KEY:hyclaude:Tencent TokenHub\"\n \"SF_API_KEY:sfclaude:SiliconFlow\"\n)\n\n# ---- Subcommands: ls, menu -------------------------------------------------\nif [ $# -gt 0 ]; then\n case \"$1\" in\n ls|list)\n printf \"%-20s %-4s %-25s %s\\n\" \"BACKEND\" \"KEY\" \"ENV_VAR\" \"LAUNCHER\"\n printf \"%-20s %-4s %-25s %s\\n\" \"-------\" \"---\" \"-------\" \"--------\"\n for entry in \"${PROVIDERS[@]}\"; do\n IFS=\":\" read -r key_var launcher label <<< \"$entry\"\n status=\"✗\"\n get_key \"$key_var\" >/dev/null 2>&1 && status=\"✓\"\n printf \"%-20s %-4s %-25s %s\\n\" \"$label\" \"$status\" \"$key_var\" \"$launcher\"\n done\n echo \"\"\n echo \"Set any key above and run: xclaude\"\n exit 0\n ;;\n menu|pick)\n echo \"Select a backend (enter number):\"\n echo \"\"\n i=1\n choices=()\n for entry in \"${PROVIDERS[@]}\"; do\n IFS=\":\" read -r key_var launcher label <<< \"$entry\"\n mark=\" \"; extra=\"\"\n if get_key \"$key_var\" >/dev/null 2>&1; then\n mark=\"✓\"; extra=\" ← key set\"\n else\n mark=\"✗\"; extra=\" (key not set)\"\n fi\n printf \" %2d) [%s] %-30s%s\\n\" \"$i\" \"$mark\" \"$label\" \"$extra\"\n choices+=(\"$launcher\")\n i=$((i+1))\n done\n echo \"\"\n read -r -p \"Choice [1-$((i-1))]: \" choice\n idx=\"${choice:-1}\"\n if [ \"$idx\" -ge 1 ] 2>/dev/null && [ \"$idx\" -lt \"$i\" ]; then\n SELECTED=\"${choices[$((idx-1))]}\"\n LAUNCHER_PATH=\"$REPO/$SELECTED\"\n if [ -x \"$LAUNCHER_PATH\" ]; then\n echo \"xclaude: launching $SELECTED...\"\n shift\n _ensure_claude\n exec \"$LAUNCHER_PATH\" \"$@\"\n else\n echo \"xclaude: launcher not found: $LAUNCHER_PATH\" >&2; exit 1\n fi\n else\n echo \"xclaude: invalid choice.\" >&2; exit 1\n fi\n exit 0\n ;;\n help|--help|-h)\n echo \"xclaude — auto-detect API key and launch the right backend.\"\n echo \"\"\n echo \"Usage:\"\n echo \" xclaude [args] Auto-detect and launch\"\n echo \" xclaude ls List all backends and key status\"\n echo \" xclaude menu Interactive backend picker\"\n echo \" xclaude All args forwarded to launcher\"\n echo \" (fast, long, effort, model aliases...)\"\n echo \"\"\n echo \"Env:\"\n echo \" XCLAUDE_PREFER= Force a specific backend\"\n echo \" XCLAUDE_HOME=/path/to/repo Repo location override\"\n exit 0\n ;;\n esac\nfi\n\n# ---- Override via XCLAUDE_PREFER -------------------------------------------\nif [ -n \"${XCLAUDE_PREFER:-}\" ]; then\n FOUND=\"\"\n for entry in \"${PROVIDERS[@]}\"; do\n IFS=\":\" read -r key_var launcher label <<< \"$entry\"\n if [ \"$launcher\" = \"$XCLAUDE_PREFER\" ]; then\n key=\"$(get_key \"$key_var\" || true)\"\n if [ -n \"${key:-}\" ]; then FOUND=\"$launcher:$key:$label\"; break; fi\n fi\n done\n if [ -z \"$FOUND\" ]; then\n echo \"xclaude: XCLAUDE_PREFER=$XCLAUDE_PREFER but that key is not set. Trying auto-detect...\" >&2\n fi\nfi\n\n# ---- Auto-detect -----------------------------------------------------------\nif [ -z \"${FOUND:-}\" ]; then\n FOUND=\"\"\n for entry in \"${PROVIDERS[@]}\"; do\n IFS=\":\" read -r key_var launcher label <<< \"$entry\"\n key=\"$(get_key \"$key_var\" || true)\"\n if [ -n \"${key:-}\" ]; then\n if [ -z \"$FOUND\" ]; then\n FOUND=\"$launcher:$key:$label\"\n else\n # Multiple keys detected — warn but stick with the first.\n echo \"xclaude: multiple API keys detected. Using first found ($label).\" >&2\n echo \" Set XCLAUDE_PREFER= to choose a specific provider.\" >&2\n break\n fi\n fi\n done\nfi\n\nif [ -z \"${FOUND:-}\" ]; then\n echo \"❌ xclaude: no known API key found.\" >&2\n echo \" Set one of these in your ~/.zshrc or environment:\" >&2\n echo \" export DEEPSEEK_API_KEY=sk-... # DeepSeek\" >&2\n echo \" export GLM_API_KEY=... # ZhipuAI GLM\" >&2\n echo \" export KIMI_API_KEY=sk-... # Moonshot Kimi\" >&2\n echo \" export DASHSCOPE_API_KEY=sk-... # Bailian Qwen\" >&2\n echo \" export ARK_API_KEY=... # Volcengine Ark\" >&2\n echo \" export LONGCAT_API_KEY=lc-... # Meituan LongCat\" >&2\n echo \" export MINIMAX_API_KEY=... # MiniMax\" >&2\n echo \" export HY_API_KEY=... # Tencent TokenHub\" >&2\n echo \" export SF_API_KEY=sk-... # SiliconFlow\" >&2\n echo \" export MIMO_API_KEY=sk-... # Xiaomi MiMo\" >&2\n echo \" Or use a specific launcher directly: dsclaude, mmclaude, qwclaude, ...\" >&2\n exit 1\nfi\n\nIFS=\":\" read -r LAUNCHER _ VALID_LABEL <<< \"$FOUND\"\nLAUNCHER_PATH=\"$REPO/$LAUNCHER\"\n\nif [ ! -x \"$LAUNCHER_PATH\" ]; then\n echo \"xclaude: launcher not found or not executable at $LAUNCHER_PATH\" >&2\n exit 1\nfi\n\n# Forward ALL remaining args to the underlying launcher.\n# The launcher will handle its own arg parsing (fast, long, effort, model aliases, etc.).\necho \"xclaude: detected $VALID_LABEL → delegating to $LAUNCHER\"\n_ensure_claude\nexec \"$LAUNCHER_PATH\" \"$@\"\n"}}, "docs/zh.md": {"c07db31916dca8077b9124f5c098258f9607b016": {"t": 1785595190.537779, "n": 6736, "h": "a24a31a144fe42c1", "c": "---\ntitle: dsclaude\ndescription: 面向非 Anthropic 后端的启动器工具集\n---\n\n[English](./) · **中文** · [GitHub](https://github.com/Agents365-ai/dsclaude) · [Gitee 镜像](https://gitee.com/Agents365-ai/dsclaude)\n\n让 [Claude Code](https://claude.ai/code) 和 Claude Desktop 接入 DeepSeek、小米 MiMo 等第三方模型后端的小工具集。\n\n**作者:** [Agents365-ai](https://github.com/Agents365-ai) · [Bilibili](https://space.bilibili.com/441831884)\n\n---\n\n## 工具一览\n\n| 工具 | 作用 | 平台 | 后端 |\n|------|------|------|------|\n| **[dsclaude](https://github.com/Agents365-ai/dsclaude/blob/main/dsclaude)** | Claude Code CLI 启动器 | macOS / Linux | DeepSeek |\n| **[mmclaude](https://github.com/Agents365-ai/dsclaude/blob/main/mmclaude)** | Claude Code CLI 启动器 | macOS / Linux | 小米 MiMo |\n| **[dsclaude-desktop](https://github.com/Agents365-ai/dsclaude/blob/main/dsclaude-desktop)** | Claude Desktop GUI 配置器 | macOS | DeepSeek |\n| **[dsclaude-desktop.ps1](https://github.com/Agents365-ai/dsclaude/blob/main/dsclaude-desktop.ps1)** | Claude Desktop GUI 配置器 | Windows | DeepSeek |\n| **[skills/deepseek-vision](https://github.com/Agents365-ai/dsclaude/tree/main/skills/deepseek-vision)** | 视觉识别 skill(零依赖) | macOS / Linux | DashScope Qwen |\n| **[dsvision-mcp](https://github.com/Agents365-ai/dsclaude/blob/main/dsvision-mcp)** | 视觉识别 MCP 服务 | macOS / Linux | DashScope Qwen |\n\n---\n\n## macOS 快速开始\n\n```bash\ngit clone https://github.com/Agents365-ai/dsclaude.git\ncd dsclaude\nchmod +x dsclaude\n./dsclaude\n```\n\n---\n\n## dsclaude — Claude Code 接入 DeepSeek\n\n遵循 [DeepSeek Anthropic API](https://api-docs.deepseek.com/guides/anthropic_api) 指南。\n\n```bash\nexport DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxxxxxxx # 添加到 ~/.zshrc\n\ndsclaude # 默认 deepseek-v4-pro(完整推理)\ndsclaude fast # deepseek-v4-flash(更快更便宜)\ndsclaude long # 1M 上下文窗口\ndsclaude long fast # 1M + flash\n```\n\n自动设置 DeepSeek 推荐的环境变量(`ANTHROPIC_BASE_URL`、模型映射、`CLAUDE_CODE_EFFORT_LEVEL=max`),并在 `/model` 选择器中暴露备选模型。上下文窗口上限可通过 `DSCLAUDE_MAX_TOKENS` 覆盖,effort 级别通过 `DSCLAUDE_EFFORT` 覆盖。\n\n> 两个模型都原生支持 1M token,在 Claude Code 中需加 `[1m]` 后缀(如 `deepseek-v4-pro[1m]`),脚本已自动处理。\n\n---\n\n## mmclaude — Claude Code 接入小米 MiMo\n\n```bash\nexport MIMO_API_KEY=sk-xxxxxxxxxxxxxxxxxx # 按量付费\n# 或\nexport MIMO_API_KEY=tp-xxxxxxxxxxxxxxxxxx # Token Plan\n\nmmclaude # 启动 mimo-v2.5-pro\nmmclaude update # git pull 拉取更新\n```\n\n按 key 前缀自动选择 base URL(`sk-*` → 公网,`tp-*` → Token Plan),可用 `MIMO_BASE_URL` 覆盖。所有模型槽位都指向 `mimo-v2.5-pro`,并自动 unset `ANTHROPIC_API_KEY`(避免遮蔽 bearer token)。\n\n---\n\n## dsclaude-desktop — Claude Desktop GUI 配置器\n\n一键配置 Claude Desktop **内置**的 Third-Party Inference 功能(Developer 菜单),预填 DeepSeek 参数并重启 App。\n\n### 前置条件\n\n1. 已安装 Claude Desktop([claude.ai/download](https://claude.ai/download))\n2. 已启用 Developer Mode(Help → Troubleshooting → Enable Developer Mode,一次即可)\n3. 已设置 `DEEPSEEK_API_KEY` 环境变量\n\n### 用法(macOS)\n\n```bash\nexport DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxxxxxxx\n./dsclaude-desktop # 配置并重启\n./dsclaude-desktop -h # 帮助\n```\n\n脚本在 `~/Library/Application Support/Claude-3p/configLibrary/` 下生成配置 entry,将其设为 `appliedId`,然后重启 App。原本通过 GUI 添加的其他 entry 不受影响。\n\n### 模式切换\n\nClaude Desktop 启动选择器原生支持 Anthropic ↔ Gateway 切换,无需 `--revert`。在 App 内点头像 → Disconnect,下次启动时选另一个入口即可。\n\n> 唯一不可用的功能是经典 **Chat**(依赖 Anthropic 托管服务且不在 inference API 表面)。需要用 Chat 时切回 Anthropic 模式即可。\n\n### 用法(Windows)\n\n```powershell\n$env:DEEPSEEK_API_KEY = \"sk-xxxxxxxxxxxxxxxxxx\"\npwsh ./dsclaude-desktop.ps1\n```\n\n**无需手动启用 Developer Mode** —— 脚本会自动创建 `developer_settings.json`。\n\n配置目录:`%LOCALAPPDATA%\\Claude-3p\\configLibrary\\`(若为 Store/MSIX 安装,脚本还会额外写入沙箱路径 `LocalCache\\Roaming\\Claude-3p\\configLibrary\\` 作为后备)。\n\n已在 Windows 11 + Claude Desktop 1.7196(Windows Store, arm64)上实测通过。\n\n---\n\n## deepseek-vision skill — 视觉识别(零依赖方案)\n\n给纯文本模型(如 DeepSeek)补上\"看图\"能力的 skill。代理遇到图片时调 `analyze-image` 脚本,发给 Qwen3.6-Flash 识别后将描述返回主模型。\n\n```bash\nexport DASHSCOPE_API_KEY=sk-xxxxxxxxxxxxxxxxxx\n./skills/deepseek-vision/analyze-image /path/to/screenshot.png \"图里报的什么错?\"\n./skills/deepseek-vision/analyze-image https://example.com/diagram.png\n```\n\n任何加载 `SKILL.md` 的 agent(Claude Code、Cowork 等)都能用它。默认模型 `qwen3.6-flash`,可通过 `DSVISION_MODEL` 和 `DSVISION_BASE_URL` 切换。\n\n> **限制**:需文件路径或 URL,不支持拖拽/粘贴/「+ → Add files or photos」上传的图片。这类场景请用下方的 **dsvision-mcp**。\n\n---\n\n## dsvision-mcp — 视觉识别(MCP 方案)\n\n功能同上,但以 MCP 服务形式运行,绕过 Cowork 沙箱的两个限制:\n\n1. **网络出口管制** — skill 调 DashScope API 会被沙箱防火墙拦截,MCP 服务跑在沙箱外\n2. **内联图片** — 自动读取 `~/.claude/image-cache/` 中最新缓存,拖拽/粘贴/菜单上传均可正常工作(仅 macOS,Windows Cowork 不缓存内联图)\n\n### 安装\n\n```bash\npip3 install fastmcp requests\nexport DASHSCOPE_API_KEY=sk-xxxxxxxxxxxxxxxxxx # 建议加到 ~/.zshrc\ncd /path/to/dsclaude && pwd # 记下绝对路径\n```\n\n然后根据当前模式,在对应的配置文件中添加 MCP 服务:\n\n| 模式 | 配置文件 |\n|------|----------|\n| 3P/Gateway(通过 `dsclaude-desktop` 使用 DeepSeek) | `~/Library/Application Support/Claude-3p/claude_desktop_config.json` |\n| 标准 Anthropic 模式 | `~/Library/Application Support/Claude/claude_desktop_config.json` |\n\n```json\n{\n \"mcpServers\": {\n \"dsvision\": {\n \"command\": \"/绝对/路径/dsclaude/dsvision-mcp\"\n }\n }\n}\n```\n\n重启 Claude Desktop 后,`analyze_image` 工具自动出现。\n\n### 用法\n\n```\nanalyze_image() # 自动检测最新缓存图片\nanalyze_image(image_path=\"/绝对/路径/foo.png\")\nanalyze_image(focus=\"图里报的什么错?\") # 自定义 prompt\n```\n\n### 常见问题\n\n| 现象 | 排查方向 |\n|------|----------|\n| 工具不显示 | 配置文件路径选错 / JSON 格式错误(用 `python3 -m json.tool` 校验) |\n| 工具报错 | `DASHSCOPE_API_KEY` 未设置 |\n| `ModuleNotFoundError` | 用 `pip3` 而非 `pip` |\n| 找不到图片 | 传绝对路径,或检查 `~/.claude/image-cache/` 是否存在 |\n\n### skill vs MCP 怎么选\n\n| 场景 | 推荐 |\n|------|------|\n| Claude Code (CLI),给明确路径 | `skills/deepseek-vision`(零依赖) |\n| Cowork / Desktop,拖拽/粘贴内联图 | `dsvision-mcp`(唯一能用的) |\n| Cowork,给明确路径,不介意沙箱限制 | 两者均可 |\n\n---\n\n## 社区\n\n- **Discord:** \n- **微信:** 扫描下方二维码\n\n

\n \"微信交流群\"\n

\n\n## 赞赏支持\n\n如果这些脚本为你节省了时间,欢迎支持作者:\n\n\n \n \n \n \n \n \n
\"微信支付\"
微信支付
\"支付宝\"
支付宝
\"Buy
Buy Me a Coffee
\"打赏\"
打赏鼓励
\n\n## 开源协议\n\n[CC BY-NC 4.0](https://github.com/Agents365-ai/dsclaude/blob/main/LICENSE.md) — 非商业用途免费。**商业使用需获得授权。**\n"}, "19aaa2af30c47c7e1a85baed155ff3f239f61d59": {"t": 1785758055.877773, "n": 6736, "h": "a24a31a144fe42c1", "c": "---\ntitle: dsclaude\ndescription: 面向非 Anthropic 后端的启动器工具集\n---\n\n[English](./) · **中文** · [GitHub](https://github.com/Agents365-ai/dsclaude) · [Gitee 镜像](https://gitee.com/Agents365-ai/dsclaude)\n\n让 [Claude Code](https://claude.ai/code) 和 Claude Desktop 接入 DeepSeek、小米 MiMo 等第三方模型后端的小工具集。\n\n**作者:** [Agents365-ai](https://github.com/Agents365-ai) · [Bilibili](https://space.bilibili.com/441831884)\n\n---\n\n## 工具一览\n\n| 工具 | 作用 | 平台 | 后端 |\n|------|------|------|------|\n| **[dsclaude](https://github.com/Agents365-ai/dsclaude/blob/main/dsclaude)** | Claude Code CLI 启动器 | macOS / Linux | DeepSeek |\n| **[mmclaude](https://github.com/Agents365-ai/dsclaude/blob/main/mmclaude)** | Claude Code CLI 启动器 | macOS / Linux | 小米 MiMo |\n| **[dsclaude-desktop](https://github.com/Agents365-ai/dsclaude/blob/main/dsclaude-desktop)** | Claude Desktop GUI 配置器 | macOS | DeepSeek |\n| **[dsclaude-desktop.ps1](https://github.com/Agents365-ai/dsclaude/blob/main/dsclaude-desktop.ps1)** | Claude Desktop GUI 配置器 | Windows | DeepSeek |\n| **[skills/deepseek-vision](https://github.com/Agents365-ai/dsclaude/tree/main/skills/deepseek-vision)** | 视觉识别 skill(零依赖) | macOS / Linux | DashScope Qwen |\n| **[dsvision-mcp](https://github.com/Agents365-ai/dsclaude/blob/main/dsvision-mcp)** | 视觉识别 MCP 服务 | macOS / Linux | DashScope Qwen |\n\n---\n\n## macOS 快速开始\n\n```bash\ngit clone https://github.com/Agents365-ai/dsclaude.git\ncd dsclaude\nchmod +x dsclaude\n./dsclaude\n```\n\n---\n\n## dsclaude — Claude Code 接入 DeepSeek\n\n遵循 [DeepSeek Anthropic API](https://api-docs.deepseek.com/guides/anthropic_api) 指南。\n\n```bash\nexport DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxxxxxxx # 添加到 ~/.zshrc\n\ndsclaude # 默认 deepseek-v4-pro(完整推理)\ndsclaude fast # deepseek-v4-flash(更快更便宜)\ndsclaude long # 1M 上下文窗口\ndsclaude long fast # 1M + flash\n```\n\n自动设置 DeepSeek 推荐的环境变量(`ANTHROPIC_BASE_URL`、模型映射、`CLAUDE_CODE_EFFORT_LEVEL=max`),并在 `/model` 选择器中暴露备选模型。上下文窗口上限可通过 `DSCLAUDE_MAX_TOKENS` 覆盖,effort 级别通过 `DSCLAUDE_EFFORT` 覆盖。\n\n> 两个模型都原生支持 1M token,在 Claude Code 中需加 `[1m]` 后缀(如 `deepseek-v4-pro[1m]`),脚本已自动处理。\n\n---\n\n## mmclaude — Claude Code 接入小米 MiMo\n\n```bash\nexport MIMO_API_KEY=sk-xxxxxxxxxxxxxxxxxx # 按量付费\n# 或\nexport MIMO_API_KEY=tp-xxxxxxxxxxxxxxxxxx # Token Plan\n\nmmclaude # 启动 mimo-v2.5-pro\nmmclaude update # git pull 拉取更新\n```\n\n按 key 前缀自动选择 base URL(`sk-*` → 公网,`tp-*` → Token Plan),可用 `MIMO_BASE_URL` 覆盖。所有模型槽位都指向 `mimo-v2.5-pro`,并自动 unset `ANTHROPIC_API_KEY`(避免遮蔽 bearer token)。\n\n---\n\n## dsclaude-desktop — Claude Desktop GUI 配置器\n\n一键配置 Claude Desktop **内置**的 Third-Party Inference 功能(Developer 菜单),预填 DeepSeek 参数并重启 App。\n\n### 前置条件\n\n1. 已安装 Claude Desktop([claude.ai/download](https://claude.ai/download))\n2. 已启用 Developer Mode(Help → Troubleshooting → Enable Developer Mode,一次即可)\n3. 已设置 `DEEPSEEK_API_KEY` 环境变量\n\n### 用法(macOS)\n\n```bash\nexport DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxxxxxxx\n./dsclaude-desktop # 配置并重启\n./dsclaude-desktop -h # 帮助\n```\n\n脚本在 `~/Library/Application Support/Claude-3p/configLibrary/` 下生成配置 entry,将其设为 `appliedId`,然后重启 App。原本通过 GUI 添加的其他 entry 不受影响。\n\n### 模式切换\n\nClaude Desktop 启动选择器原生支持 Anthropic ↔ Gateway 切换,无需 `--revert`。在 App 内点头像 → Disconnect,下次启动时选另一个入口即可。\n\n> 唯一不可用的功能是经典 **Chat**(依赖 Anthropic 托管服务且不在 inference API 表面)。需要用 Chat 时切回 Anthropic 模式即可。\n\n### 用法(Windows)\n\n```powershell\n$env:DEEPSEEK_API_KEY = \"sk-xxxxxxxxxxxxxxxxxx\"\npwsh ./dsclaude-desktop.ps1\n```\n\n**无需手动启用 Developer Mode** —— 脚本会自动创建 `developer_settings.json`。\n\n配置目录:`%LOCALAPPDATA%\\Claude-3p\\configLibrary\\`(若为 Store/MSIX 安装,脚本还会额外写入沙箱路径 `LocalCache\\Roaming\\Claude-3p\\configLibrary\\` 作为后备)。\n\n已在 Windows 11 + Claude Desktop 1.7196(Windows Store, arm64)上实测通过。\n\n---\n\n## deepseek-vision skill — 视觉识别(零依赖方案)\n\n给纯文本模型(如 DeepSeek)补上\"看图\"能力的 skill。代理遇到图片时调 `analyze-image` 脚本,发给 Qwen3.6-Flash 识别后将描述返回主模型。\n\n```bash\nexport DASHSCOPE_API_KEY=sk-xxxxxxxxxxxxxxxxxx\n./skills/deepseek-vision/analyze-image /path/to/screenshot.png \"图里报的什么错?\"\n./skills/deepseek-vision/analyze-image https://example.com/diagram.png\n```\n\n任何加载 `SKILL.md` 的 agent(Claude Code、Cowork 等)都能用它。默认模型 `qwen3.6-flash`,可通过 `DSVISION_MODEL` 和 `DSVISION_BASE_URL` 切换。\n\n> **限制**:需文件路径或 URL,不支持拖拽/粘贴/「+ → Add files or photos」上传的图片。这类场景请用下方的 **dsvision-mcp**。\n\n---\n\n## dsvision-mcp — 视觉识别(MCP 方案)\n\n功能同上,但以 MCP 服务形式运行,绕过 Cowork 沙箱的两个限制:\n\n1. **网络出口管制** — skill 调 DashScope API 会被沙箱防火墙拦截,MCP 服务跑在沙箱外\n2. **内联图片** — 自动读取 `~/.claude/image-cache/` 中最新缓存,拖拽/粘贴/菜单上传均可正常工作(仅 macOS,Windows Cowork 不缓存内联图)\n\n### 安装\n\n```bash\npip3 install fastmcp requests\nexport DASHSCOPE_API_KEY=sk-xxxxxxxxxxxxxxxxxx # 建议加到 ~/.zshrc\ncd /path/to/dsclaude && pwd # 记下绝对路径\n```\n\n然后根据当前模式,在对应的配置文件中添加 MCP 服务:\n\n| 模式 | 配置文件 |\n|------|----------|\n| 3P/Gateway(通过 `dsclaude-desktop` 使用 DeepSeek) | `~/Library/Application Support/Claude-3p/claude_desktop_config.json` |\n| 标准 Anthropic 模式 | `~/Library/Application Support/Claude/claude_desktop_config.json` |\n\n```json\n{\n \"mcpServers\": {\n \"dsvision\": {\n \"command\": \"/绝对/路径/dsclaude/dsvision-mcp\"\n }\n }\n}\n```\n\n重启 Claude Desktop 后,`analyze_image` 工具自动出现。\n\n### 用法\n\n```\nanalyze_image() # 自动检测最新缓存图片\nanalyze_image(image_path=\"/绝对/路径/foo.png\")\nanalyze_image(focus=\"图里报的什么错?\") # 自定义 prompt\n```\n\n### 常见问题\n\n| 现象 | 排查方向 |\n|------|----------|\n| 工具不显示 | 配置文件路径选错 / JSON 格式错误(用 `python3 -m json.tool` 校验) |\n| 工具报错 | `DASHSCOPE_API_KEY` 未设置 |\n| `ModuleNotFoundError` | 用 `pip3` 而非 `pip` |\n| 找不到图片 | 传绝对路径,或检查 `~/.claude/image-cache/` 是否存在 |\n\n### skill vs MCP 怎么选\n\n| 场景 | 推荐 |\n|------|------|\n| Claude Code (CLI),给明确路径 | `skills/deepseek-vision`(零依赖) |\n| Cowork / Desktop,拖拽/粘贴内联图 | `dsvision-mcp`(唯一能用的) |\n| Cowork,给明确路径,不介意沙箱限制 | 两者均可 |\n\n---\n\n## 社区\n\n- **Discord:** \n- **微信:** 扫描下方二维码\n\n

\n \"微信交流群\"\n

\n\n## 赞赏支持\n\n如果这些脚本为你节省了时间,欢迎支持作者:\n\n\n \n \n \n \n \n \n
\"微信支付\"
微信支付
\"支付宝\"
支付宝
\"Buy
Buy Me a Coffee
\"打赏\"
打赏鼓励
\n\n## 开源协议\n\n[CC BY-NC 4.0](https://github.com/Agents365-ai/dsclaude/blob/main/LICENSE.md) — 非商业用途免费。**商业使用需获得授权。**\n"}, "017b91e3d433498894a800f92646ce146a34a892": {"t": 1785758057.5355337, "n": 6758, "h": "91a290ce52ce422a", "c": "---\ntitle: dsclaude\ndescription: 面向非 Anthropic 后端的启动器工具集\n---\n\n[English](./) · **中文** · [GitHub](https://github.com/Agents365-ai/dsclaude) · [Gitee 镜像](https://gitee.com/Agents365-ai/dsclaude)\n\n让 [Claude Code](https://claude.ai/code) 和 Claude Desktop 接入 DeepSeek、小米 MiMo 等第三方模型后端的小工具集。\n\n**作者:** [Agents365-ai](https://github.com/Agents365-ai) · [Bilibili](https://space.bilibili.com/441831884)\n\n---\n\n## 工具一览\n\n| 工具 | 作用 | 平台 | 后端 |\n|------|------|------|------|\n| **[dsclaude](https://github.com/Agents365-ai/dsclaude/blob/main/dsclaude)** | Claude Code CLI 启动器 | macOS / Linux | DeepSeek |\n| **[mmclaude](https://github.com/Agents365-ai/dsclaude/blob/main/mmclaude)** | Claude Code CLI 启动器 | macOS / Linux | 小米 MiMo |\n| **[dsclaude-desktop](https://github.com/Agents365-ai/dsclaude/blob/main/dsclaude-desktop)** | Claude Desktop GUI 配置器 | macOS | DeepSeek |\n| **[dsclaude-desktop.ps1](https://github.com/Agents365-ai/dsclaude/blob/main/dsclaude-desktop.ps1)** | Claude Desktop GUI 配置器 | Windows | DeepSeek |\n| **[skills/deepseek-vision](https://github.com/Agents365-ai/dsclaude/tree/main/skills/deepseek-vision)** | 视觉识别 skill(零依赖) | macOS / Linux | DashScope Qwen |\n| **[dsvision-mcp](https://github.com/Agents365-ai/dsclaude/blob/main/dsvision-mcp)** | 视觉识别 MCP 服务 | macOS / Linux | DashScope Qwen |\n\n---\n\n## macOS 快速开始\n\n```bash\ngit clone https://github.com/Agents365-ai/dsclaude.git\ncd dsclaude\nchmod +x dsclaude\n./dsclaude\n```\n\n---\n\n## dsclaude — Claude Code 接入 DeepSeek\n\n遵循 [DeepSeek Anthropic API](https://api-docs.deepseek.com/guides/anthropic_api) 指南。\n\n```bash\nexport DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxxxxxxx # 添加到 ~/.zshrc\n\ndsclaude # 默认 deepseek-v4-pro(完整推理)\ndsclaude fast # deepseek-v4-flash(更快更便宜)\ndsclaude long # 1M 上下文窗口\ndsclaude long fast # 1M + flash\n```\n\n自动设置 DeepSeek 推荐的环境变量(`ANTHROPIC_BASE_URL`、模型映射、`CLAUDE_CODE_EFFORT_LEVEL=max`),并在 `/model` 选择器中暴露备选模型。上下文窗口上限可通过 `DSCLAUDE_MAX_TOKENS` 覆盖,effort 级别通过 `DSCLAUDE_EFFORT` 覆盖。\n\n> 两个模型都原生支持 1M token,在 Claude Code 中需加 `[1m]` 后缀(如 `deepseek-v4-pro[1m]`),脚本已自动处理。\n\n---\n\n## mmclaude — Claude Code 接入小米 MiMo\n\n```bash\nexport MIMO_API_KEY=sk-xxxxxxxxxxxxxxxxxx # 按量付费\n# 或\nexport MIMO_API_KEY=tp-xxxxxxxxxxxxxxxxxx # Token Plan\n\nmmclaude # 启动 mimo-v2.5-pro\nmmclaude update # git pull 拉取更新\n```\n\n按 key 前缀自动选择 base URL(`sk-*` → 公网,`tp-*` → Token Plan),可用 `MIMO_BASE_URL` 覆盖。所有模型槽位都指向 `mimo-v2.5-pro`,并自动 unset `ANTHROPIC_API_KEY`(避免遮蔽 bearer token)。\n\n---\n\n## dsclaude-desktop — Claude Desktop GUI 配置器\n\n一键配置 Claude Desktop **内置**的 Third-Party Inference 功能(Developer 菜单),预填 DeepSeek 参数并重启 App。\n\n### 前置条件\n\n1. 已安装 Claude Desktop([claude.ai/download](https://claude.ai/download))\n2. 已启用 Developer Mode(Help → Troubleshooting → Enable Developer Mode,一次即可)\n3. 已设置 `DEEPSEEK_API_KEY` 环境变量\n\n### 用法(macOS)\n\n```bash\nexport DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxxxxxxx\n./dsclaude-desktop # 配置并重启\n./dsclaude-desktop -h # 帮助\n```\n\n脚本在 `~/Library/Application Support/Claude-3p/configLibrary/` 下生成配置 entry,将其设为 `appliedId`,然后重启 App。原本通过 GUI 添加的其他 entry 不受影响。\n\n### 模式切换\n\nClaude Desktop 启动选择器原生支持 Anthropic ↔ Gateway 切换,无需 `--revert`。在 App 内点头像 → Disconnect,下次启动时选另一个入口即可。\n\n> 唯一不可用的功能是经典 **Chat**(依赖 Anthropic 托管服务且不在 inference API 表面)。需要用 Chat 时切回 Anthropic 模式即可。\n\n### 用法(Windows)\n\n```powershell\n$env:DEEPSEEK_API_KEY = \"sk-xxxxxxxxxxxxxxxxxx\"\npwsh ./dsclaude-desktop.ps1\n```\n\n**无需手动启用 Developer Mode** —— 脚本会自动创建 `developer_settings.json`。\n\n配置目录:`%LOCALAPPDATA%\\Claude-3p\\configLibrary\\`(若为 Store/MSIX 安装,脚本还会额外写入沙箱路径 `LocalCache\\Roaming\\Claude-3p\\configLibrary\\` 作为后备)。\n\n已在 Windows 11 + Claude Desktop 1.7196(Windows Store, arm64)上实测通过。\n\n---\n\n## deepseek-vision skill — 视觉识别(零依赖方案)\n\n给纯文本模型(如 DeepSeek)补上\"看图\"能力的 skill。代理遇到图片时调 `analyze-image` 脚本,发给 Qwen3.6-Flash 识别后将描述返回主模型。\n\n```bash\nexport DASHSCOPE_API_KEY=sk-xxxxxxxxxxxxxxxxxx\n./skills/deepseek-vision/analyze-image /path/to/screenshot.png \"图里报的什么错?\"\n./skills/deepseek-vision/analyze-image https://example.com/diagram.png\n```\n\n任何加载 `SKILL.md` 的 agent(Claude Code、Cowork 等)都能用它。默认模型 `qwen3.6-flash`,可通过 `DSVISION_MODEL` 和 `DSVISION_BASE_URL` 切换。\n\n> **限制**:需文件路径或 URL,不支持拖拽/粘贴/「+ → Add files or photos」上传的图片。这类场景请用下方的 **dsvision-mcp**。\n\n---\n\n## dsvision-mcp — 视觉识别(MCP 方案)\n\n功能同上,但以 MCP 服务形式运行,绕过 Cowork 沙箱的两个限制:\n\n1. **网络出口管制** — skill 调 DashScope API 会被沙箱防火墙拦截,MCP 服务跑在沙箱外\n2. **内联图片** — 自动读取 `~/.claude/image-cache/` 中最新缓存,拖拽/粘贴/菜单上传均可正常工作(仅 macOS,Windows Cowork 不缓存内联图)\n\n### 安装\n\n```bash\npip3 install fastmcp requests\nexport DASHSCOPE_API_KEY=sk-xxxxxxxxxxxxxxxxxx # 建议加到 ~/.zshrc\ncd /path/to/dsclaude && pwd # 记下绝对路径\n```\n\n然后根据当前模式,在对应的配置文件中添加 MCP 服务:\n\n| 模式 | 配置文件 |\n|------|----------|\n| 3P/Gateway(通过 `dsclaude-desktop` 使用 DeepSeek) | `~/Library/Application Support/Claude-3p/claude_desktop_config.json` |\n| 标准 Anthropic 模式 | `~/Library/Application Support/Claude/claude_desktop_config.json` |\n\n```json\n{\n \"mcpServers\": {\n \"dsvision\": {\n \"command\": \"/绝对/路径/dsclaude/dsvision-mcp\"\n }\n }\n}\n```\n\n重启 Claude Desktop 后,`analyze_image` 工具自动出现。\n\n### 用法\n\n```\nanalyze_image() # 自动检测最新缓存图片\nanalyze_image(image_path=\"/绝对/路径/foo.png\")\nanalyze_image(focus=\"图里报的什么错?\") # 自定义 prompt\n```\n\n### 常见问题\n\n| 现象 | 排查方向 |\n|------|----------|\n| 工具不显示 | 配置文件路径选错 / JSON 格式错误(用 `python3 -m json.tool` 校验) |\n| 工具报错 | `DASHSCOPE_API_KEY` 未设置 |\n| `ModuleNotFoundError` | 用 `pip3` 而非 `pip` |\n| 找不到图片 | 传绝对路径,或检查 `~/.claude/image-cache/` 是否存在 |\n\n### skill vs MCP 怎么选\n\n| 场景 | 推荐 |\n|------|------|\n| Claude Code (CLI),给明确路径 | `skills/deepseek-vision`(零依赖) |\n| Cowork / Desktop,拖拽/粘贴内联图 | `dsvision-mcp`(唯一能用的) |\n| Cowork,给明确路径,不介意沙箱限制 | 两者均可 |\n\n---\n\n## 社区\n\n- **Discord:** \n- **微信:** 扫描下方二维码\n\n

\n \"微信交流群\"\n

\n\n## 赞赏支持\n\n如果这些脚本为你节省了时间,欢迎支持作者:\n\n\n \n \n \n \n \n \n
\"微信支付\"
微信支付
\"支付宝\"
支付宝
\"Buy
Buy Me a Coffee
\"打赏\"
打赏鼓励
\n\n## 开源协议\n\n[PolyForm Noncommercial 1.0.0](https://github.com/Agents365-ai/dsclaude/blob/main/LICENSE.md) — 个人、科研、教育等非商业用途免费。**禁止商业使用。**\n"}, "6cd1a6909bee21e91a0c849547299a89e547c57c": {"t": 1785758060.4822056, "n": 6637, "h": "bdf6828ac1e1dbcb", "c": "---\ntitle: dsclaude\ndescription: 面向非 Anthropic 后端的启动器工具集\n---\n\n[English](./) · **中文** · [GitHub](https://github.com/Agents365-ai/dsclaude) · [Gitee 镜像](https://gitee.com/Agents365-ai/dsclaude)\n\n让 [Claude Code](https://claude.ai/code) 和 Claude Desktop 接入 DeepSeek、小米 MiMo 等第三方模型后端的小工具集。\n\n**作者:** [Agents365-ai](https://github.com/Agents365-ai) · [Bilibili](https://space.bilibili.com/441831884)\n\n---\n\n## 工具一览\n\n| 工具 | 作用 | 平台 | 后端 |\n|------|------|------|------|\n| **[dsclaude](https://github.com/Agents365-ai/dsclaude/blob/main/dsclaude)** | Claude Code CLI 启动器 | macOS / Linux | DeepSeek |\n| **[mmclaude](https://github.com/Agents365-ai/dsclaude/blob/main/mmclaude)** | Claude Code CLI 启动器 | macOS / Linux | 小米 MiMo |\n| **[dsclaude-desktop](https://github.com/Agents365-ai/dsclaude/blob/main/dsclaude-desktop)** | Claude Desktop GUI 配置器 | macOS | DeepSeek |\n| **[dsclaude-desktop.ps1](https://github.com/Agents365-ai/dsclaude/blob/main/dsclaude-desktop.ps1)** | Claude Desktop GUI 配置器 | Windows | DeepSeek |\n| **[skills/deepseek-vision](https://github.com/Agents365-ai/dsclaude/tree/main/skills/deepseek-vision)** | 视觉识别 skill(零依赖) | macOS / Linux | DashScope Qwen |\n| **[dsvision-mcp](https://github.com/Agents365-ai/dsclaude/blob/main/dsvision-mcp)** | 视觉识别 MCP 服务 | macOS / Linux | DashScope Qwen |\n\n---\n\n## macOS 快速开始\n\n```bash\ngit clone https://github.com/Agents365-ai/dsclaude.git\ncd dsclaude\nchmod +x dsclaude\n./dsclaude\n```\n\n---\n\n## dsclaude — Claude Code 接入 DeepSeek\n\n遵循 [DeepSeek Anthropic API](https://api-docs.deepseek.com/guides/anthropic_api) 指南。\n\n```bash\nexport DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxxxxxxx # 添加到 ~/.zshrc\n\ndsclaude # 默认 deepseek-v4-pro(完整推理)\ndsclaude fast # deepseek-v4-flash(更快更便宜)\ndsclaude long # 1M 上下文窗口\ndsclaude long fast # 1M + flash\n```\n\n自动设置 DeepSeek 推荐的环境变量(`ANTHROPIC_BASE_URL`、模型映射、`CLAUDE_CODE_EFFORT_LEVEL=max`),并在 `/model` 选择器中暴露备选模型。上下文窗口上限可通过 `DSCLAUDE_MAX_TOKENS` 覆盖,effort 级别通过 `DSCLAUDE_EFFORT` 覆盖。\n\n> 两个模型都原生支持 1M token,在 Claude Code 中需加 `[1m]` 后缀(如 `deepseek-v4-pro[1m]`),脚本已自动处理。\n\n---\n\n## mmclaude — Claude Code 接入小米 MiMo\n\n```bash\nexport MIMO_API_KEY=sk-xxxxxxxxxxxxxxxxxx # 按量付费\n# 或\nexport MIMO_API_KEY=tp-xxxxxxxxxxxxxxxxxx # Token Plan\n\nmmclaude # 启动 mimo-v2.5-pro\nmmclaude update # git pull 拉取更新\n```\n\n按 key 前缀自动选择 base URL(`sk-*` → 公网,`tp-*` → Token Plan),可用 `MIMO_BASE_URL` 覆盖。所有模型槽位都指向 `mimo-v2.5-pro`,并自动 unset `ANTHROPIC_API_KEY`(避免遮蔽 bearer token)。\n\n---\n\n## dsclaude-desktop — Claude Desktop GUI 配置器\n\n一键配置 Claude Desktop **内置**的 Third-Party Inference 功能(Developer 菜单),预填 DeepSeek 参数并重启 App。\n\n### 前置条件\n\n1. 已安装 Claude Desktop([claude.ai/download](https://claude.ai/download))\n2. 已启用 Developer Mode(Help → Troubleshooting → Enable Developer Mode,一次即可)\n3. 已设置 `DEEPSEEK_API_KEY` 环境变量\n\n### 用法(macOS)\n\n```bash\nexport DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxxxxxxx\n./dsclaude-desktop # 配置并重启\n./dsclaude-desktop -h # 帮助\n```\n\n脚本在 `~/Library/Application Support/Claude-3p/configLibrary/` 下生成配置 entry,将其设为 `appliedId`,然后重启 App。原本通过 GUI 添加的其他 entry 不受影响。\n\n### 模式切换\n\nClaude Desktop 启动选择器原生支持 Anthropic ↔ Gateway 切换,无需 `--revert`。在 App 内点头像 → Disconnect,下次启动时选另一个入口即可。\n\n> 唯一不可用的功能是经典 **Chat**(依赖 Anthropic 托管服务且不在 inference API 表面)。需要用 Chat 时切回 Anthropic 模式即可。\n\n### 用法(Windows)\n\n```powershell\n$env:DEEPSEEK_API_KEY = \"sk-xxxxxxxxxxxxxxxxxx\"\npwsh ./dsclaude-desktop.ps1\n```\n\n**无需手动启用 Developer Mode** —— 脚本会自动创建 `developer_settings.json`。\n\n配置目录:`%LOCALAPPDATA%\\Claude-3p\\configLibrary\\`(若为 Store/MSIX 安装,脚本还会额外写入沙箱路径 `LocalCache\\Roaming\\Claude-3p\\configLibrary\\` 作为后备)。\n\n已在 Windows 11 + Claude Desktop 1.7196(Windows Store, arm64)上实测通过。\n\n---\n\n## deepseek-vision skill — 视觉识别(零依赖方案)\n\n给纯文本模型(如 DeepSeek)补上\"看图\"能力的 skill。代理遇到图片时调 `analyze-image` 脚本,发给 Qwen3.6-Flash 识别后将描述返回主模型。\n\n```bash\nexport DASHSCOPE_API_KEY=sk-xxxxxxxxxxxxxxxxxx\n./skills/deepseek-vision/analyze-image /path/to/screenshot.png \"图里报的什么错?\"\n./skills/deepseek-vision/analyze-image https://example.com/diagram.png\n```\n\n任何加载 `SKILL.md` 的 agent(Claude Code、Cowork 等)都能用它。默认模型 `qwen3.6-flash`,可通过 `DSVISION_MODEL` 和 `DSVISION_BASE_URL` 切换。\n\n> **限制**:需文件路径或 URL,不支持拖拽/粘贴/「+ → Add files or photos」上传的图片。这类场景请用下方的 **dsvision-mcp**。\n\n---\n\n## dsvision-mcp — 视觉识别(MCP 方案)\n\n功能同上,但以 MCP 服务形式运行,绕过 Cowork 沙箱的两个限制:\n\n1. **网络出口管制** — skill 调 DashScope API 会被沙箱防火墙拦截,MCP 服务跑在沙箱外\n2. **内联图片** — 自动读取 `~/.claude/image-cache/` 中最新缓存,拖拽/粘贴/菜单上传均可正常工作(仅 macOS,Windows Cowork 不缓存内联图)\n\n### 安装\n\n```bash\npip3 install fastmcp requests\nexport DASHSCOPE_API_KEY=sk-xxxxxxxxxxxxxxxxxx # 建议加到 ~/.zshrc\ncd /path/to/dsclaude && pwd # 记下绝对路径\n```\n\n然后根据当前模式,在对应的配置文件中添加 MCP 服务:\n\n| 模式 | 配置文件 |\n|------|----------|\n| 3P/Gateway(通过 `dsclaude-desktop` 使用 DeepSeek) | `~/Library/Application Support/Claude-3p/claude_desktop_config.json` |\n| 标准 Anthropic 模式 | `~/Library/Application Support/Claude/claude_desktop_config.json` |\n\n```json\n{\n \"mcpServers\": {\n \"dsvision\": {\n \"command\": \"/绝对/路径/dsclaude/dsvision-mcp\"\n }\n }\n}\n```\n\n重启 Claude Desktop 后,`analyze_image` 工具自动出现。\n\n### 用法\n\n```\nanalyze_image() # 自动检测最新缓存图片\nanalyze_image(image_path=\"/绝对/路径/foo.png\")\nanalyze_image(focus=\"图里报的什么错?\") # 自定义 prompt\n```\n\n### 常见问题\n\n| 现象 | 排查方向 |\n|------|----------|\n| 工具不显示 | 配置文件路径选错 / JSON 格式错误(用 `python3 -m json.tool` 校验) |\n| 工具报错 | `DASHSCOPE_API_KEY` 未设置 |\n| `ModuleNotFoundError` | 用 `pip3` 而非 `pip` |\n| 找不到图片 | 传绝对路径,或检查 `~/.claude/image-cache/` 是否存在 |\n\n### skill vs MCP 怎么选\n\n| 场景 | 推荐 |\n|------|------|\n| Claude Code (CLI),给明确路径 | `skills/deepseek-vision`(零依赖) |\n| Cowork / Desktop,拖拽/粘贴内联图 | `dsvision-mcp`(唯一能用的) |\n| Cowork,给明确路径,不介意沙箱限制 | 两者均可 |\n\n---\n\n## 社区\n\n- **Discord:** \n- **微信:** 扫描下方二维码\n\n

\n \"微信交流群\"\n

\n\n## 赞赏支持\n\n如果这些脚本为你节省了时间,欢迎支持作者:\n\n\n \n \n \n \n \n \n
\"微信支付\"
微信支付
\"支付宝\"
支付宝
\"Buy
Buy Me a Coffee
\"打赏\"
打赏鼓励
\n\n## 开源协议\n\nMIT\n"}, "cfc2733483dc3b2284b287357f1da64fe0ce8db9": {"t": 1785758062.0289745, "n": 6583, "h": "3ec3021bf0482760", "c": "---\ntitle: dsclaude\ndescription: 面向非 Anthropic 后端的启动器工具集\n---\n\n[English](./) · **中文** · [GitHub](https://github.com/Agents365-ai/dsclaude)\n\n让 [Claude Code](https://claude.ai/code) 和 Claude Desktop 接入 DeepSeek、小米 MiMo 等第三方模型后端的小工具集。\n\n**作者:** [Agents365-ai](https://github.com/Agents365-ai) · [Bilibili](https://space.bilibili.com/441831884)\n\n---\n\n## 工具一览\n\n| 工具 | 作用 | 平台 | 后端 |\n|------|------|------|------|\n| **[dsclaude](https://github.com/Agents365-ai/dsclaude/blob/main/dsclaude)** | Claude Code CLI 启动器 | macOS / Linux | DeepSeek |\n| **[mmclaude](https://github.com/Agents365-ai/dsclaude/blob/main/mmclaude)** | Claude Code CLI 启动器 | macOS / Linux | 小米 MiMo |\n| **[dsclaude-desktop](https://github.com/Agents365-ai/dsclaude/blob/main/dsclaude-desktop)** | Claude Desktop GUI 配置器 | macOS | DeepSeek |\n| **[dsclaude-desktop.ps1](https://github.com/Agents365-ai/dsclaude/blob/main/dsclaude-desktop.ps1)** | Claude Desktop GUI 配置器 | Windows | DeepSeek |\n| **[skills/deepseek-vision](https://github.com/Agents365-ai/dsclaude/tree/main/skills/deepseek-vision)** | 视觉识别 skill(零依赖) | macOS / Linux | DashScope Qwen |\n| **[dsvision-mcp](https://github.com/Agents365-ai/dsclaude/blob/main/dsvision-mcp)** | 视觉识别 MCP 服务 | macOS / Linux | DashScope Qwen |\n\n---\n\n## macOS 快速开始\n\n```bash\ngit clone https://github.com/Agents365-ai/dsclaude.git\ncd dsclaude\nchmod +x dsclaude\n./dsclaude\n```\n\n---\n\n## dsclaude — Claude Code 接入 DeepSeek\n\n遵循 [DeepSeek Anthropic API](https://api-docs.deepseek.com/guides/anthropic_api) 指南。\n\n```bash\nexport DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxxxxxxx # 添加到 ~/.zshrc\n\ndsclaude # 默认 deepseek-v4-pro(完整推理)\ndsclaude fast # deepseek-v4-flash(更快更便宜)\ndsclaude long # 1M 上下文窗口\ndsclaude long fast # 1M + flash\n```\n\n自动设置 DeepSeek 推荐的环境变量(`ANTHROPIC_BASE_URL`、模型映射、`CLAUDE_CODE_EFFORT_LEVEL=max`),并在 `/model` 选择器中暴露备选模型。上下文窗口上限可通过 `DSCLAUDE_MAX_TOKENS` 覆盖,effort 级别通过 `DSCLAUDE_EFFORT` 覆盖。\n\n> 两个模型都原生支持 1M token,在 Claude Code 中需加 `[1m]` 后缀(如 `deepseek-v4-pro[1m]`),脚本已自动处理。\n\n---\n\n## mmclaude — Claude Code 接入小米 MiMo\n\n```bash\nexport MIMO_API_KEY=sk-xxxxxxxxxxxxxxxxxx # 按量付费\n# 或\nexport MIMO_API_KEY=tp-xxxxxxxxxxxxxxxxxx # Token Plan\n\nmmclaude # 启动 mimo-v2.5-pro\nmmclaude update # git pull 拉取更新\n```\n\n按 key 前缀自动选择 base URL(`sk-*` → 公网,`tp-*` → Token Plan),可用 `MIMO_BASE_URL` 覆盖。所有模型槽位都指向 `mimo-v2.5-pro`,并自动 unset `ANTHROPIC_API_KEY`(避免遮蔽 bearer token)。\n\n---\n\n## dsclaude-desktop — Claude Desktop GUI 配置器\n\n一键配置 Claude Desktop **内置**的 Third-Party Inference 功能(Developer 菜单),预填 DeepSeek 参数并重启 App。\n\n### 前置条件\n\n1. 已安装 Claude Desktop([claude.ai/download](https://claude.ai/download))\n2. 已启用 Developer Mode(Help → Troubleshooting → Enable Developer Mode,一次即可)\n3. 已设置 `DEEPSEEK_API_KEY` 环境变量\n\n### 用法(macOS)\n\n```bash\nexport DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxxxxxxx\n./dsclaude-desktop # 配置并重启\n./dsclaude-desktop -h # 帮助\n```\n\n脚本在 `~/Library/Application Support/Claude-3p/configLibrary/` 下生成配置 entry,将其设为 `appliedId`,然后重启 App。原本通过 GUI 添加的其他 entry 不受影响。\n\n### 模式切换\n\nClaude Desktop 启动选择器原生支持 Anthropic ↔ Gateway 切换,无需 `--revert`。在 App 内点头像 → Disconnect,下次启动时选另一个入口即可。\n\n> 唯一不可用的功能是经典 **Chat**(依赖 Anthropic 托管服务且不在 inference API 表面)。需要用 Chat 时切回 Anthropic 模式即可。\n\n### 用法(Windows)\n\n```powershell\n$env:DEEPSEEK_API_KEY = \"sk-xxxxxxxxxxxxxxxxxx\"\npwsh ./dsclaude-desktop.ps1\n```\n\n**无需手动启用 Developer Mode** —— 脚本会自动创建 `developer_settings.json`。\n\n配置目录:`%LOCALAPPDATA%\\Claude-3p\\configLibrary\\`(若为 Store/MSIX 安装,脚本还会额外写入沙箱路径 `LocalCache\\Roaming\\Claude-3p\\configLibrary\\` 作为后备)。\n\n已在 Windows 11 + Claude Desktop 1.7196(Windows Store, arm64)上实测通过。\n\n---\n\n## deepseek-vision skill — 视觉识别(零依赖方案)\n\n给纯文本模型(如 DeepSeek)补上\"看图\"能力的 skill。代理遇到图片时调 `analyze-image` 脚本,发给 Qwen3.6-Flash 识别后将描述返回主模型。\n\n```bash\nexport DASHSCOPE_API_KEY=sk-xxxxxxxxxxxxxxxxxx\n./skills/deepseek-vision/analyze-image /path/to/screenshot.png \"图里报的什么错?\"\n./skills/deepseek-vision/analyze-image https://example.com/diagram.png\n```\n\n任何加载 `SKILL.md` 的 agent(Claude Code、Cowork 等)都能用它。默认模型 `qwen3.6-flash`,可通过 `DSVISION_MODEL` 和 `DSVISION_BASE_URL` 切换。\n\n> **限制**:需文件路径或 URL,不支持拖拽/粘贴/「+ → Add files or photos」上传的图片。这类场景请用下方的 **dsvision-mcp**。\n\n---\n\n## dsvision-mcp — 视觉识别(MCP 方案)\n\n功能同上,但以 MCP 服务形式运行,绕过 Cowork 沙箱的两个限制:\n\n1. **网络出口管制** — skill 调 DashScope API 会被沙箱防火墙拦截,MCP 服务跑在沙箱外\n2. **内联图片** — 自动读取 `~/.claude/image-cache/` 中最新缓存,拖拽/粘贴/菜单上传均可正常工作(仅 macOS,Windows Cowork 不缓存内联图)\n\n### 安装\n\n```bash\npip3 install fastmcp requests\nexport DASHSCOPE_API_KEY=sk-xxxxxxxxxxxxxxxxxx # 建议加到 ~/.zshrc\ncd /path/to/dsclaude && pwd # 记下绝对路径\n```\n\n然后根据当前模式,在对应的配置文件中添加 MCP 服务:\n\n| 模式 | 配置文件 |\n|------|----------|\n| 3P/Gateway(通过 `dsclaude-desktop` 使用 DeepSeek) | `~/Library/Application Support/Claude-3p/claude_desktop_config.json` |\n| 标准 Anthropic 模式 | `~/Library/Application Support/Claude/claude_desktop_config.json` |\n\n```json\n{\n \"mcpServers\": {\n \"dsvision\": {\n \"command\": \"/绝对/路径/dsclaude/dsvision-mcp\"\n }\n }\n}\n```\n\n重启 Claude Desktop 后,`analyze_image` 工具自动出现。\n\n### 用法\n\n```\nanalyze_image() # 自动检测最新缓存图片\nanalyze_image(image_path=\"/绝对/路径/foo.png\")\nanalyze_image(focus=\"图里报的什么错?\") # 自定义 prompt\n```\n\n### 常见问题\n\n| 现象 | 排查方向 |\n|------|----------|\n| 工具不显示 | 配置文件路径选错 / JSON 格式错误(用 `python3 -m json.tool` 校验) |\n| 工具报错 | `DASHSCOPE_API_KEY` 未设置 |\n| `ModuleNotFoundError` | 用 `pip3` 而非 `pip` |\n| 找不到图片 | 传绝对路径,或检查 `~/.claude/image-cache/` 是否存在 |\n\n### skill vs MCP 怎么选\n\n| 场景 | 推荐 |\n|------|------|\n| Claude Code (CLI),给明确路径 | `skills/deepseek-vision`(零依赖) |\n| Cowork / Desktop,拖拽/粘贴内联图 | `dsvision-mcp`(唯一能用的) |\n| Cowork,给明确路径,不介意沙箱限制 | 两者均可 |\n\n---\n\n## 社区\n\n- **Discord:** \n- **微信:** 扫描下方二维码\n\n

\n \"微信交流群\"\n

\n\n## 赞赏支持\n\n如果这些脚本为你节省了时间,欢迎支持作者:\n\n\n \n \n \n \n \n \n
\"微信支付\"
微信支付
\"支付宝\"
支付宝
\"Buy
Buy Me a Coffee
\"打赏\"
打赏鼓励
\n\n## 开源协议\n\nMIT\n"}}, "README.md": {"c07db31916dca8077b9124f5c098258f9607b016": {"t": 1785595191.9534256, "n": 31394, "h": "c49d6c68ebd22a04", "c": "# dsclaude — Claude Code & Claude Desktop launchers for alternative backends\n\n[中文文档](README_CN.md)\n\nA collection of launchers and configurators that point [Claude Code](https://claude.ai/code) and Claude Desktop at third-party model backends (DeepSeek, MiMo, Qwen, GLM, Kimi, Ark, LongCat, MiniMax, TokenHub, SiliconFlow, etc.).\n\n---\n\n## Tools\n\n| Tool | What it does | Platform | Backend |\n| ------ | ------------- | ---------- | --------- |\n| **[dsclaude](dsclaude)** | Claude Code CLI launcher | macOS / Linux | DeepSeek |\n| **[dsclaude.ps1](dsclaude.ps1)** | Claude Code CLI launcher | Windows | DeepSeek |\n| **[mmclaude](mmclaude)** | Claude Code CLI launcher | macOS / Linux | Xiaomi MiMo |\n| **[mmclaude.ps1](mmclaude.ps1)** | Claude Code CLI launcher | Windows | Xiaomi MiMo |\n| **[qwclaude](qwclaude)** | Claude Code CLI launcher | macOS / Linux | Alibaba Cloud Bailian (Qwen) |\n| **[qwclaude.ps1](qwclaude.ps1)** | Claude Code CLI launcher | Windows | Alibaba Cloud Bailian (Qwen) |\n| **[glmclaude](glmclaude)** | Claude Code CLI launcher | macOS / Linux | ZhipuAI GLM |\n| **[glmclaude.ps1](glmclaude.ps1)** | Claude Code CLI launcher | Windows | ZhipuAI GLM |\n| **[kmclaude](kmclaude)** | Claude Code CLI launcher | macOS / Linux | Moonshot AI Kimi |\n| **[kmclaude.ps1](kmclaude.ps1)** | Claude Code CLI launcher | Windows | Moonshot AI Kimi |\n| **[arkclaude](arkclaude)** | Claude Code CLI launcher | macOS / Linux | Volcengine Ark (doubao/Kimi/DeepSeek/GLM…) |\n| **[arkclaude.ps1](arkclaude.ps1)** | Claude Code CLI launcher | Windows | Volcengine Ark (doubao/Kimi/DeepSeek/GLM…) |\n| **[lcclaude](lcclaude)** | Claude Code CLI launcher | macOS / Linux | Meituan LongCat |\n| **[lcclaude.ps1](lcclaude.ps1)** | Claude Code CLI launcher | Windows | Meituan LongCat |\n| **[mxclaude](mxclaude)** | Claude Code CLI launcher | macOS / Linux | MiniMax |\n| **[mxclaude.ps1](mxclaude.ps1)** | Claude Code CLI launcher | Windows | MiniMax |\n| **[hyclaude](hyclaude)** | Claude Code CLI launcher | macOS / Linux | Tencent TokenHub (HY3/DeepSeek/Kimi/GLM…) |\n| **[hyclaude.ps1](hyclaude.ps1)** | Claude Code CLI launcher | Windows | Tencent TokenHub (HY3/DeepSeek/Kimi/GLM…) |\n| **[sfclaude](sfclaude)** | Claude Code CLI launcher | macOS / Linux | SiliconFlow (DeepSeek/Kimi/GLM/Qwen/Yi…) |\n| **[sfclaude.ps1](sfclaude.ps1)** | Claude Code CLI launcher | Windows | SiliconFlow (DeepSeek/Kimi/GLM/Qwen/Yi…) |\n| **[xclaude](xclaude)** | Unified auto-detect launcher | macOS / Linux | Any (auto-detects from API keys) |\n| **[dsclaude-desktop](dsclaude-desktop)** | Claude Desktop GUI configurator | macOS | DeepSeek |\n| **[dsclaude-desktop.ps1](dsclaude-desktop.ps1)** | Claude Desktop GUI configurator | Windows | DeepSeek |\n| **[mmclaude-desktop](mmclaude-desktop)** | Claude Desktop GUI configurator | macOS | Xiaomi MiMo |\n| **[mmclaude-desktop.ps1](mmclaude-desktop.ps1)** | Claude Desktop GUI configurator | Windows | Xiaomi MiMo |\n| **[qwclaude-desktop](qwclaude-desktop)** | Claude Desktop GUI configurator | macOS | Alibaba Cloud Bailian (Qwen) |\n| **[qwclaude-desktop.ps1](qwclaude-desktop.ps1)** | Claude Desktop GUI configurator | Windows | Alibaba Cloud Bailian (Qwen) |\n| **[glmclaude-desktop](glmclaude-desktop)** | Claude Desktop GUI configurator | macOS | ZhipuAI GLM |\n| **[glmclaude-desktop.ps1](glmclaude-desktop.ps1)** | Claude Desktop GUI configurator | Windows | ZhipuAI GLM |\n| **[kmclaude-desktop](kmclaude-desktop)** | Claude Desktop GUI configurator | macOS | Moonshot AI Kimi |\n| **[kmclaude-desktop.ps1](kmclaude-desktop.ps1)** | Claude Desktop GUI configurator | Windows | Moonshot AI Kimi |\n| **[arkclaude-desktop](arkclaude-desktop)** | Claude Desktop GUI configurator | macOS | Volcengine Ark |\n| **[arkclaude-desktop.ps1](arkclaude-desktop.ps1)** | Claude Desktop GUI configurator | Windows | Volcengine Ark |\n| **[lcclaude-desktop](lcclaude-desktop)** | Claude Desktop GUI configurator | macOS | Meituan LongCat |\n| **[lcclaude-desktop.ps1](lcclaude-desktop.ps1)** | Claude Desktop GUI configurator | Windows | Meituan LongCat |\n| **[mxclaude-desktop](mxclaude-desktop)** | Claude Desktop GUI configurator | macOS | MiniMax |\n| **[mxclaude-desktop.ps1](mxclaude-desktop.ps1)** | Claude Desktop GUI configurator | Windows | MiniMax |\n| **[hyclaude-desktop](hyclaude-desktop)** | Claude Desktop GUI configurator | macOS | Tencent TokenHub |\n| **[hyclaude-desktop.ps1](hyclaude-desktop.ps1)** | Claude Desktop GUI configurator | Windows | Tencent TokenHub |\n| **[sfclaude-desktop](sfclaude-desktop)** | Claude Desktop GUI configurator | macOS | SiliconFlow |\n| **[sfclaude-desktop.ps1](sfclaude-desktop.ps1)** | Claude Desktop GUI configurator | Windows | SiliconFlow |\n| **[skills/deepseek-vision](skills/deepseek-vision/)** | Vision skill (zero deps) | macOS / Linux | DashScope Qwen |\n| **[dsvision-mcp](dsvision-mcp)** | Vision MCP server | macOS / Linux | DashScope Qwen |\n\n---\n\n## How it works\n\n![xxclaude script-logic diagram](docs/xxclaude-logic.drawio.png)\n\nScript-logic overview: the installer, the `xclaude` auto-detect dispatcher, the provider CLI launchers, the Claude Desktop configurators, and the Codex bridge — all sharing `lib/common.sh`. The PNG has the draw.io XML embedded, so opening it in [draw.io](https://app.diagrams.net) recovers the editable diagram ([source](docs/xxclaude-logic.drawio) · [中文版](docs/xxclaude-logic-cn.drawio.png)).\n\n---\n\n## Quick start on macOS\n\n```bash\n# One-line install (recommended):\ncurl -fsSL https://raw.githubusercontent.com/Agents365-ai/dsclaude/main/install.sh | bash\n\n# Or user install (no sudo):\ncurl -fsSL https://raw.githubusercontent.com/Agents365-ai/dsclaude/main/install.sh | bash -s -- --user\n\n# Or manual:\ngit clone https://github.com/Agents365-ai/dsclaude.git\ncd dsclaude\nchmod +x xclaude\n./xclaude\n```\n\n## Quick start on Windows\n\n```powershell\n# One-line install (PowerShell as admin recommended):\nirm https://raw.githubusercontent.com/Agents365-ai/dsclaude/main/install.ps1 | iex\n\n# Install with auto-PATH:\nirm https://raw.githubusercontent.com/Agents365-ai/dsclaude/main/install.ps1 | iex -AddToPath\n\n# Then launch:\npwsh -File xclaude.ps1\n```\n\n---\n\n## xclaude — Unified auto-detect launcher\n\nDon't remember which script to run? `xclaude` auto-detects your API key and delegates to the right backend.\n\n```bash\n# Set any one of these in your ~/.zshrc:\nexport DEEPSEEK_API_KEY=sk-... # → dsclaude\nexport GLM_API_KEY=... # → glmclaude\nexport KIMI_API_KEY=sk-... # → kmclaude\nexport ARK_API_KEY=... # → arkclaude\n# ... or any other supported key\n\nxclaude # auto-detect and launch\nxclaude fast # ...with fast/flash tier\nxclaude long effort max # ...with 1M context + max effort\nxclaude kimi # forwarded: on Ark → kimi model, etc.\n```\n\nAll positional args (model aliases, `fast`, `long`, `effort`, etc.) are forwarded to the underlying launcher. If multiple keys are set, the first found wins; set `XCLAUDE_PREFER=dsclaude` to force a specific provider.\n\n---\n\n## dsclaude — Claude Code on DeepSeek\n\nFollows the [DeepSeek Anthropic API](https://api-docs.deepseek.com/guides/anthropic_api) guide.\n\n```bash\nexport DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxxxxxxx # add to ~/.zshrc\n\ndsclaude # default: deepseek-v4-pro (full reasoning)\ndsclaude fast # deepseek-v4-flash (cheaper / faster)\ndsclaude long # request 1M context window\ndsclaude long fast # 1M + flash\n```\n\nSets the DeepSeek-recommended env vars (`ANTHROPIC_BASE_URL`, model mappings, `CLAUDE_CODE_EFFORT_LEVEL=max`), and exposes the alternate model in Claude Code's `/model` picker. Override context window via `DSCLAUDE_MAX_TOKENS` and effort via `DSCLAUDE_EFFORT`.\n\n> Both models natively support 1M-token context. The `[1m]` suffix (e.g. `deepseek-v4-pro[1m]`) is required in Claude Code — `dsclaude` sets it automatically.\n>\n> Windows (PowerShell 7+): `pwsh -File ./dsclaude.ps1` (same flags).\n\n---\n\n## mmclaude — Claude Code on Xiaomi MiMo\n\n```bash\nexport MIMO_API_KEY=sk-xxxxxxxxxxxxxxxxxx # pay-as-you-go\n# or\nexport MIMO_API_KEY=tp-xxxxxxxxxxxxxxxxxx # Token Plan\n\nmmclaude # start on mimo-v2.5-pro\nmmclaude fast # start on mimo-v2.5 (cheaper / faster flash tier)\nmmclaude update # git pull\n```\n\nAuto-detects base URL from the key prefix (`sk-*` → public, `tp-*` → Token Plan); override with `MIMO_BASE_URL`. Main/opus/sonnet slots run `mimo-v2.5-pro` while the haiku and subagent tiers run `mimo-v2.5` (flash); `mmclaude fast` flips the main model to flash, and the other tier is exposed in the `/model` picker for mid-session switching. Unsets `ANTHROPIC_API_KEY` (per MiMo docs). Override the tiers with `MIMO_MODEL` / `MIMO_FLASH_MODEL`.\n\n> Windows (PowerShell 7+): `pwsh -File ./mmclaude.ps1` (same flags).\n\n---\n\n## qwclaude — Claude Code on Alibaba Cloud Bailian (Qwen)\n\n```bash\n# One key per plan — each comes from a different Bailian console entry:\nexport DASHSCOPE_API_KEY=sk-xxxxxxxxxxxxxxxxxx # pay-as-you-go\nexport DASHSCOPE_CP_API_KEY=sk-xxxxxxxxxxxxxxxxxx # Coding Plan\nexport DASHSCOPE_TP_API_KEY=sk-xxxxxxxxxxxxxxxxxx # Token Plan team edition\n\n# macOS / Linux — three model tiers\nqwclaude # pay-as-you-go, qwen3.7-max (Beijing) → DASHSCOPE_API_KEY\nqwclaude plus # qwen3.7-plus (balanced, ~1/6 cost of max)\nqwclaude max # explicit qwen3.7-max\nqwclaude fast # qwen3.6-flash as the main model\nqwclaude intl # pay-as-you-go on the Singapore endpoint\nqwclaude coding # Coding Plan (qwen3.7-plus recommended) → DASHSCOPE_CP_API_KEY\nqwclaude coding plus # Coding Plan, qwen3.7-plus (default)\nqwclaude coding fast # Coding Plan, qwen3.6-plus\nqwclaude token # Token Plan (qwen3.7-max) → DASHSCOPE_TP_API_KEY\nqwclaude token plus # Token Plan, qwen3.7-plus\nqwclaude update # git pull\n\n# Windows (PowerShell 7+)\npwsh -File ./qwclaude.ps1 coding\n```\n\nPicks the base URL, model lineup, and API-key variable per billing plan and model tier. Three model tiers:\n\n| Tier | Pay-as-you-go & Token Plan | Coding Plan |\n| ------ | --------------------------- | ------------- |\n| **max** (default) | `qwen3.7-max` (flagship) | N/A |\n| **plus** | `qwen3.7-plus` (balanced, ~1/6 cost) | `qwen3.7-plus` (recommended) |\n| **flash** (subagent/haiku) | `qwen3.6-flash` | `qwen3.6-plus` |\n\nMain/opus/sonnet slots run the selected tier (default `qwen3.7-max`) while the haiku + subagent tiers always use the flash model. `fast` flips the main model to flash; `plus` flips to qwen3.7-plus. The other tier is exposed in the `/model` picker for mid-session switching. Sets `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1` and unsets `ANTHROPIC_API_KEY` to keep traffic on Bailian. Override via `QWEN_PLAN` / `QWEN_REGION` / `QWEN_MODEL` / `QWEN_PLUS_MODEL` / `QWEN_FLASH_MODEL` / `QWEN_BASE_URL`.\n\n> The Windows port (`qwclaude.ps1`) requires PowerShell 7+ (`winget install Microsoft.PowerShell`) — run it with `pwsh -File`.\n\n---\n\n## glmclaude — Claude Code on ZhipuAI GLM\n\nFollows ZhipuAI's Anthropic-compatible API.\n\n```bash\nexport GLM_API_KEY=your_zhipu_api_key # add to ~/.zshrc\n# Get your key at: https://open.bigmodel.cn/usercenter/apikeys\n\nglmclaude # default: glm-5.2 (full reasoning)\nglmclaude fast # glm-4.7 (cheaper / faster)\nglmclaude update # git pull\n```\n\nSets the ZhipuAI-recommended env vars (`ANTHROPIC_BASE_URL`, model mappings), and exposes the alternate model in Claude Code's `/model` picker. Main/opus/sonnet slots run `glm-5.2` while the haiku and subagent tiers run `glm-4.7`; `glmclaude fast` flips the main model to flash, and the other tier is exposed in the `/model` picker for mid-session switching.\n\nBy default uses the China endpoint (`https://open.bigmodel.cn/api/anthropic`). For the international endpoint, set `GLM_BASE_URL`:\n\n```bash\nexport GLM_BASE_URL=https://api.z.ai/api/anthropic\nglmclaude\n```\n\nOverride the tiers with `GLM_MODEL` / `GLM_FLASH_MODEL`.\n\n> Windows (PowerShell 7+): `pwsh -File ./glmclaude.ps1` (same flags).\n\n---\n\n## kmclaude — Claude Code on Moonshot AI Kimi\n\n```bash\nexport KIMI_API_KEY=sk-xxxxxxxxxxxxxxxxxx # add to ~/.zshrc\n# Get your key at: https://platform.moonshot.cn/console/api-keys\n\nkmclaude # start on kimi-k3 (flagship)\nkmclaude fast # start on kimi-k2.5 (cheaper / faster tier)\nkmclaude update # git pull\n```\n\nUses the official Kimi Anthropic-compatible endpoint (`https://api.moonshot.cn/anthropic`). Main/opus/sonnet slots run `kimi-k3` while the haiku and subagent tiers run `kimi-k2.5`; `kmclaude fast` flips the main model to k2.5, and the other tier is exposed in the `/model` picker for mid-session switching. Unsets `ANTHROPIC_API_KEY` to avoid credential shadowing. Override the tiers with `KIMI_MODEL` / `KIMI_FLASH_MODEL` and the base URL with `KIMI_BASE_URL`.\n\n> Windows (PowerShell 7+): `pwsh -File ./kmclaude.ps1` (same flags).\n\n---\n\n## dsclaude-desktop — Claude Desktop GUI configurator\n\nOne-command configurator for Claude Desktop's built-in **Third-Party Inference** feature (Developer menu), pre-filled for DeepSeek.\n\n### Prerequisites\n\n1. Claude Desktop installed ([claude.ai/download](https://claude.ai/download))\n2. Developer Mode enabled (Help → Troubleshooting → Enable Developer Mode, once)\n3. `DEEPSEEK_API_KEY` environment variable set\n\n### Usage\n\n```bash\nexport DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxxxxxxx\n./dsclaude-desktop # configure and restart\n./dsclaude-desktop -h # help\n```\n\nGenerates an entry under `~/Library/Application Support/Claude-3p/configLibrary/`, sets it as `appliedId` in `_meta.json`, then restarts the app. Existing GUI-added entries are preserved.\n\n### Switching modes\n\nClaude Desktop's launch chooser handles Anthropic ↔ Gateway switching natively — no `--revert` flag. Click your profile → **Disconnect** (or sign out), then pick the other option at next launch.\n\n> Classic **Chat** (claude.ai-style) is unavailable in Gateway mode — it depends on Anthropic-hosted features not exposed via the inference API. Switch back to Anthropic mode to use it.\n\n### Windows\n\n```powershell\n$env:DEEPSEEK_API_KEY = \"sk-xxxxxxxxxxxxxxxxxx\"\npwsh ./dsclaude-desktop.ps1\n```\n\nWrites to `%APPDATA%\\Claude-3p\\configLibrary\\`. > Untested by the maintainer — please [open an issue](https://github.com/Agents365-ai/dsclaude/issues) if anything misbehaves.\n\n---\nPrerequisites: Claude Desktop installed (Store or standard), DeepSeek API key. Unlike macOS, Developer Mode is **auto-enabled** by the script — no manual GUI toggle needed.\n\nConfig path: `%LOCALAPPDATA%\\Claude-3p\\configLibrary\\` (for Store/MSIX installs, the script also writes to the sandboxed package path as a fallback).\n\nTested on Windows 11 with Claude Desktop 1.7196 (Windows Store, arm64).\n\n---\n\n## mmclaude-desktop — Claude Desktop on Xiaomi MiMo\n\nSame configurator as `dsclaude-desktop`, pre-filled for Xiaomi MiMo. Reads `MIMO_API_KEY` and auto-detects the base URL from the key prefix (`tp-*` → Token Plan, else pay-as-you-go; override with `MIMO_BASE_URL`). Configures `mimo-v2.5-pro` + `mimo-v2.5`.\n\n```bash\nexport MIMO_API_KEY=sk-xxxxxxxxxxxxxxxxxx # or tp-... for Token Plan\n./mmclaude-desktop # configure and restart (macOS)\n./mmclaude-desktop -h # help\n\n# Windows (PowerShell)\n$env:MIMO_API_KEY = \"sk-xxxxxxxxxxxxxxxxxx\"\npwsh ./mmclaude-desktop.ps1\n```\n\n---\n\n## qwclaude-desktop — Claude Desktop on Alibaba Cloud Bailian (Qwen)\n\nSame configurator, with per-plan base URL, models, and key variable. Pay-as-you-go (`DASHSCOPE_API_KEY`) and Token Plan (`DASHSCOPE_TP_API_KEY`) default to `qwen3.7-max` + `qwen3.6-flash`; Coding Plan (`DASHSCOPE_CP_API_KEY`) configures `qwen3.7-plus` + `qwen3.6-plus`. Add `plus` to use qwen3.7-plus for any plan.\n\n```bash\nexport DASHSCOPE_API_KEY=sk-xxxxxxxxxxxxxxxxxx # pay-as-you-go\nexport DASHSCOPE_CP_API_KEY=sk-xxxxxxxxxxxxxxxxxx # Coding Plan\nexport DASHSCOPE_TP_API_KEY=sk-xxxxxxxxxxxxxxxxxx # Token Plan\n\n./qwclaude-desktop # pay-as-you-go (Beijing), qwen3.7-max, then restart\n./qwclaude-desktop plus # pay-as-you-go, qwen3.7-plus\n./qwclaude-desktop intl # pay-as-you-go, Singapore endpoint\n./qwclaude-desktop coding # Coding Plan (qwen3.7-plus)\n./qwclaude-desktop token # Token Plan, qwen3.7-max\n./qwclaude-desktop token plus # Token Plan, qwen3.7-plus\n\n# Windows (PowerShell)\npwsh ./qwclaude-desktop.ps1 -Plan coding\npwsh ./qwclaude-desktop.ps1 -Plan token -ModelTier plus\n```\n\n> The `.ps1` Windows ports mirror `dsclaude-desktop.ps1` and are **untested by the maintainer** — please [open an issue](https://github.com/Agents365-ai/dsclaude/issues) if anything misbehaves. Both configurators set `unstableDisableModelVerification` so Claude Desktop accepts the non-Anthropic model names, and (like `dsclaude-desktop`) disable Chat mode while the gateway is active.\n\n---\n\n## glmclaude-desktop — Claude Desktop on ZhipuAI GLM\n\nSame configurator, pre-filled for ZhipuAI GLM. Reads `GLM_API_KEY`. Configures `glm-5.2` + `glm-4.7`.\n\n```bash\nexport GLM_API_KEY=your_zhipu_api_key\n./glmclaude-desktop # configure and restart (macOS)\n./glmclaude-desktop -h # help\n\n# Windows (PowerShell)\n$env:GLM_API_KEY = \"your_zhipu_api_key\"\npwsh ./glmclaude-desktop.ps1\n```\n\nOverride the base URL with `GLM_BASE_URL` (default: `https://open.bigmodel.cn/api/anthropic`).\n\n---\n\n## kmclaude-desktop — Claude Desktop on Moonshot AI Kimi\n\nSame configurator, pre-filled for Moonshot Kimi. Reads `KIMI_API_KEY`. Configures `kimi-k3` + `kimi-k2.5`.\n\n```bash\nexport KIMI_API_KEY=sk-xxxxxxxxxxxxxxxxxx\n./kmclaude-desktop # configure and restart (macOS)\n./kmclaude-desktop -h # help\n\n# Windows (PowerShell)\n$env:KIMI_API_KEY = \"sk-xxxxxxxxxxxxxxxxxx\"\npwsh ./kmclaude-desktop.ps1\n```\n\nOverride the base URL with `KIMI_BASE_URL` (default: `https://api.moonshot.cn/anthropic`).\n\n---\n\n## arkclaude — Claude Code on Volcengine Ark (Coding Plan)\n\nVolcengine Ark's Coding Plan aggregates multiple model families under one subscription — doubao, Kimi, DeepSeek, GLM, MiniMax, and more. One API key, one endpoint, many models.\n\n```bash\nexport ARK_API_KEY=your_ark_api_key # add to ~/.zshrc\n# Get your key at: https://console.volcengine.com/ark\n\n# Three doubao tiers + provider aliases for quick model switching\narkclaude # doubao-seed-2.0-code (code specialist, default)\narkclaude plus # doubao-seed-2.0-pro (balanced flagship)\narkclaude fast # doubao-seed-2.0-lite (cheap / fast)\narkclaude kimi # kimi-k2.7-code (Kimi code model)\narkclaude kimi-pro # kimi-k2.6\narkclaude deepseek # deepseek-v4-pro\narkclaude deepseek-flash # deepseek-v4-flash\narkclaude glm # glm-5.2\narkclaude minimax # minimax-m2.7\narkclaude update # git pull\n```\n\nUses the Ark Coding Plan endpoint (`https://ark.cn-beijing.volces.com/api/coding`). Main/opus/sonnet slots run the chosen model while the haiku + subagent tiers always use the cheapest model in the same family (or `doubao-seed-2.0-lite` as fallback). The /model picker exposes a smart alternate based on your selection — Pro ↔ Code when using doubao, K2.6 ↔ K2.7-code when using Kimi, etc. Sets `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1` and unsets `ANTHROPIC_API_KEY` to keep traffic on Ark. Override via `ARK_MODEL` / `ARK_PLUS_MODEL` / `ARK_FLASH_MODEL` / `ARK_BASE_URL`.\n\n> Windows (PowerShell 7+): `pwsh -File ./arkclaude.ps1` (same flags).\n\n---\n\n## arkclaude-desktop — Claude Desktop on Volcengine Ark\n\nSame configurator, pre-filled for Ark Coding Plan. Reads `ARK_API_KEY`. Supports all model aliases for picking the inference model.\n\n```bash\nexport ARK_API_KEY=your_ark_api_key\n./arkclaude-desktop # configure with doubao-seed-2.0-code and restart\n./arkclaude-desktop plus # doubao-seed-2.0-pro\n./arkclaude-desktop kimi # kimi-k2.7-code\n./arkclaude-desktop deepseek # deepseek-v4-pro\n./arkclaude-desktop glm # glm-5.2\n./arkclaude-desktop minimax # minimax-m2.7\n./arkclaude-desktop -h # help\n\n# Windows (PowerShell)\n$env:ARK_API_KEY = \"your_ark_api_key\"\npwsh ./arkclaude-desktop.ps1 -ModelTier kimi\n```\n\nOverride the base URL with `ARK_BASE_URL` (default: `https://ark.cn-beijing.volces.com/api/coding`).\n\n---\n\n## lcclaude — Claude Code on Meituan LongCat\n\nLongCat-2.0 is a 1.6T-param MoE model built entirely on Chinese-manufactured compute. It ranked #2 globally in Claude Code monthly call volume on OpenRouter. **Free during public beta** — 500K tokens/day.\n\n```bash\nexport LONGCAT_API_KEY=lc-xxxxxxxxxxxxxxxxxx # add to ~/.zshrc\n# Get your free key at: https://longcat.chat/platform\n\nlcclaude # LongCat-2.0 (1M context, flagship)\nlcclaude fast # LongCat-Flash-Chat (cheaper / faster)\nlcclaude think # LongCat-Flash-Thinking (deep reasoning)\nlcclaude update # git pull\n```\n\nUses the LongCat Anthropic-compatible endpoint (`https://api.longcat.chat/anthropic`). Main/opus/sonnet slots run the chosen model while the haiku + subagent tiers use `LongCat-Flash-Chat`. The `/model` picker exposes the alternate tier. Override via `LONGCAT_MODEL` / `LONGCAT_FLASH_MODEL` / `LONGCAT_THINK_MODEL` / `LONGCAT_BASE_URL`.\n\n> Windows (PowerShell 7+): `pwsh -File ./lcclaude.ps1` (same flags).\n\n---\n\n## lcclaude-desktop — Claude Desktop on Meituan LongCat\n\nSame configurator, pre-filled for LongCat. Reads `LONGCAT_API_KEY`. Configures `LongCat-2.0` + `LongCat-Flash-Chat`.\n\n```bash\nexport LONGCAT_API_KEY=lc-xxxxxxxxxxxxxxxxxx\n./lcclaude-desktop # configure and restart (macOS)\n./lcclaude-desktop -h # help\n\n# Windows (PowerShell)\n$env:LONGCAT_API_KEY = \"lc-xxxxxxxxxxxxxxxxxx\"\npwsh ./lcclaude-desktop.ps1\n```\n\nOverride the base URL with `LONGCAT_BASE_URL` (default: `https://api.longcat.chat/anthropic`).\n\n---\n\n## mxclaude — Claude Code on MiniMax\n\nMiniMax-M3 is a 1M-context flagship model optimized for agentic reasoning, tool use, and coding. **Requires a Coding Plan (Token Plan) API key** — not pay-as-you-go.\n\n```bash\nexport MINIMAX_API_KEY=your_minimax_api_key # add to ~/.zshrc\n# Get your key at: https://platform.minimaxi.com\n\nmxclaude # MiniMax-M3 (1M context, flagship)\nmxclaude fast # MiniMax-M2.5 (cheaper / faster)\nmxclaude long # request 1M context window\nmxclaude effort max # set reasoning effort (low|medium|high|xhigh|max)\nmxclaude update # git pull\n```\n\nUses the MiniMax Anthropic-compatible endpoint (default: `https://api.minimaxi.com/anthropic` for China; override with `MINIMAX_BASE_URL` for international `https://api.minimax.io/anthropic`). Main/opus/sonnet slots run the chosen model while the haiku + subagent tiers use `MiniMax-M2.5`. The `/model` picker exposes the alternate tier. Override via `MINIMAX_MODEL` / `MINIMAX_FLASH_MODEL` / `MINIMAX_BASE_URL` / `MINIMAX_CTX` / `MINIMAX_OUTPUT` / `MINIMAX_EFFORT`.\n\n> Windows (PowerShell 7+): `pwsh -File ./mxclaude.ps1` (same flags).\n\n---\n\n## mxclaude-desktop — Claude Desktop on MiniMax\n\nSame configurator, pre-filled for MiniMax. Reads `MINIMAX_API_KEY`. Configures `MiniMax-M3` + `MiniMax-M2.5`.\n\n```bash\nexport MINIMAX_API_KEY=your_minimax_api_key\n./mxclaude-desktop # configure and restart (macOS)\n./mxclaude-desktop -h # help\n\n# Windows (PowerShell)\n$env:MINIMAX_API_KEY = \"your_minimax_api_key\"\npwsh ./mxclaude-desktop.ps1\n```\n\nOverride the base URL with `MINIMAX_BASE_URL` (default: `https://api.minimaxi.com/anthropic`; international: `https://api.minimax.io/anthropic`).\n\n---\n\n## hyclaude — Claude Code on Tencent TokenHub\n\nTencent TokenHub is a multi-model aggregator — one subscription gives access to Hunyuan (HY3), DeepSeek, GLM, Kimi, MiniMax, Qwen, and more.\n\n```bash\nexport HY_API_KEY=your_api_key # add to ~/.zshrc\n# Get your key at: https://cloud.tencent.com/product/lkeap\n\nhyclaude # hy3-preview (Tencent default)\nhyclaude fast # hy-mt2-lite (cheap / fast)\nhyclaude deepseek # deepseek-v4-pro\nhyclaude kimi # kimi-k2.7-code\nhyclaude glm # glm-5.2\nhyclaude minimax # minimax-m3\nhyclaude qwen # qwen3.5-plus\nhyclaude long # request max context window\nhyclaude effort max # set reasoning effort (low|medium|high|xhigh|max)\nhyclaude update # git pull\n```\n\nUses the TokenHub Anthropic-compatible endpoint (default: `https://api.lkeap.cloud.tencent.com/plan/anthropic`). Main/opus/sonnet slots run the chosen model while haiku + subagent tiers use `hy-mt2-lite` (or a same-family flash model for non-HY selections). The `/model` picker exposes a smart alternate. Override via `HY_MODEL` / `HY_FLASH_MODEL` / `HY_BASE_URL` / `HY_CTX` / `HY_OUTPUT` / `HY_EFFORT`.\n\n> Windows (PowerShell 7+): `pwsh -File ./hyclaude.ps1` (same flags).\n\n---\n\n## hyclaude-desktop — Claude Desktop on Tencent TokenHub\n\nSame configurator, pre-filled for TokenHub. Reads `HY_API_KEY`. Supports model aliases for the backend model.\n\n```bash\nexport HY_API_KEY=your_api_key\n./hyclaude-desktop # configure with hy3-preview and restart\n./hyclaude-desktop kimi # kimi-k2.7-code\n./hyclaude-desktop deepseek # deepseek-v4-pro\n./hyclaude-desktop glm # glm-5.2\n./hyclaude-desktop minimax # minimax-m3\n./hyclaude-desktop qwen # qwen3.5-plus\n./hyclaude-desktop -h # help\n\n# Windows (PowerShell)\n$env:HY_API_KEY = \"your_api_key\"\npwsh ./hyclaude-desktop.ps1 -ModelTier kimi\n```\n\nOverride the base URL with `HY_BASE_URL` (default: `https://api.lkeap.cloud.tencent.com/plan/anthropic`).\n\n---\n\n## sfclaude — Claude Code on SiliconFlow\n\nSiliconFlow (硅基流动) is a multi-model platform aggregating DeepSeek, Kimi, GLM, MiniMax, Qwen, Yi, and more. Models use the `provider/Model-Name` convention (e.g. `deepseek-ai/DeepSeek-V4-PRO`).\n\n```bash\nexport SF_API_KEY=sk-xxxxxxxxxxxxxxxxxx # add to ~/.zshrc\n# Get your key at: https://cloud.siliconflow.cn/account/ak\n\nsfclaude # deepseek-ai/DeepSeek-V4-PRO (default)\nsfclaude fast # deepseek-ai/DeepSeek-V3 (cheaper)\nsfclaude kimi # moonshotai/Kimi-K2-Instruct-0905\nsfclaude glm # Pro/zai-org/GLM-5\nsfclaude minimax # Pro/MiniMaxAI/MiniMax-M2.5\nsfclaude qwen # Qwen/Qwen2.5-Coder\nsfclaude yi # 01-ai/Yi-1.5\nsfclaude r1 # deepseek-ai/DeepSeek-R1 (deep reasoning)\nsfclaude long # request max context window\nsfclaude effort max # set reasoning effort (low|medium|high|xhigh|max)\nsfclaude update # git pull\n```\n\nUses the SiliconFlow Anthropic-compatible endpoint (`https://api.siliconflow.cn/`). Main/opus/sonnet slots run the chosen model while haiku + subagent tiers use `deepseek-ai/DeepSeek-V3`. Override via `SF_MODEL` / `SF_FLASH_MODEL` / `SF_BASE_URL` / `SF_CTX` / `SF_OUTPUT` / `SF_EFFORT`.\n\n> Windows (PowerShell 7+): `pwsh -File ./sfclaude.ps1` (same flags).\n\n---\n\n## sfclaude-desktop — Claude Desktop on SiliconFlow\n\nSame configurator, pre-filled for SiliconFlow. Reads `SF_API_KEY`. Supports model aliases.\n\n```bash\nexport SF_API_KEY=sk-xxxxxxxxxxxxxxxxxx\n./sfclaude-desktop # deepseek-ai/DeepSeek-V4-PRO and restart\n./sfclaude-desktop kimi # moonshotai/Kimi-K2-Instruct-0905\n./sfclaude-desktop r1 # deepseek-ai/DeepSeek-R1\n./sfclaude-desktop -h # help\n\n# Windows (PowerShell)\n$env:SF_API_KEY = \"sk-xxxxxxxxxxxxxxxxxx\"\npwsh ./sfclaude-desktop.ps1 -ModelTier kimi\n```\n\n---\n\n## deepseek-vision skill — Vision (zero-dependency)\n\nGives text-only agents (like DeepSeek) the ability to \"see\" images. When the agent encounters an image, it calls `analyze-image`, which sends it to Qwen3.6-Flash and returns a text description.\n\n```bash\nexport DASHSCOPE_API_KEY=sk-xxxxxxxxxxxxxxxxxx\n./skills/deepseek-vision/analyze-image /path/to/screenshot.png \"What error is shown?\"\n./skills/deepseek-vision/analyze-image https://example.com/diagram.png\n```\n\nWorks with any agent that loads `SKILL.md` (Claude Code, Cowork, etc.). Default model `qwen3.6-flash`; override via `DSVISION_MODEL` and `DSVISION_BASE_URL`.\n\n> **Limitation**: requires a file path or URL — inline images (drag-drop, paste, \"+ → Add files or photos\") aren't supported. Use **dsvision-mcp** below for that.\n\n---\n\n## dsvision-mcp — Vision (MCP server)\n\nSame functionality as the skill above, but runs as an MCP server — bypassing two Cowork sandbox limitations:\n\n1. **Network egress** — the skill's DashScope API calls are firewalled inside Cowork's VM; the MCP server runs outside it\n2. **Inline images** — auto-picks the latest cached image from `~/.claude/image-cache/`, so drag-drop/paste/\"+\" workflows work (macOS only; Windows Cowork doesn't cache inline images to disk)\n\n### Setup\n\n```bash\npip3 install fastmcp requests\nexport DASHSCOPE_API_KEY=sk-xxxxxxxxxxxxxxxxxx # add to ~/.zshrc\ncd /path/to/dsclaude && pwd # note the absolute path\n```\n\nAdd to the MCP config file matching your mode:\n\n| Mode | Config file |\n|------|-------------|\n| 3P/Gateway (DeepSeek via `dsclaude-desktop`) | `~/Library/Application Support/Claude-3p/claude_desktop_config.json` |\n| Standard Anthropic | `~/Library/Application Support/Claude/claude_desktop_config.json` |\n\n```json\n{\n \"mcpServers\": {\n \"dsvision\": {\n \"command\": \"/absolute/path/dsclaude/dsvision-mcp\"\n }\n }\n}\n```\n\nRestart Claude Desktop. The `analyze_image` tool appears automatically.\n\n### Usage\n\n```\nanalyze_image() # auto: latest cached image\nanalyze_image(image_path=\"/abs/path/foo.png\")\nanalyze_image(focus=\"What error is shown?\")\n```\n\n### Troubleshooting\n\n| Symptom | Check |\n| --------- | ------- |\n| Tool doesn't appear | Wrong config file path / invalid JSON (validate with `python3 -m json.tool`) |\n| Tool errors | `DASHSCOPE_API_KEY` not set |\n| `ModuleNotFoundError` | Use `pip3` not `pip` |\n| Image not found | Pass absolute path, or check `~/.claude/image-cache/` exists |\n\n### Skill vs MCP: which to use\n\n| Scenario | Use |\n| ---------- | ----- |\n| Claude Code (CLI), explicit paths | `skills/deepseek-vision` (zero deps) |\n| Cowork / Desktop with inline images | `dsvision-mcp` (only option that works) |\n| Cowork with explicit paths, sandbox tweaks OK | either |\n\n## Support\n\nIf these scripts save you time, consider supporting the author:\n\n\n \n \n \n \n \n \n
\"WeChat
WeChat Pay
\"Alipay\"
Alipay
\"Buy
Buy Me a Coffee
\"Give
Give a Reward
\n\n## Author\n\n**Agents365-ai** · [Bilibili](https://space.bilibili.com/441831884) · [GitHub](https://github.com/Agents365-ai)\n\n## License\n\n[CC BY-NC 4.0](LICENSE.md) — free for non-commercial use. **Commercial use requires permission.**\n"}}, "docs/index.md": {"c07db31916dca8077b9124f5c098258f9607b016": {"t": 1785595192.1269927, "n": 8585, "h": "3630317bb4818a02", "c": "---\ntitle: dsclaude\ndescription: Claude Code & Claude Desktop launchers for alternative backends\n---\n\n**English** · [中文](zh.html) · [GitHub](https://github.com/Agents365-ai/dsclaude)\n\nA collection of launchers and configurators that point [Claude Code](https://claude.ai/code) and Claude Desktop at third-party model backends (DeepSeek, Xiaomi MiMo, etc.).\n\n**Author:** [Agents365-ai](https://github.com/Agents365-ai) · [Bilibili](https://space.bilibili.com/441831884)\n\n---\n\n## Tools\n\n| Tool | What it does | Platform | Backend |\n|------|-------------|----------|---------|\n| **[dsclaude](https://github.com/Agents365-ai/dsclaude/blob/main/dsclaude)** | Claude Code CLI launcher | macOS / Linux | DeepSeek |\n| **[mmclaude](https://github.com/Agents365-ai/dsclaude/blob/main/mmclaude)** | Claude Code CLI launcher | macOS / Linux | Xiaomi MiMo |\n| **[dsclaude-desktop](https://github.com/Agents365-ai/dsclaude/blob/main/dsclaude-desktop)** | Claude Desktop GUI configurator | macOS | DeepSeek |\n| **[dsclaude-desktop.ps1](https://github.com/Agents365-ai/dsclaude/blob/main/dsclaude-desktop.ps1)** | Claude Desktop GUI configurator | Windows | DeepSeek |\n| **[skills/deepseek-vision](https://github.com/Agents365-ai/dsclaude/tree/main/skills/deepseek-vision)** | Vision skill (zero deps) | macOS / Linux | DashScope Qwen |\n| **[dsvision-mcp](https://github.com/Agents365-ai/dsclaude/blob/main/dsvision-mcp)** | Vision MCP server | macOS / Linux | DashScope Qwen |\n\n---\n\n## Quick start on macOS\n\n```bash\ngit clone https://github.com/Agents365-ai/dsclaude.git\ncd dsclaude\nchmod +x dsclaude\n./dsclaude\n```\n\n---\n\n## dsclaude — Claude Code on DeepSeek\n\nFollows the [DeepSeek Anthropic API](https://api-docs.deepseek.com/guides/anthropic_api) guide.\n\n```bash\nexport DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxxxxxxx # add to ~/.zshrc\n\ndsclaude # default: deepseek-v4-pro (full reasoning)\ndsclaude fast # deepseek-v4-flash (cheaper / faster)\ndsclaude long # request 1M context window\ndsclaude long fast # 1M + flash\n```\n\nSets the DeepSeek-recommended env vars (`ANTHROPIC_BASE_URL`, model mappings, `CLAUDE_CODE_EFFORT_LEVEL=max`), and exposes the alternate model in Claude Code's `/model` picker. Override context window via `DSCLAUDE_MAX_TOKENS` and effort via `DSCLAUDE_EFFORT`.\n\n> Both models natively support 1M-token context. The `[1m]` suffix (e.g. `deepseek-v4-pro[1m]`) is required in Claude Code — `dsclaude` sets it automatically.\n\n---\n\n## mmclaude — Claude Code on Xiaomi MiMo\n\n```bash\nexport MIMO_API_KEY=sk-xxxxxxxxxxxxxxxxxx # pay-as-you-go\n# or\nexport MIMO_API_KEY=tp-xxxxxxxxxxxxxxxxxx # Token Plan\n\nmmclaude # start on mimo-v2.5-pro\nmmclaude update # git pull\n```\n\nAuto-detects base URL from the key prefix (`sk-*` → public, `tp-*` → Token Plan); override with `MIMO_BASE_URL`. Sets all four model slots to `mimo-v2.5-pro` and unsets `ANTHROPIC_API_KEY` (per MiMo docs).\n\n---\n\n## dsclaude-desktop — Claude Desktop GUI configurator\n\nOne-command configurator for Claude Desktop's built-in **Third-Party Inference** feature (Developer menu), pre-filled for DeepSeek.\n\n### Prerequisites\n\n1. Claude Desktop installed ([claude.ai/download](https://claude.ai/download))\n2. Developer Mode enabled (Help → Troubleshooting → Enable Developer Mode, once)\n3. `DEEPSEEK_API_KEY` environment variable set\n\n### Usage (macOS)\n\n```bash\nexport DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxxxxxxx\n./dsclaude-desktop # configure and restart\n./dsclaude-desktop -h # help\n```\n\nGenerates an entry under `~/Library/Application Support/Claude-3p/configLibrary/`, sets it as `appliedId` in `_meta.json`, then restarts the app. Existing GUI-added entries are preserved.\n\n### Switching modes\n\nClaude Desktop's launch chooser handles Anthropic ↔ Gateway switching natively — no `--revert` flag. Click your profile → **Disconnect** (or sign out), then pick the other option at next launch.\n\n> Classic **Chat** (claude.ai-style) is unavailable in Gateway mode — it depends on Anthropic-hosted features not exposed via the inference API. Switch back to Anthropic mode to use it.\n\n### Usage (Windows)\n\n```powershell\n$env:DEEPSEEK_API_KEY = \"sk-xxxxxxxxxxxxxxxxxx\"\npwsh ./dsclaude-desktop.ps1\n```\n\nUnlike macOS, Developer Mode is **auto-enabled** by the script — no manual GUI toggle needed.\n\nConfig path: `%LOCALAPPDATA%\\Claude-3p\\configLibrary\\` (for Store/MSIX installs, the script also writes to the sandboxed package path as a fallback).\n\nTested on Windows 11 with Claude Desktop 1.7196 (Windows Store, arm64).\n\n---\n\n## deepseek-vision skill — Vision (zero-dependency)\n\nGives text-only agents (like DeepSeek) the ability to \"see\" images. When the agent encounters an image, it calls `analyze-image`, which sends it to Qwen3.6-Flash and returns a text description.\n\n```bash\nexport DASHSCOPE_API_KEY=sk-xxxxxxxxxxxxxxxxxx\n./skills/deepseek-vision/analyze-image /path/to/screenshot.png \"What error is shown?\"\n./skills/deepseek-vision/analyze-image https://example.com/diagram.png\n```\n\nWorks with any agent that loads `SKILL.md` (Claude Code, Cowork, etc.). Default model `qwen3.6-flash`; override via `DSVISION_MODEL` and `DSVISION_BASE_URL`.\n\n> **Limitation**: requires a file path or URL — inline images (drag-drop, paste, \"+ → Add files or photos\") aren't supported. Use **dsvision-mcp** below for that.\n\n---\n\n## dsvision-mcp — Vision (MCP server)\n\nSame functionality as the skill above, but runs as an MCP server — bypassing two Cowork sandbox limitations:\n\n1. **Network egress** — the skill's DashScope API calls are firewalled inside Cowork's VM; the MCP server runs outside it\n2. **Inline images** — auto-picks the latest cached image from `~/.claude/image-cache/`, so drag-drop/paste/\"+\" workflows work (macOS only; Windows Cowork doesn't cache inline images to disk)\n\n### Setup\n\n```bash\npip3 install fastmcp requests\nexport DASHSCOPE_API_KEY=sk-xxxxxxxxxxxxxxxxxx # add to ~/.zshrc\ncd /path/to/dsclaude && pwd # note the absolute path\n```\n\nAdd to the MCP config file matching your mode:\n\n| Mode | Config file |\n|------|-------------|\n| 3P/Gateway (DeepSeek via `dsclaude-desktop`) | `~/Library/Application Support/Claude-3p/claude_desktop_config.json` |\n| Standard Anthropic | `~/Library/Application Support/Claude/claude_desktop_config.json` |\n\n```json\n{\n \"mcpServers\": {\n \"dsvision\": {\n \"command\": \"/absolute/path/dsclaude/dsvision-mcp\"\n }\n }\n}\n```\n\nRestart Claude Desktop. The `analyze_image` tool appears automatically.\n\n### Usage\n\n```\nanalyze_image() # auto: latest cached image\nanalyze_image(image_path=\"/abs/path/foo.png\")\nanalyze_image(focus=\"What error is shown?\")\n```\n\n### Troubleshooting\n\n| Symptom | Check |\n|---------|-------|\n| Tool doesn't appear | Wrong config file path / invalid JSON (validate with `python3 -m json.tool`) |\n| Tool errors | `DASHSCOPE_API_KEY` not set |\n| `ModuleNotFoundError` | Use `pip3` not `pip` |\n| Image not found | Pass absolute path, or check `~/.claude/image-cache/` exists |\n\n### Skill vs MCP: which to use\n\n| Scenario | Use |\n|----------|-----|\n| Claude Code (CLI), explicit paths | `skills/deepseek-vision` (zero deps) |\n| Cowork / Desktop with inline images | `dsvision-mcp` (only option that works) |\n| Cowork with explicit paths, sandbox tweaks OK | either |\n\n---\n\n## Community\n\n- **Discord:** \n- **WeChat:** scan the QR code below\n\n

\n \"WeChat\n

\n\n## Support\n\nIf these scripts save you time, consider supporting the author:\n\n\n \n \n \n \n \n \n
\"WeChat
WeChat Pay
\"Alipay\"
Alipay
\"Buy
Buy Me a Coffee
\"Give
Give a Reward
\n\n## License\n\n[CC BY-NC 4.0](https://github.com/Agents365-ai/dsclaude/blob/main/LICENSE.md) — free for non-commercial use. **Commercial use requires permission.**\n"}}, "README_CN.md": {"c07db31916dca8077b9124f5c098258f9607b016": {"t": 1785595193.9504657, "n": 27072, "h": "a2f5a878f9afe2ad", "c": "# dsclaude — 面向非 Anthropic 后端的启动器工具集\n\n[English](README.md)\n\n让 [Claude Code](https://claude.ai/code) 和 Claude Desktop 接入 DeepSeek、小米 MiMo、阿里云百炼 Qwen、智谱 GLM、月之暗面 Kimi、火山方舟 Ark、美团 LongCat、MiniMax、腾讯 TokenHub、硅基流动 SiliconFlow 等第三方模型后端的小工具集。\n\n---\n\n## 工具一览\n\n| 脚本 | Agent | 平台 | 后端 | 模型 |\n| ------ | ------- | ------ | ------ | ------ |\n| **[dsclaude](dsclaude)** | Claude Code (CLI) | macOS / Linux | DeepSeek API(Anthropic 兼容端点) | `deepseek-v4-pro[1m]`(默认,统一推理)· `deepseek-v4-flash[1m]`(快速 / haiku 档位) |\n| **[dsclaude.ps1](dsclaude.ps1)** | Claude Code (CLI) | Windows(PowerShell 7+) | DeepSeek API(Anthropic 兼容端点) | 同上 |\n| **[mmclaude](mmclaude)** | Claude Code (CLI) | macOS / Linux | 小米 MiMo(Anthropic 兼容端点) | `mimo-v2.5-pro`(默认)· `mimo-v2.5`(快速 / haiku 档位) |\n| **[mmclaude.ps1](mmclaude.ps1)** | Claude Code (CLI) | Windows(PowerShell 7+) | 小米 MiMo(Anthropic 兼容端点) | 同上 |\n| **[qwclaude](qwclaude)** | Claude Code (CLI) | macOS / Linux | 阿里云百炼 Qwen(Anthropic 兼容端点) | `qwen3.7-max`(默认)· `qwen3.6-flash`(快速 / haiku 档位)· `qwen3.6-plus`(Coding Plan) |\n| **[qwclaude.ps1](qwclaude.ps1)** | Claude Code (CLI) | Windows(PowerShell 7+) | 阿里云百炼 Qwen(Anthropic 兼容端点) | 同上 |\n| **[glmclaude](glmclaude)** | Claude Code (CLI) | macOS / Linux | 智谱 AI GLM(Anthropic 兼容端点) | `glm-5.2`(默认)· `glm-4.7`(快速 / haiku 档位) |\n| **[glmclaude.ps1](glmclaude.ps1)** | Claude Code (CLI) | Windows(PowerShell 7+) | 智谱 AI GLM(Anthropic 兼容端点) | 同上 |\n| **[kmclaude](kmclaude)** | Claude Code (CLI) | macOS / Linux | 月之暗面 Kimi(Anthropic 兼容端点) | `kimi-k3`(默认)· `kimi-k2.5`(快速 / haiku 档位) |\n| **[kmclaude.ps1](kmclaude.ps1)** | Claude Code (CLI) | Windows(PowerShell 7+) | 月之暗面 Kimi(Anthropic 兼容端点) | 同上 |\n| **[arkclaude](arkclaude)** | Claude Code (CLI) | macOS / Linux | 火山方舟 Ark(Anthropic 兼容端点) | `doubao-seed-2.0-code`(默认)· `doubao-seed-2.0-pro`(平衡)· `doubao-seed-2.0-lite`(快速) + Kimi/DeepSeek/GLM/MiniMax 别名 |\n| **[arkclaude.ps1](arkclaude.ps1)** | Claude Code (CLI) | Windows(PowerShell 7+) | 火山方舟 Ark(Anthropic 兼容端点) | 同上 |\n| **[lcclaude](lcclaude)** | Claude Code (CLI) | macOS / Linux | 美团 LongCat(Anthropic 兼容端点) | `LongCat-2.0`(默认,1M 上下文)· `LongCat-Flash-Chat`(快速)· `LongCat-Flash-Thinking`(深度思考) |\n| **[lcclaude.ps1](lcclaude.ps1)** | Claude Code (CLI) | Windows(PowerShell 7+) | 美团 LongCat(Anthropic 兼容端点) | 同上 |\n| **[mxclaude](mxclaude)** | Claude Code (CLI) | macOS / Linux | MiniMax(Anthropic 兼容端点) | `MiniMax-M3`(默认,1M 上下文)· `MiniMax-M2.5`(快速) |\n| **[mxclaude.ps1](mxclaude.ps1)** | Claude Code (CLI) | Windows(PowerShell 7+) | MiniMax(Anthropic 兼容端点) | 同上 |\n| **[hyclaude](hyclaude)** | Claude Code (CLI) | macOS / Linux | 腾讯 TokenHub(Anthropic 兼容端点) | `hy3-preview`(默认)+ DeepSeek/Kimi/GLM/MiniMax/Qwen 别名 |\n| **[hyclaude.ps1](hyclaude.ps1)** | Claude Code (CLI) | Windows(PowerShell 7+) | 腾讯 TokenHub(Anthropic 兼容端点) | 同上 |\n| **[sfclaude](sfclaude)** | Claude Code (CLI) | macOS / Linux | 硅基流动 SiliconFlow(Anthropic 兼容端点) | `deepseek-ai/DeepSeek-V4-PRO`(默认)+ Kimi/GLM/Qwen/Yi/R1 别名 |\n| **[sfclaude.ps1](sfclaude.ps1)** | Claude Code (CLI) | Windows(PowerShell 7+) | 硅基流动 SiliconFlow(Anthropic 兼容端点) | 同上 |\n| **[xclaude](xclaude)** | 统一自动检测启动器 | macOS / Linux | 任意(自动检测已设置的 API Key) | — |\n| **[dsclaude-desktop](dsclaude-desktop)** | Claude Desktop (GUI) | macOS | DeepSeek API(Anthropic 兼容端点) | `deepseek-v4-pro` · `deepseek-v4-flash`(均启用 1M 上下文) |\n| **[dsclaude-desktop.ps1](dsclaude-desktop.ps1)** | Claude Desktop (GUI) | Windows(Store 版 & 标准安装) | DeepSeek API(Anthropic 兼容端点) | 同上 |\n| **[mmclaude-desktop](mmclaude-desktop)** | Claude Desktop (GUI) | macOS | 小米 MiMo(Anthropic 兼容端点) | `mimo-v2.5-pro` · `mimo-v2.5` |\n| **[mmclaude-desktop.ps1](mmclaude-desktop.ps1)** | Claude Desktop (GUI) | Windows | 小米 MiMo(Anthropic 兼容端点) | 同上 |\n| **[qwclaude-desktop](qwclaude-desktop)** | Claude Desktop (GUI) | macOS | 阿里云百炼 Qwen(Anthropic 兼容端点) | `qwen3.7-max` · `qwen3.6-flash`(按量/Token)· `qwen3.6-plus`(Coding Plan) |\n| **[qwclaude-desktop.ps1](qwclaude-desktop.ps1)** | Claude Desktop (GUI) | Windows | 阿里云百炼 Qwen(Anthropic 兼容端点) | 同上 |\n| **[glmclaude-desktop](glmclaude-desktop)** | Claude Desktop (GUI) | macOS | 智谱 AI GLM(Anthropic 兼容端点) | `glm-5.2` · `glm-4.7` |\n| **[glmclaude-desktop.ps1](glmclaude-desktop.ps1)** | Claude Desktop (GUI) | Windows | 智谱 AI GLM(Anthropic 兼容端点) | 同上 |\n| **[kmclaude-desktop](kmclaude-desktop)** | Claude Desktop (GUI) | macOS | 月之暗面 Kimi(Anthropic 兼容端点) | `kimi-k3` · `kimi-k2.5` |\n| **[kmclaude-desktop.ps1](kmclaude-desktop.ps1)** | Claude Desktop (GUI) | Windows | 月之暗面 Kimi(Anthropic 兼容端点) | 同上 |\n| **[arkclaude-desktop](arkclaude-desktop)** | Claude Desktop (GUI) | macOS | 火山方舟 Ark(Anthropic 兼容端点) | `doubao-seed-2.0-code` · `doubao-seed-2.0-pro` · `doubao-seed-2.0-lite` + Kimi/DeepSeek/GLM/MiniMax |\n| **[arkclaude-desktop.ps1](arkclaude-desktop.ps1)** | Claude Desktop (GUI) | Windows | 火山方舟 Ark(Anthropic 兼容端点) | 同上 |\n| **[lcclaude-desktop](lcclaude-desktop)** | Claude Desktop (GUI) | macOS | 美团 LongCat(Anthropic 兼容端点) | `LongCat-2.0` · `LongCat-Flash-Chat` |\n| **[lcclaude-desktop.ps1](lcclaude-desktop.ps1)** | Claude Desktop (GUI) | Windows | 美团 LongCat(Anthropic 兼容端点) | 同上 |\n| **[mxclaude-desktop](mxclaude-desktop)** | Claude Desktop (GUI) | macOS | MiniMax(Anthropic 兼容端点) | `MiniMax-M3` · `MiniMax-M2.5` |\n| **[mxclaude-desktop.ps1](mxclaude-desktop.ps1)** | Claude Desktop (GUI) | Windows | MiniMax(Anthropic 兼容端点) | 同上 |\n| **[hyclaude-desktop](hyclaude-desktop)** | Claude Desktop (GUI) | macOS | 腾讯 TokenHub(Anthropic 兼容端点) | `hy3-preview` + DeepSeek/Kimi/GLM/MiniMax/Qwen |\n| **[hyclaude-desktop.ps1](hyclaude-desktop.ps1)** | Claude Desktop (GUI) | Windows | 腾讯 TokenHub(Anthropic 兼容端点) | 同上 |\n| **[sfclaude-desktop](sfclaude-desktop)** | Claude Desktop (GUI) | macOS | 硅基流动 SiliconFlow(Anthropic 兼容端点) | `deepseek-ai/DeepSeek-V4-PRO` + Kimi/GLM/Qwen/Yi/R1 |\n| **[sfclaude-desktop.ps1](sfclaude-desktop.ps1)** | Claude Desktop (GUI) | Windows | 硅基流动 SiliconFlow(Anthropic 兼容端点) | 同上 |\n| **[skills/deepseek-vision](skills/deepseek-vision/)** | skill(任何加载 SKILL.md 的 agent) | macOS / Linux | DashScope(OpenAI/Anthropic 兼容) | `qwen3.6-flash`(默认视觉模型) |\n| **[dsvision-mcp](dsvision-mcp)** | MCP server(Claude Desktop / Cowork / 任何 MCP 客户端) | macOS / Linux | DashScope | `qwen3.6-flash`(默认视觉模型) |\n\n---\n\n## 工作原理\n\n![xxclaude 脚本逻辑图](docs/xxclaude-logic-cn.drawio.png)\n\n脚本逻辑总览:安装器、`xclaude` 自动检测调度器、各后端 CLI 启动器、Claude Desktop 配置器与 Codex 桥接,全部共享 `lib/common.sh`。PNG 内嵌 draw.io XML,用 [draw.io](https://app.diagrams.net) 打开即可继续编辑([中文源文件](docs/xxclaude-logic-cn.drawio) · [English version](docs/xxclaude-logic.drawio.png))。\n\n---\n\n## macOS 快速开始\n\n```bash\n# 一行安装(推荐):\ncurl -fsSL https://raw.githubusercontent.com/Agents365-ai/dsclaude/main/install.sh | bash\n\n# 或用户目录安装(无需 sudo):\ncurl -fsSL https://raw.githubusercontent.com/Agents365-ai/dsclaude/main/install.sh | bash -s -- --user\n\n# 或手动安装:\ngit clone https://github.com/Agents365-ai/dsclaude.git\ncd dsclaude\nchmod +x xclaude\n./xclaude\n```\n\n## Windows 快速开始\n\n```powershell\n# 一行安装(建议以管理员运行 PowerShell):\nirm https://raw.githubusercontent.com/Agents365-ai/dsclaude/main/install.ps1 | iex\n\n# 安装并自动添加 PATH:\nirm https://raw.githubusercontent.com/Agents365-ai/dsclaude/main/install.ps1 | iex -AddToPath\n\n# 然后启动:\npwsh -File xclaude.ps1\n```\n\n---\n\n## xclaude — 统一自动检测启动器\n\n不记得该用哪个脚本?`xclaude` 自动检测你设置的 API Key 并委托给对应的后端启动器。\n\n```bash\n# 在 ~/.zshrc 中设置任意一个即可:\nexport DEEPSEEK_API_KEY=sk-... # → dsclaude\nexport GLM_API_KEY=... # → glmclaude\nexport KIMI_API_KEY=sk-... # → kmclaude\nexport ARK_API_KEY=... # → arkclaude\n# ... 或其他支持的 Key\n\nxclaude # 自动检测并启动\nxclaude fast # 使用 fast/flash 档位\nxclaude long effort max # 1M 上下文 + max 推理等级\nxclaude kimi # 转发:在 Ark/TokenHub 上 → kimi 模型\n```\n\n所有位置参数(模型别名、`fast`、`long`、`effort` 等)均透传给底层启动器。如果同时设置了多个 Key,按检测顺序选第一个;可设置 `XCLAUDE_PREFER=dsclaude` 来强制指定。\n\n---\n\n## dsclaude — Claude Code 接入 DeepSeek\n\n遵循 [DeepSeek Anthropic API](https://api-docs.deepseek.com/guides/anthropic_api) 指南。\n\n```bash\nexport DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxxxxxxx # 添加到 ~/.zshrc\n\ndsclaude # 默认 deepseek-v4-pro(完整推理)\ndsclaude fast # deepseek-v4-flash(更快更便宜)\ndsclaude long # 1M 上下文窗口\ndsclaude long fast # 1M + flash\n```\n\n自动设置 DeepSeek 推荐的环境变量(`ANTHROPIC_BASE_URL`、模型映射、`CLAUDE_CODE_EFFORT_LEVEL=max`),并在 `/model` 选择器中暴露备选模型。上下文窗口上限可通过 `DSCLAUDE_MAX_TOKENS` 覆盖,effort 级别通过 `DSCLAUDE_EFFORT` 覆盖。\n\n> 两个模型都原生支持 1M token,在 Claude Code 中需加 `[1m]` 后缀(如 `deepseek-v4-pro[1m]`),脚本已自动处理。\n>\n> Windows(PowerShell 7+):`pwsh -File ./dsclaude.ps1`(参数相同)。\n\n---\n\n## mmclaude — Claude Code 接入小米 MiMo\n\n```bash\nexport MIMO_API_KEY=sk-xxxxxxxxxxxxxxxxxx # 按量付费\n# 或\nexport MIMO_API_KEY=tp-xxxxxxxxxxxxxxxxxx # Token Plan\n\nmmclaude # 启动 mimo-v2.5-pro\nmmclaude fast # 启动 mimo-v2.5(更便宜 / 更快的 flash 档)\nmmclaude update # git pull 拉取更新\n```\n\n按 key 前缀自动选择 base URL(`sk-*` → 公网,`tp-*` → Token Plan),可用 `MIMO_BASE_URL` 覆盖。main/opus/sonnet 槽位使用 `mimo-v2.5-pro`,haiku 与子代理(subagent)档使用 `mimo-v2.5`(flash);`mmclaude fast` 会把主模型切到 flash,另一档会出现在 `/model` 选择器里以便会话中切换。自动 unset `ANTHROPIC_API_KEY`(避免遮蔽 bearer token)。可用 `MIMO_MODEL` / `MIMO_FLASH_MODEL` 覆盖两档模型。\n\n> Windows(PowerShell 7+):`pwsh -File ./mmclaude.ps1`(参数相同)。\n\n---\n\n## qwclaude — Claude Code 接入阿里云百炼 Qwen\n\n```bash\n# 每个套餐一把 key,分别来自百炼控制台不同入口:\nexport DASHSCOPE_API_KEY=sk-xxxxxxxxxxxxxxxxxx # 按量付费\nexport DASHSCOPE_CP_API_KEY=sk-xxxxxxxxxxxxxxxxxx # Coding Plan\nexport DASHSCOPE_TP_API_KEY=sk-xxxxxxxxxxxxxxxxxx # Token Plan 团队版\n\n# macOS / Linux — 三个模型档位\nqwclaude # 按量付费,qwen3.7-max(北京) → DASHSCOPE_API_KEY\nqwclaude plus # qwen3.7-plus(平衡之选,约 max 的 1/6 价格)\nqwclaude max # 显示指定 qwen3.7-max\nqwclaude fast # qwen3.6-flash 作主模型\nqwclaude intl # 按量付费,新加坡端点\nqwclaude coding # Coding Plan(qwen3.7-plus 推荐) → DASHSCOPE_CP_API_KEY\nqwclaude coding plus # Coding Plan,qwen3.7-plus(默认)\nqwclaude coding fast # Coding Plan,qwen3.6-plus\nqwclaude token # Token Plan(qwen3.7-max) → DASHSCOPE_TP_API_KEY\nqwclaude token plus # Token Plan,qwen3.7-plus\nqwclaude update # git pull 拉取更新\n\n# Windows(PowerShell 7+)\npwsh -File ./qwclaude.ps1 coding\n```\n\n按所选套餐与模型档位自动选择 base URL、模型阵容与 API key 变量。三个模型档位:\n\n| 档位 | 按量付费 / Token Plan | Coding Plan |\n| ------ | ---------------------- | ------------- |\n| **max**(默认) | `qwen3.7-max`(旗舰推理) | 不可用 |\n| **plus** | `qwen3.7-plus`(平衡,约 max 的 1/6) | `qwen3.7-plus`(推荐) |\n| **flash**(subagent/haiku 档) | `qwen3.6-flash` | `qwen3.6-plus` |\n\nMain/opus/sonnet 槽位运行所选档位(默认 `qwen3.7-max`),haiku 与子代理(subagent)档始终使用 flash 模型。`fast` 把主模型切到 flash;`plus` 切到 qwen3.7-plus。另一档会出现在 `/model` 选择器里以便会话中切换。设置 `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1` 并 unset `ANTHROPIC_API_KEY`,把流量锁定在百炼(避免连到 `api.anthropic.com` 报错)。可用 `QWEN_PLAN` / `QWEN_REGION` / `QWEN_MODEL` / `QWEN_PLUS_MODEL` / `QWEN_FLASH_MODEL` / `QWEN_BASE_URL` 覆盖。\n\n> Windows 版(`qwclaude.ps1`)需要 PowerShell 7+(`winget install Microsoft.PowerShell`),用 `pwsh -File` 运行。\n\n---\n\n## glmclaude — Claude Code 接入智谱 AI GLM\n\n遵循智谱 AI 的 Anthropic 兼容 API。\n\n```bash\nexport GLM_API_KEY=你的智谱API_KEY # 添加到 ~/.zshrc\n# 在 https://open.bigmodel.cn/usercenter/apikeys 获取你的 key\n\nglmclaude # 默认 glm-5.2(完整推理)\nglmclaude fast # glm-4.7(更快更便宜)\nglmclaude update # git pull 拉取更新\n```\n\n自动设置智谱推荐的环境变量(`ANTHROPIC_BASE_URL`、模型映射),并在 `/model` 选择器中暴露备选模型。main/opus/sonnet 槽位使用 `glm-5.2`,haiku 与子代理(subagent)档使用 `glm-4.7`;`glmclaude fast` 会把主模型切到 flash,另一档会出现在 `/model` 选择器里以便会话中切换。\n\n默认使用国内端点(`https://open.bigmodel.cn/api/anthropic`)。如需使用海外端点,设置 `GLM_BASE_URL`:\n\n```bash\nexport GLM_BASE_URL=https://api.z.ai/api/anthropic\nglmclaude\n```\n\n可用 `GLM_MODEL` / `GLM_FLASH_MODEL` 覆盖两档模型。\n\n> Windows(PowerShell 7+):`pwsh -File ./glmclaude.ps1`(参数相同)。\n\n---\n\n## kmclaude — Claude Code 接入月之暗面 Kimi\n\n遵循月之暗面 Kimi 的 Anthropic 兼容 API。\n\n```bash\nexport KIMI_API_KEY=sk-xxxxxxxxxxxxxxxxxx # 添加到 ~/.zshrc\n# 在 https://platform.moonshot.cn/console/api-keys 获取你的 key\n\nkmclaude # 默认 kimi-k3(旗舰推理)\nkmclaude fast # kimi-k2.5(更快更便宜)\nkmclaude update # git pull 拉取更新\n```\n\n使用 Kimi 官方 Anthropic 兼容端点(`https://api.moonshot.cn/anthropic`)。main/opus/sonnet 槽位使用 `kimi-k3`,haiku 与子代理(subagent)档使用 `kimi-k2.5`;`kmclaude fast` 会把主模型切到 flash,另一档会出现在 `/model` 选择器里以便会话中切换。自动 unset `ANTHROPIC_API_KEY`(避免遮蔽 bearer token)。可用 `KIMI_MODEL` / `KIMI_FLASH_MODEL` 覆盖两档模型,`KIMI_BASE_URL` 覆盖端点地址。\n\n> Windows(PowerShell 7+):`pwsh -File ./kmclaude.ps1`(参数相同)。\n\n---\n\n## dsclaude-desktop — Claude Desktop GUI 配置器\n\n一键配置 Claude Desktop **内置**的 Third-Party Inference 功能(Developer 菜单),预填 DeepSeek 参数并重启 App。\n\n### 前置条件\n\n1. 已安装 Claude Desktop([claude.ai/download](https://claude.ai/download))\n2. 已启用 Developer Mode(Help → Troubleshooting → Enable Developer Mode,一次即可)\n3. 已设置 `DEEPSEEK_API_KEY` 环境变量\n\n### 用法\n\n```bash\nexport DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxxxxxxx\n./dsclaude-desktop # 配置并重启\n./dsclaude-desktop -h # 帮助\n```\n\n脚本在 `~/Library/Application Support/Claude-3p/configLibrary/` 下生成配置 entry,将其设为 `appliedId`,然后重启 App。原本通过 GUI 添加的其他 entry 不受影响。\n\n### 模式切换\n\nClaude Desktop 启动选择器原生支持 Anthropic ↔ Gateway 切换,无需 `--revert`。在 App 内点头像 → Disconnect,下次启动时选另一个入口即可。\n\n> 唯一不可用的功能是经典 **Chat**(依赖 Anthropic 托管服务且不在 inference API 表面)。需要用 Chat 时切回 Anthropic 模式即可。\n\n### Windows 版本\n\n```powershell\n$env:DEEPSEEK_API_KEY = \"sk-xxxxxxxxxxxxxxxxxx\"\npwsh ./dsclaude-desktop.ps1\n```\n\n配置目录为 `%APPDATA%\\Claude-3p\\configLibrary\\`。> 作者未在 Windows 上实测,如有问题请[提 issue](https://github.com/Agents365-ai/dsclaude/issues)。\n\n---\n前置条件:Claude Desktop 已安装(Store 版或标准安装均可)、有 DeepSeek API Key。**无需手动启用 Developer Mode**——脚本会自动创建 `developer_settings.json`。\n\n配置目录:`%LOCALAPPDATA%\\Claude-3p\\configLibrary\\`(若为 Store/MSIX 安装,脚本还会额外写入沙箱路径 `LocalCache\\Roaming\\Claude-3p\\configLibrary\\` 作为后备)。\n\n已在 Windows 11 + Claude Desktop 1.7196(Windows Store, arm64)上实测通过。\n\n---\n\n## mmclaude-desktop — Claude Desktop 接入小米 MiMo\n\n与 `dsclaude-desktop` 相同的配置器,预填小米 MiMo。读取 `MIMO_API_KEY`,按 key 前缀自动选择 base URL(`tp-*` → Token Plan,否则按量付费;可用 `MIMO_BASE_URL` 覆盖),配置 `mimo-v2.5-pro` + `mimo-v2.5`。\n\n```bash\nexport MIMO_API_KEY=sk-xxxxxxxxxxxxxxxxxx # 或 tp-... 表示 Token Plan\n./mmclaude-desktop # 配置并重启(macOS)\n./mmclaude-desktop -h # 帮助\n\n# Windows(PowerShell)\n$env:MIMO_API_KEY = \"sk-xxxxxxxxxxxxxxxxxx\"\npwsh ./mmclaude-desktop.ps1\n```\n\n---\n\n## qwclaude-desktop — Claude Desktop 接入阿里云百炼 Qwen\n\n同款配置器,按套餐与模型档位自动选择 base URL、模型与 key 变量。按量付费(`DASHSCOPE_API_KEY`)与 Token Plan(`DASHSCOPE_TP_API_KEY`)配置 `qwen3.7-max` + `qwen3.6-flash`;Coding Plan(`DASHSCOPE_CP_API_KEY`)配置 `qwen3.7-plus` + `qwen3.6-plus`。添加 `plus` 参数可在任意套餐中使用 qwen3.7-plus。\n\n```bash\nexport DASHSCOPE_API_KEY=sk-xxxxxxxxxxxxxxxxxx # 按量付费\nexport DASHSCOPE_CP_API_KEY=sk-xxxxxxxxxxxxxxxxxx # Coding Plan\nexport DASHSCOPE_TP_API_KEY=sk-xxxxxxxxxxxxxxxxxx # Token Plan\n\n./qwclaude-desktop # 按量付费(北京),qwen3.7-max,然后重启\n./qwclaude-desktop plus # 按量付费,qwen3.7-plus\n./qwclaude-desktop intl # 按量付费,新加坡端点\n./qwclaude-desktop coding # Coding Plan(qwen3.7-plus)\n./qwclaude-desktop token # Token Plan,qwen3.7-max\n./qwclaude-desktop token plus # Token Plan,qwen3.7-plus\n\n# Windows(PowerShell)\npwsh ./qwclaude-desktop.ps1 -Plan coding\npwsh ./qwclaude-desktop.ps1 -Plan token -ModelTier plus\n```\n\n> 两个 `.ps1` Windows 版移植自 `dsclaude-desktop.ps1`,**作者未在 Windows 上实测**,如有问题请[提 issue](https://github.com/Agents365-ai/dsclaude/issues)。两个配置器都会设置 `unstableDisableModelVerification`,让 Claude Desktop 接受非 Anthropic 的模型名;与 `dsclaude-desktop` 一样,网关启用期间 Chat 模式不可用。\n\n## glmclaude-desktop — Claude Desktop 接入智谱 AI GLM\n\n同款配置器,预填智谱 GLM。读取 `GLM_API_KEY`,配置 `glm-5.2` + `glm-4.7`。\n\n```bash\nexport GLM_API_KEY=你的智谱API_KEY\n./glmclaude-desktop # 配置并重启(macOS)\n./glmclaude-desktop -h # 帮助\n\n# Windows(PowerShell)\n$env:GLM_API_KEY = \"你的智谱API_KEY\"\npwsh ./glmclaude-desktop.ps1\n```\n\n可通过 `GLM_BASE_URL` 覆盖 base URL(默认:`https://open.bigmodel.cn/api/anthropic`)。\n\n---\n\n## kmclaude-desktop — Claude Desktop 接入月之暗面 Kimi\n\n同款配置器,预填 Kimi。读取 `KIMI_API_KEY`,配置 `kimi-k3` + `kimi-k2.5`。\n\n```bash\nexport KIMI_API_KEY=你的Kimi_API_KEY\n./kmclaude-desktop # 配置并重启(macOS)\n./kmclaude-desktop -h # 帮助\n\n# Windows(PowerShell)\n$env:KIMI_API_KEY = \"你的Kimi_API_KEY\"\npwsh ./kmclaude-desktop.ps1\n```\n\n可通过 `KIMI_BASE_URL` 覆盖 base URL(默认:`https://api.moonshot.cn/anthropic`)。\n\n---\n\n## arkclaude — Claude Code 接入火山方舟 Ark(Coding Plan)\n\n火山方舟 Ark Coding Plan 是一个多模型聚合平台 — 一次订阅即可使用豆包、Kimi、DeepSeek、GLM、MiniMax 等多家模型。一个 API Key、一个端点、多模型随意切换。\n\n```bash\nexport ARK_API_KEY=你的Ark_API_KEY # 添加到 ~/.zshrc\n# 在 https://console.volcengine.com/ark 获取你的 key\n\n# 三种豆包档位 + 厂商别名快速切换\narkclaude # doubao-seed-2.0-code(代码专项,默认)\narkclaude plus # doubao-seed-2.0-pro(平衡之选)\narkclaude fast # doubao-seed-2.0-lite(轻量快速)\narkclaude kimi # kimi-k2.7-code(Kimi 代码模型)\narkclaude kimi-pro # kimi-k2.6\narkclaude deepseek # deepseek-v4-pro\narkclaude deepseek-flash # deepseek-v4-flash\narkclaude glm # glm-5.2\narkclaude minimax # minimax-m2.7\narkclaude update # git pull 拉取更新\n```\n\n使用 Ark Coding Plan 端点(`https://ark.cn-beijing.volces.com/api/coding`)。main/opus/sonnet 槽位运行所选模型,haiku 与子代理(subagent)档始终使用同一家族中最便宜的模型(或 `doubao-seed-2.0-lite` 作为降级)。`/model` 选择器会根据当前选择智能暴露对应备选 — 用 doubao 时暴露 Pro↔Code,用 Kimi 时暴露 K2.6↔K2.7-code 等。设置 `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1` 并 unset `ANTHROPIC_API_KEY`。可用 `ARK_MODEL` / `ARK_PLUS_MODEL` / `ARK_FLASH_MODEL` / `ARK_BASE_URL` 覆盖。\n\n> Windows(PowerShell 7+):`pwsh -File ./arkclaude.ps1`(参数相同)。\n\n---\n\n## arkclaude-desktop — Claude Desktop 接入火山方舟 Ark\n\n同款配置器,预填 Ark Coding Plan。读取 `ARK_API_KEY`。支持所有模型别名。\n\n```bash\nexport ARK_API_KEY=你的Ark_API_KEY\n./arkclaude-desktop # 配置 doubao-seed-2.0-code 并重启\n./arkclaude-desktop plus # doubao-seed-2.0-pro\n./arkclaude-desktop kimi # kimi-k2.7-code\n./arkclaude-desktop deepseek # deepseek-v4-pro\n./arkclaude-desktop glm # glm-5.2\n./arkclaude-desktop minimax # minimax-m2.7\n./arkclaude-desktop -h # 帮助\n\n# Windows(PowerShell)\n$env:ARK_API_KEY = \"你的Ark_API_KEY\"\npwsh ./arkclaude-desktop.ps1 -ModelTier kimi\n```\n\n可通过 `ARK_BASE_URL` 覆盖 base URL(默认:`https://ark.cn-beijing.volces.com/api/coding`)。\n\n---\n\n## lcclaude — Claude Code 接入美团 LongCat\n\nLongCat-2.0 是美团自研的 1.6 万亿参数 MoE 大模型,全程国产算力训练,1M 原生上下文窗口。OpenRouter 数据显示 LongCat-2.0 在 Claude Code 月调用量位列全球第二。**公测期间免费** — 每日 50 万 Token。\n\n```bash\nexport LONGCAT_API_KEY=lc-xxxxxxxxxxxxxxxxxx # 添加到 ~/.zshrc\n# 在 https://longcat.chat/platform 免费获取 key\n\nlcclaude # LongCat-2.0(1M 上下文,旗舰模型)\nlcclaude fast # LongCat-Flash-Chat(快速/便宜)\nlcclaude think # LongCat-Flash-Thinking(深度推理)\nlcclaude update # git pull 拉取更新\n```\n\n使用 LongCat 官方 Anthropic 兼容端点(`https://api.longcat.chat/anthropic`)。main/opus/sonnet 槽位运行所选模型,haiku 与子代理(subagent)档使用 `LongCat-Flash-Chat`。`/model` 选择器暴露备选档位。可用 `LONGCAT_MODEL` / `LONGCAT_FLASH_MODEL` / `LONGCAT_THINK_MODEL` / `LONGCAT_BASE_URL` 覆盖。\n\n> Windows(PowerShell 7+):`pwsh -File ./lcclaude.ps1`(参数相同)。\n\n---\n\n## lcclaude-desktop — Claude Desktop 接入美团 LongCat\n\n同款配置器,预填 LongCat。读取 `LONGCAT_API_KEY`,配置 `LongCat-2.0` + `LongCat-Flash-Chat`。\n\n```bash\nexport LONGCAT_API_KEY=lc-xxxxxxxxxxxxxxxxxx\n./lcclaude-desktop # 配置并重启(macOS)\n./lcclaude-desktop -h # 帮助\n\n# Windows(PowerShell)\n$env:LONGCAT_API_KEY = \"lc-xxxxxxxxxxxxxxxxxx\"\npwsh ./lcclaude-desktop.ps1\n```\n\n可通过 `LONGCAT_BASE_URL` 覆盖 base URL(默认:`https://api.longcat.chat/anthropic`)。\n\n---\n\n## mxclaude — Claude Code 接入 MiniMax\n\nMiniMax-M3 是 1M 上下文旗舰模型,专为 Agent 推理、工具调用和编程场景优化。**需要使用 Coding Plan(Token Plan)API Key**,按量付费 key 不可用。\n\n```bash\nexport MINIMAX_API_KEY=你的MiniMax_API_KEY # 添加到 ~/.zshrc\n# 在 https://platform.minimaxi.com 获取你的 key\n\nmxclaude # MiniMax-M3(1M 上下文,旗舰模型)\nmxclaude fast # MiniMax-M2.5(快速/便宜)\nmxclaude long # 1M 上下文窗口\nmxclaude effort max # 设置推理等级(low|medium|high|xhigh|max)\nmxclaude update # git pull 拉取更新\n```\n\n使用 MiniMax 官方 Anthropic 兼容端点(默认国内:`https://api.minimaxi.com/anthropic`;国际站:`https://api.minimax.io/anthropic`,通过 `MINIMAX_BASE_URL` 设置)。main/opus/sonnet 槽位运行所选模型,haiku 与子代理(subagent)档使用 `MiniMax-M2.5`。`/model` 选择器暴露备选档位。可用 `MINIMAX_MODEL` / `MINIMAX_FLASH_MODEL` / `MINIMAX_BASE_URL` / `MINIMAX_CTX` / `MINIMAX_OUTPUT` / `MINIMAX_EFFORT` 覆盖。\n\n> Windows(PowerShell 7+):`pwsh -File ./mxclaude.ps1`(参数相同)。\n\n---\n\n## mxclaude-desktop — Claude Desktop 接入 MiniMax\n\n同款配置器,预填 MiniMax。读取 `MINIMAX_API_KEY`,配置 `MiniMax-M3` + `MiniMax-M2.5`。\n\n```bash\nexport MINIMAX_API_KEY=你的MiniMax_API_KEY\n./mxclaude-desktop # 配置并重启(macOS)\n./mxclaude-desktop -h # 帮助\n\n# Windows(PowerShell)\n$env:MINIMAX_API_KEY = \"你的MiniMax_API_KEY\"\npwsh ./mxclaude-desktop.ps1\n```\n\n可通过 `MINIMAX_BASE_URL` 覆盖 base URL默认国内:`https://api.minimaxi.com/anthropic`;国际站:`https://api.minimax.io/anthropic`)。\n\n---\n\n## hyclaude — Claude Code 接入腾讯 TokenHub\n\n腾讯 TokenHub 是多模型聚合平台 — 一次订阅即可使用混元(HY3)、DeepSeek、GLM、Kimi、MiniMax、Qwen 等多家模型。\n\n```bash\nexport HY_API_KEY=你的API_KEY # 添加到 ~/.zshrc\n# 在 https://cloud.tencent.com/product/lkeap 获取你的 key\n\nhyclaude # hy3-preview(腾讯默认)\nhyclaude fast # hy-mt2-lite(轻量快速)\nhyclaude deepseek # deepseek-v4-pro\nhyclaude kimi # kimi-k2.7-code\nhyclaude glm # glm-5.2\nhyclaude minimax # minimax-m3\nhyclaude qwen # qwen3.5-plus\nhyclaude long # 最大上下文窗口\nhyclaude effort max # 设置推理等级(low|medium|high|xhigh|max)\nhyclaude update # git pull 拉取更新\n```\n\n使用 TokenHub Anthropic 兼容端点(默认:`https://api.lkeap.cloud.tencent.com/plan/anthropic`)。main/opus/sonnet 槽位运行所选模型,haiku 与子代理(subagent)档使用 `hy-mt2-lite`(或同家族 flash 模型)。`/model` 选择器智能暴露对应备选。可用 `HY_MODEL` / `HY_FLASH_MODEL` / `HY_BASE_URL` / `HY_CTX` / `HY_OUTPUT` / `HY_EFFORT` 覆盖。\n\n> Windows(PowerShell 7+):`pwsh -File ./hyclaude.ps1`(参数相同)。\n\n---\n\n## hyclaude-desktop — Claude Desktop 接入腾讯 TokenHub\n\n同款配置器,预填 TokenHub。读取 `HY_API_KEY`。支持模型别名选定后端模型。\n\n```bash\nexport HY_API_KEY=你的API_KEY\n./hyclaude-desktop # 配置 hy3-preview 并重启\n./hyclaude-desktop kimi # kimi-k2.7-code\n./hyclaude-desktop deepseek # deepseek-v4-pro\n./hyclaude-desktop glm # glm-5.2\n./hyclaude-desktop minimax # minimax-m3\n./hyclaude-desktop qwen # qwen3.5-plus\n./hyclaude-desktop -h # 帮助\n\n# Windows(PowerShell)\n$env:HY_API_KEY = \"你的API_KEY\"\npwsh ./hyclaude-desktop.ps1 -ModelTier kimi\n```\n\n可通过 `HY_BASE_URL` 覆盖 base URL(默认:`https://api.lkeap.cloud.tencent.com/plan/anthropic`)。\n\n---\n\n## sfclaude — Claude Code 接入硅基流动 SiliconFlow\n\n硅基流动是多模型平台,聚合了 DeepSeek、Kimi、GLM、MiniMax、Qwen、Yi 等模型。模型名称使用 `provider/Model-Name` 格式(如 `deepseek-ai/DeepSeek-V4-PRO`)。\n\n```bash\nexport SF_API_KEY=sk-xxxxxxxxxxxxxxxxxx # 添加到 ~/.zshrc\n# 在 https://cloud.siliconflow.cn/account/ak 获取 key\n\nsfclaude # deepseek-ai/DeepSeek-V4-PRO(默认)\nsfclaude fast # deepseek-ai/DeepSeek-V3(轻量快速)\nsfclaude kimi # moonshotai/Kimi-K2-Instruct-0905\nsfclaude glm # Pro/zai-org/GLM-5\nsfclaude minimax # Pro/MiniMaxAI/MiniMax-M2.5\nsfclaude qwen # Qwen/Qwen2.5-Coder\nsfclaude yi # 01-ai/Yi-1.5\nsfclaude r1 # deepseek-ai/DeepSeek-R1(深度推理)\nsfclaude long # 最大上下文窗口\nsfclaude effort max # 设置推理等级(low|medium|high|xhigh|max)\nsfclaude update # git pull 拉取更新\n```\n\n使用硅基流动 Anthropic 兼容端点(`https://api.siliconflow.cn/`)。main/opus/sonnet 槽位运行所选模型,haiku 与子代理(subagent)档使用 `deepseek-ai/DeepSeek-V3`。可用 `SF_MODEL` / `SF_FLASH_MODEL` / `SF_BASE_URL` / `SF_CTX` / `SF_OUTPUT` / `SF_EFFORT` 覆盖。\n\n> Windows(PowerShell 7+):`pwsh -File ./sfclaude.ps1`(参数相同)。\n\n---\n\n## sfclaude-desktop — Claude Desktop 接入 SiliconFlow\n\n同款配置器,预填硅基流动。读取 `SF_API_KEY`。支持模型别名。\n\n```bash\nexport SF_API_KEY=sk-xxxxxxxxxxxxxxxxxx\n./sfclaude-desktop # deepseek-ai/DeepSeek-V4-PRO 并重启\n./sfclaude-desktop kimi # moonshotai/Kimi-K2-Instruct-0905\n./sfclaude-desktop r1 # deepseek-ai/DeepSeek-R1\n./sfclaude-desktop -h # 帮助\n\n# Windows(PowerShell)\n$env:SF_API_KEY = \"sk-xxxxxxxxxxxxxxxxxx\"\npwsh ./sfclaude-desktop.ps1 -ModelTier kimi\n```\n\n---\n\n## deepseek-vision skill — 视觉识别(零依赖方案)\n\n---\n\n## deepseek-vision skill — 视觉识别(零依赖方案)\n\n给纯文本模型(如 DeepSeek)补上\"看图\"能力的 skill。代理遇到图片时调 `analyze-image` 脚本,发给 Qwen3.6-Flash 识别后将描述返回主模型。\n\n```bash\nexport DASHSCOPE_API_KEY=sk-xxxxxxxxxxxxxxxxxx\n./skills/deepseek-vision/analyze-image /path/to/screenshot.png \"图里报的什么错?\"\n./skills/deepseek-vision/analyze-image https://example.com/diagram.png\n```\n\n任何加载 `SKILL.md` 的 agent(Claude Code、Cowork 等)都能用它。默认模型 `qwen3.6-flash`,可通过 `DSVISION_MODEL` 和 `DSVISION_BASE_URL` 切换。\n\n> **限制**:需文件路径或 URL,不支持拖拽/粘贴/「+ → Add files or photos」上传的图片。这类场景请用下方的 **dsvision-mcp**。\n\n---\n\n## dsvision-mcp — 视觉识别(MCP 方案)\n\n功能同上,但以 MCP 服务形式运行,绕过 Cowork 沙箱的两个限制:\n\n1. **网络出口管制** — skill 调 DashScope API 会被沙箱防火墙拦截,MCP 服务跑在沙箱外\n2. **内联图片** — 自动读取 `~/.claude/image-cache/` 中最新缓存,拖拽/粘贴/菜单上传均可正常工作(仅 macOS,Windows Cowork 不缓存内联图)\n\n### 安装\n\n```bash\npip3 install fastmcp requests\nexport DASHSCOPE_API_KEY=sk-xxxxxxxxxxxxxxxxxx # 建议加到 ~/.zshrc\ncd /path/to/dsclaude && pwd # 记下绝对路径\n```\n\n然后根据当前模式,在对应的配置文件中添加 MCP 服务:\n\n| 模式 | 配置文件 |\n|------|----------|\n| 3P/Gateway(通过 `dsclaude-desktop` 使用 DeepSeek) | `~/Library/Application Support/Claude-3p/claude_desktop_config.json` |\n| 标准 Anthropic 模式 | `~/Library/Application Support/Claude/claude_desktop_config.json` |\n\n```json\n{\n \"mcpServers\": {\n \"dsvision\": {\n \"command\": \"/绝对/路径/dsclaude/dsvision-mcp\"\n }\n }\n}\n```\n\n重启 Claude Desktop 后,`analyze_image` 工具自动出现。\n\n### 用法\n\n```\nanalyze_image() # 自动检测最新缓存图片\nanalyze_image(image_path=\"/绝对/路径/foo.png\")\nanalyze_image(focus=\"图里报的什么错?\") # 自定义 prompt\n```\n\n### 常见问题\n\n| 现象 | 排查方向 |\n| ------ | ---------- |\n| 工具不显示 | 配置文件路径选错 / JSON 格式错误(用 `python3 -m json.tool` 校验) |\n| 工具报错 | `DASHSCOPE_API_KEY` 未设置 |\n| `ModuleNotFoundError` | 用 `pip3` 而非 `pip` |\n| 找不到图片 | 传绝对路径,或检查 `~/.claude/image-cache/` 是否存在 |\n\n### skill vs MCP 怎么选\n\n| 场景 | 推荐 |\n| ------ | ------ |\n| Claude Code (CLI),给明确路径 | `skills/deepseek-vision`(零依赖) |\n| Cowork / Desktop,拖拽/粘贴内联图 | `dsvision-mcp`(唯一能用的) |\n| Cowork,给明确路径,不介意沙箱限制 | 两者均可 |\n\n---\n\n## 赞赏支持\n\n如果这些脚本为你节省了时间,欢迎支持作者:\n\n\n \n \n \n \n \n \n
\"微信支付\"
微信支付
\"支付宝\"
支付宝
\"Buy
Buy Me a Coffee
\"打赏\"
打赏鼓励
\n\n## 作者\n\n**Agents365-ai** · [Bilibili](https://space.bilibili.com/441831884) · [GitHub](https://github.com/Agents365-ai)\n\n## 开源协议\n\n[CC BY-NC 4.0](LICENSE.md) — 非商业用途免费。**商业使用需获得授权。**\n"}}, "lcclaude": {"c07db31916dca8077b9124f5c098258f9607b016": {"t": 1785674294.648063, "n": 4503, "h": "ce982304950b46b9", "c": "#!/usr/bin/env bash\n# shellcheck disable=SC2034 # variables consumed by lib/common.sh\n# lcclaude — launch Claude Code on Meituan LongCat's Anthropic-compatible API.\n#\n# Uses the official LongCat Anthropic-compatible endpoint:\n# https://api.longcat.chat/anthropic\n#\n# LongCat-2.0 is a 1.6T-param MoE model with native 1M context, built entirely\n# on Chinese-manufactured compute. It ranked #2 globally in Claude Code monthly\n# call volume on OpenRouter (behind only Claude Opus 4.8).\n#\n# Reads LONGCAT_API_KEY from the environment first, then falls back to\n# ~/.zshrc / ~/.bashrc / ~/.bash_profile / ~/.profile if not already exported.\n#\n# Quick start (no install needed):\n# chmod +x lcclaude\n# ./lcclaude\n#\n# Optional — make it globally available:\n# sudo mv lcclaude /usr/local/bin/ && sudo chmod +x /usr/local/bin/lcclaude\n#\n# Use:\n# lcclaude # start on LongCat-2.0 (flagship)\n# lcclaude fast # start on LongCat-Flash-Chat (cheaper / faster)\n# lcclaude think # start on LongCat-Flash-Thinking (deep reasoning)\n# lcclaude long # request 1M context window (native support)\n# lcclaude effort max # set reasoning effort (low|medium|high|xhigh|max)\n# lcclaude update # git pull latest from this repo\n# lcclaude --help # any remaining flag is forwarded to claude\n#\n# Optional env overrides:\n# LONGCAT_MODEL=LongCat-2.0 # main model\n# LONGCAT_FLASH_MODEL=LongCat-Flash-Chat # flash / haiku / subagent tier\n# LONGCAT_BASE_URL=https://.../anthropic # custom Anthropic-compatible base URL\n# LONGCAT_CTX=1048576 # max context tokens (defaults to 1M with `long`)\n# LONGCAT_OUTPUT=8000 # cap output tokens\n# LONGCAT_EFFORT=max # CLAUDE_CODE_EFFORT_LEVEL\n#\n# In-session switch:\n# /model LongCat-Flash-Chat # switch to the fast tier\n# /model LongCat-Flash-Thinking # switch to thinking tier\n# /model LongCat-2.0 # switch back to flagship\n#\n# Get your free API key (public beta — 500K tokens/day free):\n# https://longcat.chat/platform\n#\nset -euo pipefail\n\n# Resolve symlink to find the real script directory.\n_SELF=\"$0\"\nif [ -L \"$_SELF\" ]; then\n _LINK=\"$(readlink \"$_SELF\")\"\n case \"$_LINK\" in\n /*) _SELF=\"$_LINK\" ;;\n *) _SELF=\"$(cd \"$(dirname \"$_SELF\")\" && pwd)/$_LINK\" ;;\n esac\nfi\nSELF_DIR=\"$(cd \"$(dirname \"$_SELF\")\" && pwd)\"\nif [ -f \"$SELF_DIR/lib/common.sh\" ]; then source \"$SELF_DIR/lib/common.sh\"\nelif [ -f \"$SELF_DIR/../lib/common.sh\" ]; then source \"$SELF_DIR/../lib/common.sh\"\nelse echo \"lcclaude: cannot find lib/common.sh. Reinstall or cd to repo.\" >&2; exit 1; fi\n\ncheck_version \"lcclaude\" \"$@\"\n\nPRO_MODEL=\"${LONGCAT_MODEL:-LongCat-2.0}\"\nFLASH_MODEL=\"${LONGCAT_FLASH_MODEL:-LongCat-Flash-Chat}\"\nTHINK_MODEL=\"${LONGCAT_THINK_MODEL:-LongCat-Flash-Thinking}\"\n\nif [ $# -gt 0 ] && [ \"$1\" = \"update\" ]; then\n do_update \"lcclaude\" \"LCCLAUDE_HOME\"\nfi\n\nAPI_KEY=\"$(resolve_api_key \"LONGCAT_API_KEY\")\"\nif [ -z \"$API_KEY\" ]; then\n echo \"❌ LONGCAT_API_KEY not found.\" >&2\n echo \" Add one line to ~/.zshrc or ~/.bashrc:\" >&2\n echo \" export LONGCAT_API_KEY=lc-xxxxxxxxxxxxxxxxxx\" >&2\n echo \" Get your free key at: https://longcat.chat/platform\" >&2\n exit 1\nfi\n\nBASE_URL=\"${LONGCAT_BASE_URL:-https://api.longcat.chat/anthropic}\"\n\nLONG_CTX=0\nEFFORT=\"${LONGCAT_EFFORT:-}\"\n\nMAIN_MODEL=\"$PRO_MODEL\"\nwhile [ $# -gt 0 ]; do\n case \"$1\" in\n fast|flash) MAIN_MODEL=\"$FLASH_MODEL\"; shift ;;\n think) MAIN_MODEL=\"$THINK_MODEL\"; shift ;;\n long) LONG_CTX=1; shift ;;\n effort)\n case \"${2:-}\" in\n low|medium|high|xhigh|max) EFFORT=\"$2\"; shift 2 ;;\n *) echo \"lcclaude: invalid effort level '${2:-}'. Use: low medium high xhigh max\" >&2; exit 1 ;;\n esac\n ;;\n --) shift; break ;;\n *) break ;;\n esac\ndone\n\n# Surface the other model in the /model picker.\nif [ \"$MAIN_MODEL\" = \"$PRO_MODEL\" ]; then\n OTHER_MODEL=\"$FLASH_MODEL\"\n OTHER_DESC=\"LongCat Flash Chat — fast / cheap tier\"\nelif [ \"$MAIN_MODEL\" = \"$FLASH_MODEL\" ]; then\n OTHER_MODEL=\"$PRO_MODEL\"\n OTHER_DESC=\"LongCat 2.0 — flagship reasoning\"\nelse\n OTHER_MODEL=\"$PRO_MODEL\"\n OTHER_DESC=\"LongCat 2.0 — flagship reasoning\"\nfi\n\nexport_anthropic_base\nexport CLAUDE_CODE_SUBAGENT_MODEL=\"$FLASH_MODEL\"\nset_custom_model \"$OTHER_MODEL\" \"$MAIN_MODEL\" \"$OTHER_DESC\"\n\nCTX=\"${LONGCAT_CTX:-}\"\nOUTPUT_CAP=\"${LONGCAT_OUTPUT:-}\"\napply_context_and_effort\n\nshow_banner_and_launch \"LongCat\" \"$@\"\n"}}, "lcclaude-desktop": {"c07db31916dca8077b9124f5c098258f9607b016": {"t": 1785674295.3671978, "n": 5919, "h": "f09c747bcb1a2087", "c": "#!/usr/bin/env bash\n# lcclaude-desktop — configure Claude Desktop to use Meituan LongCat as inference backend.\n#\n# Edits ~/Library/Application Support/Claude-3p/configLibrary/{_meta,}.json\n# and restarts Claude Desktop. macOS only.\n#\n# Usage:\n# lcclaude-desktop # configure to LongCat-2.0 and restart\n# lcclaude-desktop update # git pull latest from the repo\n# lcclaude-desktop -h # help\n#\n# Reads LONGCAT_API_KEY from env or ~/.zshrc & friends (else prompts). The base URL\n# defaults to https://api.longcat.chat/anthropic; override with LONGCAT_BASE_URL.\n#\n# Get your free API key (public beta — 500K tokens/day free):\n# https://longcat.chat/platform\n#\n# Note: Once a third-party gateway is active, Claude Desktop's Chat mode is\n# unavailable — only Cowork (3P) and Code modes work.\n\nset -euo pipefail\n\nCONFIG_DIR=\"$HOME/Library/Application Support/Claude-3p/configLibrary\"\nMETA=\"$CONFIG_DIR/_meta.json\"\nENTRY_NAME=\"lcclaude-desktop\"\nAUTH_SCHEME=\"bearer\"\nMAIN_MODEL=\"LongCat-2.0\"\nFAST_MODEL=\"LongCat-Flash-Chat\"\nBASE_URL=\"${LONGCAT_BASE_URL:-https://api.longcat.chat/anthropic}\"\n\nwhile [[ $# -gt 0 ]]; do\n case \"$1\" in\n -h|--help)\n sed -n '2,20p' \"$0\" | sed 's/^# \\{0,1\\}//'\n exit 0\n ;;\n update)\n SELF_DIR=\"$(cd \"$(dirname \"$0\")\" && pwd)\"\n echo \"lcclaude-desktop: pulling latest from $SELF_DIR ...\"\n git -C \"$SELF_DIR\" pull && echo \"lcclaude-desktop: updated.\" || {\n echo \"lcclaude-desktop: git pull failed. Check network or resolve conflicts manually.\" >&2\n exit 1\n }\n exit 0\n ;;\n *)\n echo \"lcclaude-desktop: unknown argument: $1\" >&2\n echo \"Run 'lcclaude-desktop -h' for usage.\" >&2\n exit 2\n ;;\n esac\ndone\n\npreflight() {\n if [[ \"$(uname)\" != \"Darwin\" ]]; then\n echo \"lcclaude-desktop: macOS only.\" >&2\n exit 1\n fi\n if [[ ! -d \"/Applications/Claude.app\" ]]; then\n echo \"lcclaude-desktop: /Applications/Claude.app not found. Install from https://claude.ai/download.\" >&2\n exit 1\n fi\n if [[ ! -x \"/usr/bin/jq\" ]]; then\n echo \"lcclaude-desktop: /usr/bin/jq not found (required on macOS Sonoma+).\" >&2\n exit 1\n fi\n\n local dev_settings=\"$HOME/Library/Application Support/Claude/developer_settings.json\"\n if [[ ! -f \"$dev_settings\" ]] \\\n || ! /usr/bin/jq -e '.allowDevTools == true' \"$dev_settings\" >/dev/null 2>&1; then\n cat >&2 <<'EOF'\nlcclaude-desktop: Developer Mode not enabled in Claude Desktop.\n\nEnable it once in the GUI:\n 1. Open Claude Desktop\n 2. Help → Troubleshooting → Enable Developer Mode\n 3. Re-run lcclaude-desktop\nEOF\n exit 1\n fi\n}\n\nresolve_api_key() {\n if [[ -n \"${LONGCAT_API_KEY:-}\" ]]; then\n printf '%s' \"$LONGCAT_API_KEY\"\n return 0\n fi\n local rc found=\"\"\n for rc in \"$HOME/.zshrc\" \"$HOME/.bashrc\" \"$HOME/.bash_profile\" \"$HOME/.profile\"; do\n [[ -r \"$rc\" ]] || continue\n found=\"$(grep -v '^[[:space:]]*#' \"$rc\" 2>/dev/null \\\n | grep -E '^[[:space:]]*export[[:space:]]+LONGCAT_API_KEY=' \\\n | tail -1 \\\n | sed -E 's/^[^=]*=//; s/^\"(.*)\"$/\\1/; s/^'\\''(.*)'\\''$/\\1/' \\\n || true)\"\n if [[ -n \"$found\" ]]; then\n printf '%s' \"$found\"\n return 0\n fi\n done\n local key\n key=\"$(osascript <<'APPLESCRIPT' 2>/dev/null || true\ntry\n set theKey to text returned of (display dialog ¬\n \"LongCat API Key not found in env or shell rc.\\nPaste your LongCat API Key:\" ¬\n default answer \"\" ¬\n with hidden answer ¬\n with title \"lcclaude-desktop\")\n return theKey\non error\n return \"\"\nend try\nAPPLESCRIPT\n)\"\n if [[ -z \"$key\" ]]; then\n echo \"lcclaude-desktop: no LongCat API Key provided. Aborting.\" >&2\n exit 1\n fi\n printf '%s' \"$key\"\n}\n\nconfirm_or_abort() {\n echo\n echo \"About to: $1\"\n echo \"Press Enter to continue, Ctrl-C to abort.\"\n read -r _\n}\n\nwrite_entry() {\n local uuid=\"$1\"\n local entry_path=\"$CONFIG_DIR/${uuid}.json\"\n local tmp=\"${entry_path}.tmp\"\n local content\n content=\"$(jq -n \\\n --arg baseUrl \"$BASE_URL\" \\\n --arg apiKey \"$LC_KEY\" \\\n --arg auth \"$AUTH_SCHEME\" \\\n --arg main \"$MAIN_MODEL\" \\\n --arg fast \"$FAST_MODEL\" \\\n '{\n inferenceProvider: \"gateway\",\n inferenceGatewayBaseUrl: $baseUrl,\n inferenceGatewayApiKey: $apiKey,\n inferenceGatewayAuthScheme: $auth,\n unstableDisableModelVerification: true,\n inferenceModels: [\n {name: $main, supports1m: false},\n {name: $fast, supports1m: false}\n ]\n }')\"\n printf '%s' \"$content\" > \"$tmp\"\n chmod 600 \"$tmp\"\n mv \"$tmp\" \"$entry_path\"\n}\n\nensure_meta_entry() {\n mkdir -p \"$CONFIG_DIR\"\n local existing_uuid=\"\"\n if [[ -f \"$META\" ]]; then\n existing_uuid=\"$(jq -r --arg name \"$ENTRY_NAME\" \\\n '.entries[]? | select(.name==$name) | .id' \"$META\" 2>/dev/null \\\n | head -1)\"\n fi\n local uuid\n if [[ -n \"$existing_uuid\" ]]; then\n uuid=\"$existing_uuid\"\n else\n uuid=\"$(uuidgen | tr 'A-Z' 'a-z')\"\n fi\n local tmp=\"${META}.tmp\"\n local content\n if [[ -f \"$META\" ]]; then\n content=\"$(jq --arg id \"$uuid\" --arg name \"$ENTRY_NAME\" '\n .appliedId = $id\n | .entries = ((.entries // []) | map(select(.name != $name)) + [{id: $id, name: $name}])\n ' \"$META\")\"\n else\n content=\"$(jq -n --arg id \"$uuid\" --arg name \"$ENTRY_NAME\" \\\n '{appliedId: $id, entries: [{id: $id, name: $name}]}')\"\n fi\n printf '%s' \"$content\" > \"$tmp\"\n chmod 600 \"$tmp\"\n mv \"$tmp\" \"$META\"\n printf '%s' \"$uuid\"\n}\n\nrestart_claude() {\n killall Claude 2>/dev/null || true\n sleep 1\n open -a Claude\n}\n\npreflight\nLC_KEY=\"$(resolve_api_key)\"\nconfirm_or_abort \"configure Claude Desktop to use Meituan LongCat ($BASE_URL) and restart it.\"\nUUID=\"$(ensure_meta_entry)\"\nwrite_entry \"$UUID\"\nrestart_claude\n\ncat <<'EOF'\n\nDone. Claude Desktop is restarting with Meituan LongCat as the inference backend.\n\nHeads up: Chat mode is unavailable while a third-party gateway is active.\nRe-run lcclaude-desktop any time to refresh the gateway config.\nEOF\n"}}, "lcclaude.ps1": {"c07db31916dca8077b9124f5c098258f9607b016": {"t": 1785674295.8456082, "n": 7939, "h": "7aa1c9086ff26528", "c": "#!/usr/bin/env pwsh\n# lcclaude.ps1 — launch Claude Code on Meituan LongCat's Anthropic-compatible API (Windows port).\n#\n# Windows companion to the macOS/Linux bash script `lcclaude`. Same env vars,\n# same model picker — different shell.\n#\n# Uses the official LongCat Anthropic-compatible endpoint:\n# https://api.longcat.chat/anthropic\n#\n# Reads LONGCAT_API_KEY from the process env first, then User/Machine env vars.\n#\n# Quick start (from the lcclaude directory):\n# pwsh -File .\\lcclaude.ps1\n#\n# Three invocation rules that matter on Windows:\n# 1. Use `pwsh`, not `powershell`.\n# 2. Use `-File`, not `-Command` / `&`.\n# 3. Allow local scripts to run (one-time):\n# Set-ExecutionPolicy -Scope CurrentUser RemoteSigned\n#\n# Use:\n# pwsh -File ./lcclaude.ps1 # LongCat-2.0 (flagship)\n# pwsh -File ./lcclaude.ps1 fast # LongCat-Flash-Chat\n# pwsh -File ./lcclaude.ps1 think # LongCat-Flash-Thinking\n# pwsh -File ./lcclaude.ps1 long # request 1M context window\n# pwsh -File ./lcclaude.ps1 effort max # set effort (low|medium|high|xhigh|max)\n# pwsh -File ./lcclaude.ps1 update # git pull\n# pwsh -File ./lcclaude.ps1 --help # forwarded to claude\n#\n# Optional env overrides:\n# $env:LONGCAT_MODEL = 'LongCat-2.0' # main model\n# $env:LONGCAT_FLASH_MODEL = 'LongCat-Flash-Chat' # flash tier\n# $env:LONGCAT_BASE_URL = 'https://.../anthropic'\n# $env:LONGCAT_CTX = '1048576' # max context tokens\n# $env:LONGCAT_OUTPUT = '8000' # cap output tokens\n# $env:LONGCAT_EFFORT = 'max' # CLAUDE_CODE_EFFORT_LEVEL\n#\n# In-session switch:\n# /model LongCat-Flash-Chat # fast tier\n# /model LongCat-Flash-Thinking # thinking tier\n# /model LongCat-2.0 # flagship\n#\n# Get your free API key: https://longcat.chat/platform\n\n[CmdletBinding()]\nparam(\n [Parameter(ValueFromRemainingArguments = $true)]\n [string[]]$Rest\n)\n\n$ErrorActionPreference = 'Stop'\n\nif ($PSVersionTable.PSVersion.Major -lt 7) {\n Write-Error @\"\nlcclaude.ps1: PowerShell 7+ required (you're on $($PSVersionTable.PSVersion)).\n\nWindows PowerShell 5.1 cannot host claude's interactive UI.\nInstall PowerShell 7 once:\n\n winget install Microsoft.PowerShell\n\nThen re-run with:\n\n pwsh -File .\\lcclaude.ps1\n\"@\n exit 1\n}\n\n# ---- Self-update -----------------------------------------------------------\n\nfunction Invoke-LcclaudeUpdate {\n $repo = $null\n $selfDir = Split-Path -Parent $PSCommandPath\n if (Test-Path (Join-Path $selfDir '.git')) { $repo = $selfDir }\n if (-not $repo -and $env:LCCLAUDE_HOME) { $repo = $env:LCCLAUDE_HOME }\n if (-not $repo) {\n $candidate = Join-Path $env:USERPROFILE 'github\\xxclaude'\n if (Test-Path (Join-Path $candidate '.git')) { $repo = $candidate }\n }\n if (-not $repo) {\n Write-Error @'\nlcclaude: cannot find the xxclaude repo for self-update.\n Set $env:LCCLAUDE_HOME = 'C:\\path\\to\\xxclaude' or cd into the repo and run pwsh -File ./lcclaude.ps1 update\n'@\n exit 1\n }\n Write-Host \"lcclaude: pulling latest from $repo ...\"\n git -C $repo pull\n if ($LASTEXITCODE -ne 0) {\n Write-Error 'lcclaude: git pull failed. Check network or resolve conflicts manually.'\n exit 1\n }\n Write-Host 'lcclaude: updated.'\n exit 0\n}\n\n# ---- API key resolution ----------------------------------------------------\n\nfunction Resolve-ApiKey {\n if ($env:LONGCAT_API_KEY) { return $env:LONGCAT_API_KEY }\n foreach ($scope in 'User', 'Machine') {\n $v = [Environment]::GetEnvironmentVariable('LONGCAT_API_KEY', $scope)\n if ($v) { return $v }\n }\n Write-Error @'\nLONGCAT_API_KEY not found.\n Set it persistently (User scope, takes effect in new shells):\n setx LONGCAT_API_KEY \"lc-xxxxxxxxxxxxxxxxxx\"\n Or for the current shell only:\n $env:LONGCAT_API_KEY = 'lc-xxxxxxxxxxxxxxxxxx'\n Get your free key at: https://longcat.chat/platform\n'@\n exit 1\n}\n\n# ---- Arg parsing -----------------------------------------------------------\n\n$mainModel = $null\n$LongCtx = $false\n$Effort = if ($env:LONGCAT_EFFORT) { $env:LONGCAT_EFFORT } else { '' }\n\n$remaining = @()\n$rest = @($Rest)\n$i = 0\n:argloop while ($i -lt $rest.Count) {\n $a = $rest[$i]\n switch -CaseSensitive ($a) {\n 'update' { Invoke-LcclaudeUpdate }\n 'fast' { $mainModel = 'LongCat-Flash-Chat'; $i++; break }\n 'flash' { $mainModel = 'LongCat-Flash-Chat'; $i++; break }\n 'think' { $mainModel = 'LongCat-Flash-Thinking'; $i++; break }\n 'long' { $LongCtx = $true; $i++; break }\n 'effort' {\n $i++; if ($i -lt $rest.Count) { $l=$rest[$i]; if ($l -in 'low','medium','high','xhigh','max'){$Effort=$l;$i++;break}else{Write-Error \"lcclaude: invalid effort level '$l'. Use: low medium high xhigh max\";exit 1}}else{Write-Error \"lcclaude: 'effort' requires a level: low medium high xhigh max\";exit 1}\n }\n '--' {\n $i++\n if ($i -lt $rest.Count) { $remaining += $rest[$i..($rest.Count - 1)] }\n break argloop\n }\n default {\n $remaining += $rest[$i..($rest.Count - 1)]\n break argloop\n }\n }\n}\n\n$apiKey = Resolve-ApiKey\n\n$baseUrl = if ($env:LONGCAT_BASE_URL) { $env:LONGCAT_BASE_URL } else { 'https://api.longcat.chat/anthropic' }\n$proModel = if ($env:LONGCAT_MODEL) { $env:LONGCAT_MODEL } else { 'LongCat-2.0' }\n$flashModel = if ($env:LONGCAT_FLASH_MODEL) { $env:LONGCAT_FLASH_MODEL } else { 'LongCat-Flash-Chat' }\n$thinkModel = if ($env:LONGCAT_THINK_MODEL) { $env:LONGCAT_THINK_MODEL } else { 'LongCat-Flash-Thinking' }\n\nif (-not $mainModel) { $mainModel = $proModel }\n\nif ($mainModel -eq $proModel) {\n $otherModel = $flashModel\n $otherDesc = 'LongCat Flash Chat — fast / cheap tier'\n} elseif ($mainModel -eq $flashModel) {\n $otherModel = $proModel\n $otherDesc = 'LongCat 2.0 — flagship reasoning'\n} else {\n $otherModel = $proModel\n $otherDesc = 'LongCat 2.0 — flagship reasoning'\n}\n\n# ---- Export env for claude -------------------------------------------------\n\n$env:ANTHROPIC_API_KEY = $null\n\n$env:ANTHROPIC_BASE_URL = $baseUrl\n$env:ANTHROPIC_AUTH_TOKEN = $apiKey\n$env:ANTHROPIC_MODEL = $mainModel\n$env:ANTHROPIC_DEFAULT_OPUS_MODEL = $mainModel\n$env:ANTHROPIC_DEFAULT_SONNET_MODEL = $mainModel\n$env:ANTHROPIC_DEFAULT_HAIKU_MODEL = $flashModel\n$env:CLAUDE_CODE_SUBAGENT_MODEL = $flashModel\n\nif ($otherModel -ne $mainModel) {\n $env:ANTHROPIC_CUSTOM_MODEL_OPTION = $otherModel\n $env:ANTHROPIC_CUSTOM_MODEL_OPTION_NAME = $otherModel\n $env:ANTHROPIC_CUSTOM_MODEL_OPTION_DESCRIPTION = $otherDesc\n}\n\n# ---- Effort level ----------------------------------------------------------\nif ($Effort) { $env:CLAUDE_CODE_EFFORT_LEVEL = $Effort }\n# ---- Context window --------------------------------------------------------\n$ctx = if ($env:LONGCAT_CTX) { $env:LONGCAT_CTX } elseif ($LongCtx) { '1048576' } else { '' }\nif ($ctx) { $env:CLAUDE_CODE_MAX_CONTEXT_TOKENS = $ctx; $env:DISABLE_COMPACT = '1' }\n# ---- Output cap ------------------------------------------------------------\nif ($env:LONGCAT_OUTPUT) { $env:CLAUDE_CODE_MAX_OUTPUT_TOKENS = $env:LONGCAT_OUTPUT }\n\n# ---- Launch ----------------------------------------------------------------\n\nif (-not (Get-Command claude -ErrorAction SilentlyContinue)) {\n Write-Error @'\nlcclaude: `claude` CLI not found on PATH.\n Install Claude Code: npm install -g @anthropic-ai/claude-code\n Then re-run this script.\n'@\n exit 1\n}\n\n$banner = \"🚀 Claude Code on LongCat → $mainModel ($baseUrl)\"\nif ($ctx) { $banner += \" | ctx=$ctx\" }\nif ($Effort) { $banner += \" | effort=$Effort\" }\nif ($otherModel -ne $mainModel) { $banner += ' (switch mid-session via /model)' }\nWrite-Host $banner\n\n& claude @remaining\nexit $LASTEXITCODE\n"}}, "lcclaude-desktop.ps1": {"c07db31916dca8077b9124f5c098258f9607b016": {"t": 1785674297.4378116, "n": 8643, "h": "dd5b3cfe45637e15", "c": "#!/usr/bin/env pwsh\n# lcclaude-desktop.ps1 — configure Claude Desktop to use Meituan LongCat (Windows port).\n#\n# Usage:\n# pwsh ./lcclaude-desktop.ps1 # auto-detect and configure\n# pwsh ./lcclaude-desktop.ps1 -ClaudeExePath # specify custom Claude.exe\n# pwsh ./lcclaude-desktop.ps1 -Update # git pull\n# pwsh ./lcclaude-desktop.ps1 -h # help\n#\n# Reads LONGCAT_API_KEY from env (else prompts). Base URL defaults to\n# https://api.longcat.chat/anthropic; override with $env:LONGCAT_BASE_URL.\n#\n# Get your free API key: https://longcat.chat/platform\n\n[CmdletBinding()]\nparam(\n [Alias('h')][switch]$Help,\n [switch]$Update,\n [string]$ClaudeExePath\n)\n\n$ErrorActionPreference = 'Stop'\n\n$ConfigDir = Join-Path $env:LOCALAPPDATA 'Claude-3p\\configLibrary'\n$Meta = Join-Path $ConfigDir '_meta.json'\n$StoreDir = if (Get-ChildItem \"$env:LOCALAPPDATA\\Packages\\Claude_*\" -ErrorAction SilentlyContinue) {\n Join-Path (Resolve-Path \"$env:LOCALAPPDATA\\Packages\\Claude_*\") 'LocalCache\\Roaming\\Claude-3p\\configLibrary'\n } else { $null }\n$EntryName = 'lcclaude-desktop'\n$AuthScheme = 'bearer'\n$MainModel = 'LongCat-2.0'\n$FastModel = 'LongCat-Flash-Chat'\n$BaseUrl = if ($env:LONGCAT_BASE_URL) { $env:LONGCAT_BASE_URL } else { 'https://api.longcat.chat/anthropic' }\n\n$ClaudeExe = $null\n\nif ($Help) {\n Get-Content $PSCommandPath | Select-Object -Skip 1 -First 15 |\n ForEach-Object { $_ -replace '^# ?', '' }\n exit 0\n}\n\nif ($Update) {\n $repo = Split-Path -Parent $PSCommandPath\n Write-Host \"lcclaude-desktop: pulling latest from $repo ...\"\n git -C $repo pull\n if ($LASTEXITCODE -eq 0) { Write-Host 'lcclaude-desktop: updated.' }\n else { Write-Error 'lcclaude-desktop: git pull failed.'; exit 1 }\n exit 0\n}\n\n# ---- Pre-flight ------------------------------------------------------------\n\nfunction Test-Preflight {\n $isWin = if ($null -ne $IsWindows) { $IsWindows } else { $true }\n if (-not $isWin) {\n Write-Error 'lcclaude-desktop.ps1: Windows only. Use ./lcclaude-desktop on macOS.'\n exit 1\n }\n\n if ($script:ClaudeExePath) {\n if (-not (Test-Path $script:ClaudeExePath)) {\n Write-Error \"lcclaude-desktop.ps1: Claude.exe not found at '$script:ClaudeExePath'\"\n exit 1\n }\n $script:ClaudeExe = $script:ClaudeExePath\n } else {\n $candidates = @()\n $pkg = Get-AppxPackage -Name 'Claude*' -ErrorAction SilentlyContinue | Select-Object -First 1\n if ($pkg) { $candidates += Join-Path $pkg.InstallLocation 'app\\claude.exe' }\n\n $packagesBase = Join-Path $env:LOCALAPPDATA 'Packages'\n if (Test-Path $packagesBase) {\n $candidates += Get-ChildItem -Path $packagesBase -Directory -Filter 'Claude_*' -ErrorAction SilentlyContinue |\n ForEach-Object { Join-Path $_.FullName 'LocalCache\\Local\\Claude-3p\\claude-code\\*\\claude.exe' } |\n ForEach-Object { Get-ChildItem -Path $_ -ErrorAction SilentlyContinue } |\n Select-Object -ExpandProperty FullName\n }\n $candidates += @(\n (Join-Path $env:LOCALAPPDATA 'AnthropicClaude\\Claude.exe'),\n (Join-Path $env:LOCALAPPDATA 'Programs\\AnthropicClaude\\Claude.exe'),\n (Join-Path ${env:ProgramFiles} 'AnthropicClaude\\Claude.exe'),\n (Join-Path ${env:ProgramFiles(x86)} 'AnthropicClaude\\Claude.exe')\n )\n $found = $candidates | Where-Object { Test-Path $_ } | Select-Object -First 1\n if (-not $found) {\n Write-Error \"lcclaude-desktop.ps1: Claude Desktop not found. Install from https://claude.ai/download\"\n exit 1\n }\n $script:ClaudeExe = $found\n }\n\n $devSettings = Join-Path $env:APPDATA 'Claude\\developer_settings.json'\n $devDir = Split-Path $devSettings -Parent\n $needsEnable = $false\n if (Test-Path $devSettings) {\n $dev = Get-Content $devSettings -Raw | ConvertFrom-Json\n if (-not $dev.allowDevTools) { $needsEnable = $true }\n } else { $needsEnable = $true }\n if ($needsEnable) {\n Write-Host 'lcclaude-desktop.ps1: Enabling Developer Mode for Claude Desktop...'\n if (-not (Test-Path $devDir)) { New-Item -ItemType Directory -Path $devDir -Force | Out-Null }\n $devContent = '{ \"allowDevTools\": true }'\n [System.IO.File]::WriteAllText($devSettings, $devContent, [System.Text.UTF8Encoding]::new($false))\n Write-Host 'lcclaude-desktop.ps1: Developer Mode enabled.'\n }\n}\n\n# ---- API key resolution ----------------------------------------------------\n\nfunction Resolve-ApiKey {\n if ($env:LONGCAT_API_KEY) { return $env:LONGCAT_API_KEY }\n foreach ($scope in 'User', 'Machine') {\n $v = [Environment]::GetEnvironmentVariable('LONGCAT_API_KEY', $scope)\n if ($v) { return $v }\n }\n $secure = Read-Host 'LONGCAT_API_KEY not set. Paste your LongCat API Key' -AsSecureString\n if (-not $secure -or $secure.Length -eq 0) {\n Write-Error 'lcclaude-desktop.ps1: no LongCat API Key provided. Aborting.'\n exit 1\n }\n $bstr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($secure)\n try { return [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($bstr) }\n finally { [System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($bstr) }\n}\n\nfunction Confirm-OrAbort { param([string]$Action); Write-Host ''; Write-Host \"About to: $Action\"; [void](Read-Host 'Press Enter to continue, Ctrl-C to abort') }\n\nfunction Write-JsonAtomic {\n param([string]$Path, $Object)\n $json = $Object | ConvertTo-Json -Depth 6\n $json = $json.TrimEnd(\"`r\", \"`n\")\n $tmp = \"$Path.tmp\"\n [System.IO.File]::WriteAllText($tmp, $json, [System.Text.UTF8Encoding]::new($false))\n Move-Item -Path $tmp -Destination $Path -Force\n}\n\nfunction Update-MetaEntry {\n $dirs = @($script:ConfigDir) + @(if ($script:StoreDir) { $script:StoreDir } else { @() })\n foreach ($d in $dirs) { if (-not (Test-Path $d)) { New-Item -ItemType Directory -Path $d -Force | Out-Null } }\n $existingUuid = $null\n $metaPath = Join-Path $dirs[0] '_meta.json'\n if (Test-Path $metaPath) {\n $existing = Get-Content $metaPath -Raw | ConvertFrom-Json\n $existingUuid = ($existing.entries | Where-Object { $_.name -eq $script:EntryName } | Select-Object -First 1).id\n }\n $uuid = if ($existingUuid) { $existingUuid } else { [guid]::NewGuid().ToString().ToLower() }\n $entries = @()\n if (Test-Path $metaPath) {\n $existing = Get-Content $metaPath -Raw | ConvertFrom-Json\n $entries = @($existing.entries | Where-Object { $_.name -ne $script:EntryName })\n }\n $entries += [pscustomobject]@{ id = $uuid; name = $script:EntryName }\n $newMeta = [ordered]@{ appliedId = $uuid; entries = @($entries) }\n foreach ($d in $dirs) { Write-JsonAtomic -Path (Join-Path $d '_meta.json') -Object $newMeta }\n return $uuid\n}\n\nfunction Write-Entry {\n param([string]$Uuid, [string]$ApiKey)\n $entry = [ordered]@{\n inferenceProvider = 'gateway'\n inferenceGatewayBaseUrl = $script:BaseUrl\n inferenceGatewayApiKey = $ApiKey\n inferenceGatewayAuthScheme = $AuthScheme\n unstableDisableModelVerification = $true\n inferenceModels = @(\n [ordered]@{ name = $MainModel; supports1m = $false },\n [ordered]@{ name = $FastModel; supports1m = $false }\n )\n }\n $dirs = @($script:ConfigDir) + @(if ($script:StoreDir) { $script:StoreDir } else { @() })\n foreach ($d in $dirs) { Write-JsonAtomic -Path (Join-Path $d \"$Uuid.json\") -Object $entry }\n}\n\nfunction Restart-Claude {\n Get-CimInstance Win32_Process -Filter \"Name='claude.exe'\" -ErrorAction SilentlyContinue |\n Where-Object { $_.CommandLine -like \"*$($script:ClaudeExe)*\" } |\n ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }\n Start-Sleep -Seconds 1\n Start-Process -FilePath $script:ClaudeExe\n}\n\n# ---- Main ------------------------------------------------------------------\n\nTest-Preflight\n$apiKey = Resolve-ApiKey\nConfirm-OrAbort -Action \"configure Claude Desktop to use Meituan LongCat ($script:BaseUrl) and restart it.\"\n$uuid = Update-MetaEntry\nWrite-Entry -Uuid $uuid -ApiKey $apiKey\nRestart-Claude\n\n@\"\n\nDone. Claude Desktop is restarting with Meituan LongCat as the inference backend.\n\nHeads up: Chat mode is unavailable while a third-party gateway is active.\nRe-run lcclaude-desktop.ps1 any time to refresh the gateway config.\n\"@ | Write-Host\n"}}, "install.sh": {"c07db31916dca8077b9124f5c098258f9607b016": {"t": 1785745936.9618356, "n": 3613, "h": "552c7ddbbfeb270d", "c": "#!/usr/bin/env bash\n# install.sh — one-command installer for dsclaude launchers.\n#\n# Usage:\n# curl -fsSL https://raw.githubusercontent.com/Agents365-ai/dsclaude/main/install.sh | bash\n#\n# # Or, if you already have the repo:\n# ./install.sh\n#\n# # Install to ~/.local/bin instead of /usr/local/bin:\n# curl ... | bash -s -- --user\n#\n# # Custom install directory:\n# ./install.sh --prefix /opt/bin\n#\nset -euo pipefail\n\nPREFIX=\"\"\nREPO_URL=\"https://github.com/Agents365-ai/dsclaude.git\"\nTMP_DIR=\"\"\n\ncleanup() { [ -n \"${TMP_DIR:-}\" ] && rm -rf \"$TMP_DIR\"; }\ntrap cleanup EXIT\n\n# ---- Parse args ------------------------------------------------------------\nwhile [ $# -gt 0 ]; do\n case \"$1\" in\n --user) PREFIX=\"$HOME/.local/bin\" ;;\n --prefix) PREFIX=\"$2\"; shift ;;\n *) echo \"install.sh: unknown option: $1\" >&2; exit 1 ;;\n esac\n shift\ndone\n\n# ---- Resolve install directory ---------------------------------------------\nif [ -z \"$PREFIX\" ]; then\n if [ -w /usr/local/bin ]; then\n PREFIX=\"/usr/local/bin\"\n elif [ \"$(id -u)\" = \"0\" ]; then\n PREFIX=\"/usr/local/bin\"\n else\n echo \"install.sh: /usr/local/bin is not writable. Options:\"\n echo \" • Run with sudo: curl ... | sudo bash\"\n echo \" • User install: curl ... | bash -s -- --user\"\n exit 1\n fi\nfi\n\nmkdir -p \"$PREFIX\"\n\necho \"install.sh: installing to $PREFIX\"\n\n# ---- Get the scripts -------------------------------------------------------\nREPO_DIR=\"\"\n# If we're already inside a repo clone, use it directly.\nself_dir=\"$(cd \"$(dirname \"$0\")\" 2>/dev/null && pwd || true)\"\nif [ -n \"${self_dir:-}\" ] && [ -f \"$self_dir/dsclaude\" ] && [ -d \"$self_dir/.git\" ]; then\n REPO_DIR=\"$self_dir\"\n echo \"install.sh: using local repo at $REPO_DIR\"\nelse\n TMP_DIR=\"$(mktemp -d -t dsclaude-install.XXXXXX)\"\n echo \"install.sh: cloning $REPO_URL ...\"\n git clone --depth 1 \"$REPO_URL\" \"$TMP_DIR\" >/dev/null 2>&1 || {\n echo \"install.sh: git clone failed. Check your network or install git.\" >&2\n exit 1\n }\n REPO_DIR=\"$TMP_DIR\"\nfi\n\n# ---- Install shared library --------------------------------------------------\necho \"install.sh: installing shared library...\"\nmkdir -p \"$PREFIX/lib\"\ncp \"$REPO_DIR/lib/common.sh\" \"$PREFIX/lib/common.sh\"\nchmod +x \"$PREFIX/lib/common.sh\"\n\n# ---- Install CLI launchers (no extension) ----------------------------------\ncount=0\necho \"install.sh: installing CLI launchers...\"\nfor script in \"$REPO_DIR\"/*claude; do\n name=\"$(basename \"$script\")\"\n # Skip .ps1 files and desktop configurators.\n case \"$name\" in\n *.ps1|*-desktop) continue ;;\n esac\n # Skip non-files.\n [ ! -f \"$script\" ] && continue\n cp \"$script\" \"$PREFIX/$name\"\n chmod +x \"$PREFIX/$name\"\n echo \" $name\"\n count=$((count + 1))\ndone\n\n# ---- Install desktop configurators -----------------------------------------\necho \"install.sh: installing desktop configurators...\"\nfor script in \"$REPO_DIR\"/*-desktop; do\n name=\"$(basename \"$script\")\"\n [ ! -f \"$script\" ] && continue\n cp \"$script\" \"$PREFIX/$name\"\n chmod +x \"$PREFIX/$name\"\n echo \" $name\"\n count=$((count + 1))\ndone\n\necho \"\"\necho \"✓ Installed $count scripts to $PREFIX\"\n\n# ---- PATH reminder ----------------------------------------------------------\nif [ \"$PREFIX\" = \"$HOME/.local/bin\" ]; then\n if ! echo \"$PATH\" | tr ':' '\\n' | grep -qFx \"$PREFIX\"; then\n echo \"\"\n echo \"⚠️ $PREFIX is not in your PATH. Add this to your ~/.zshrc or ~/.bashrc:\"\n echo \" export PATH=\\\"\\$HOME/.local/bin:\\$PATH\\\"\"\n fi\nfi\n\necho \"\"\necho \"Now set an API key and run xclaude (auto-detect) or any launcher directly:\"\necho \" export DEEPSEEK_API_KEY=sk-...\"\necho \" xclaude\"\n"}, "a8b31904f7f4db6cf2d9821361c59048c9e26687": {"t": 1785758056.182733, "n": 3613, "h": "552c7ddbbfeb270d", "c": "#!/usr/bin/env bash\n# install.sh — one-command installer for dsclaude launchers.\n#\n# Usage:\n# curl -fsSL https://raw.githubusercontent.com/Agents365-ai/dsclaude/main/install.sh | bash\n#\n# # Or, if you already have the repo:\n# ./install.sh\n#\n# # Install to ~/.local/bin instead of /usr/local/bin:\n# curl ... | bash -s -- --user\n#\n# # Custom install directory:\n# ./install.sh --prefix /opt/bin\n#\nset -euo pipefail\n\nPREFIX=\"\"\nREPO_URL=\"https://github.com/Agents365-ai/dsclaude.git\"\nTMP_DIR=\"\"\n\ncleanup() { [ -n \"${TMP_DIR:-}\" ] && rm -rf \"$TMP_DIR\"; }\ntrap cleanup EXIT\n\n# ---- Parse args ------------------------------------------------------------\nwhile [ $# -gt 0 ]; do\n case \"$1\" in\n --user) PREFIX=\"$HOME/.local/bin\" ;;\n --prefix) PREFIX=\"$2\"; shift ;;\n *) echo \"install.sh: unknown option: $1\" >&2; exit 1 ;;\n esac\n shift\ndone\n\n# ---- Resolve install directory ---------------------------------------------\nif [ -z \"$PREFIX\" ]; then\n if [ -w /usr/local/bin ]; then\n PREFIX=\"/usr/local/bin\"\n elif [ \"$(id -u)\" = \"0\" ]; then\n PREFIX=\"/usr/local/bin\"\n else\n echo \"install.sh: /usr/local/bin is not writable. Options:\"\n echo \" • Run with sudo: curl ... | sudo bash\"\n echo \" • User install: curl ... | bash -s -- --user\"\n exit 1\n fi\nfi\n\nmkdir -p \"$PREFIX\"\n\necho \"install.sh: installing to $PREFIX\"\n\n# ---- Get the scripts -------------------------------------------------------\nREPO_DIR=\"\"\n# If we're already inside a repo clone, use it directly.\nself_dir=\"$(cd \"$(dirname \"$0\")\" 2>/dev/null && pwd || true)\"\nif [ -n \"${self_dir:-}\" ] && [ -f \"$self_dir/dsclaude\" ] && [ -d \"$self_dir/.git\" ]; then\n REPO_DIR=\"$self_dir\"\n echo \"install.sh: using local repo at $REPO_DIR\"\nelse\n TMP_DIR=\"$(mktemp -d -t dsclaude-install.XXXXXX)\"\n echo \"install.sh: cloning $REPO_URL ...\"\n git clone --depth 1 \"$REPO_URL\" \"$TMP_DIR\" >/dev/null 2>&1 || {\n echo \"install.sh: git clone failed. Check your network or install git.\" >&2\n exit 1\n }\n REPO_DIR=\"$TMP_DIR\"\nfi\n\n# ---- Install shared library --------------------------------------------------\necho \"install.sh: installing shared library...\"\nmkdir -p \"$PREFIX/lib\"\ncp \"$REPO_DIR/lib/common.sh\" \"$PREFIX/lib/common.sh\"\nchmod +x \"$PREFIX/lib/common.sh\"\n\n# ---- Install CLI launchers (no extension) ----------------------------------\ncount=0\necho \"install.sh: installing CLI launchers...\"\nfor script in \"$REPO_DIR\"/*claude; do\n name=\"$(basename \"$script\")\"\n # Skip .ps1 files and desktop configurators.\n case \"$name\" in\n *.ps1|*-desktop) continue ;;\n esac\n # Skip non-files.\n [ ! -f \"$script\" ] && continue\n cp \"$script\" \"$PREFIX/$name\"\n chmod +x \"$PREFIX/$name\"\n echo \" $name\"\n count=$((count + 1))\ndone\n\n# ---- Install desktop configurators -----------------------------------------\necho \"install.sh: installing desktop configurators...\"\nfor script in \"$REPO_DIR\"/*-desktop; do\n name=\"$(basename \"$script\")\"\n [ ! -f \"$script\" ] && continue\n cp \"$script\" \"$PREFIX/$name\"\n chmod +x \"$PREFIX/$name\"\n echo \" $name\"\n count=$((count + 1))\ndone\n\necho \"\"\necho \"✓ Installed $count scripts to $PREFIX\"\n\n# ---- PATH reminder ----------------------------------------------------------\nif [ \"$PREFIX\" = \"$HOME/.local/bin\" ]; then\n if ! echo \"$PATH\" | tr ':' '\\n' | grep -qFx \"$PREFIX\"; then\n echo \"\"\n echo \"⚠️ $PREFIX is not in your PATH. Add this to your ~/.zshrc or ~/.bashrc:\"\n echo \" export PATH=\\\"\\$HOME/.local/bin:\\$PATH\\\"\"\n fi\nfi\n\necho \"\"\necho \"Now set an API key and run xclaude (auto-detect) or any launcher directly:\"\necho \" export DEEPSEEK_API_KEY=sk-...\"\necho \" xclaude\"\n"}, "2525882659f2c26f4e2221ba062878ff8234b7c3": {"t": 1785758058.1636488, "n": 3374, "h": "2e22cedcbdae5aa5", "c": "#!/usr/bin/env bash\n# install.sh — one-command installer for dsclaude launchers.\n#\n# Usage:\n# curl -fsSL https://raw.githubusercontent.com/Agents365-ai/dsclaude/main/install.sh | bash\n#\n# # Or, if you already have the repo:\n# ./install.sh\n#\n# # Install to ~/.local/bin instead of /usr/local/bin:\n# curl ... | bash -s -- --user\n#\n# # Custom install directory:\n# ./install.sh --prefix /opt/bin\n#\nset -euo pipefail\n\nPREFIX=\"\"\nREPO_URL=\"https://github.com/Agents365-ai/dsclaude.git\"\nTMP_DIR=\"\"\n\ncleanup() { [ -n \"${TMP_DIR:-}\" ] && rm -rf \"$TMP_DIR\"; }\ntrap cleanup EXIT\n\n# ---- Parse args ------------------------------------------------------------\nwhile [ $# -gt 0 ]; do\n case \"$1\" in\n --user) PREFIX=\"$HOME/.local/bin\" ;;\n --prefix) PREFIX=\"$2\"; shift ;;\n *) echo \"install.sh: unknown option: $1\" >&2; exit 1 ;;\n esac\n shift\ndone\n\n# ---- Resolve install directory ---------------------------------------------\nif [ -z \"$PREFIX\" ]; then\n if [ -w /usr/local/bin ]; then\n PREFIX=\"/usr/local/bin\"\n elif [ \"$(id -u)\" = \"0\" ]; then\n PREFIX=\"/usr/local/bin\"\n else\n echo \"install.sh: /usr/local/bin is not writable. Options:\"\n echo \" • Run with sudo: curl ... | sudo bash\"\n echo \" • User install: curl ... | bash -s -- --user\"\n exit 1\n fi\nfi\n\nmkdir -p \"$PREFIX\"\n\necho \"install.sh: installing to $PREFIX\"\n\n# ---- Get the scripts -------------------------------------------------------\nREPO_DIR=\"\"\n# If we're already inside a repo clone, use it directly.\nself_dir=\"$(cd \"$(dirname \"$0\")\" 2>/dev/null && pwd || true)\"\nif [ -n \"${self_dir:-}\" ] && [ -f \"$self_dir/dsclaude\" ] && [ -d \"$self_dir/.git\" ]; then\n REPO_DIR=\"$self_dir\"\n echo \"install.sh: using local repo at $REPO_DIR\"\nelse\n TMP_DIR=\"$(mktemp -d -t dsclaude-install.XXXXXX)\"\n echo \"install.sh: cloning $REPO_URL ...\"\n git clone --depth 1 \"$REPO_URL\" \"$TMP_DIR\" >/dev/null 2>&1 || {\n echo \"install.sh: git clone failed. Check your network or install git.\" >&2\n exit 1\n }\n REPO_DIR=\"$TMP_DIR\"\nfi\n\n# ---- Install CLI launchers (no extension) ----------------------------------\ncount=0\necho \"install.sh: installing CLI launchers...\"\nfor script in \"$REPO_DIR\"/*claude; do\n name=\"$(basename \"$script\")\"\n # Skip .ps1 files and desktop configurators.\n case \"$name\" in\n *.ps1|*-desktop) continue ;;\n esac\n # Skip non-files.\n [ ! -f \"$script\" ] && continue\n cp \"$script\" \"$PREFIX/$name\"\n chmod +x \"$PREFIX/$name\"\n echo \" $name\"\n count=$((count + 1))\ndone\n\n# ---- Install desktop configurators -----------------------------------------\necho \"install.sh: installing desktop configurators...\"\nfor script in \"$REPO_DIR\"/*-desktop; do\n name=\"$(basename \"$script\")\"\n [ ! -f \"$script\" ] && continue\n cp \"$script\" \"$PREFIX/$name\"\n chmod +x \"$PREFIX/$name\"\n echo \" $name\"\n count=$((count + 1))\ndone\n\necho \"\"\necho \"✓ Installed $count scripts to $PREFIX\"\n\n# ---- PATH reminder ----------------------------------------------------------\nif [ \"$PREFIX\" = \"$HOME/.local/bin\" ]; then\n if ! echo \"$PATH\" | tr ':' '\\n' | grep -qFx \"$PREFIX\"; then\n echo \"\"\n echo \"⚠️ $PREFIX is not in your PATH. Add this to your ~/.zshrc or ~/.bashrc:\"\n echo \" export PATH=\\\"\\$HOME/.local/bin:\\$PATH\\\"\"\n fi\nfi\n\necho \"\"\necho \"Now set an API key and run xclaude (auto-detect) or any launcher directly:\"\necho \" export DEEPSEEK_API_KEY=sk-...\"\necho \" xclaude\"\n"}, "c771390e6deb25702c6665ad8e0e4427e068b15a": {"t": 1785758060.071504, "n": 3374, "h": "fdda6b535b4645ac", "c": "#!/usr/bin/env bash\n# install.sh — one-command installer for xxclaude launchers.\n#\n# Usage:\n# curl -fsSL https://raw.githubusercontent.com/Agents365-ai/dsclaude/main/install.sh | bash\n#\n# # Or, if you already have the repo:\n# ./install.sh\n#\n# # Install to ~/.local/bin instead of /usr/local/bin:\n# curl ... | bash -s -- --user\n#\n# # Custom install directory:\n# ./install.sh --prefix /opt/bin\n#\nset -euo pipefail\n\nPREFIX=\"\"\nREPO_URL=\"https://github.com/Agents365-ai/dsclaude.git\"\nTMP_DIR=\"\"\n\ncleanup() { [ -n \"${TMP_DIR:-}\" ] && rm -rf \"$TMP_DIR\"; }\ntrap cleanup EXIT\n\n# ---- Parse args ------------------------------------------------------------\nwhile [ $# -gt 0 ]; do\n case \"$1\" in\n --user) PREFIX=\"$HOME/.local/bin\" ;;\n --prefix) PREFIX=\"$2\"; shift ;;\n *) echo \"install.sh: unknown option: $1\" >&2; exit 1 ;;\n esac\n shift\ndone\n\n# ---- Resolve install directory ---------------------------------------------\nif [ -z \"$PREFIX\" ]; then\n if [ -w /usr/local/bin ]; then\n PREFIX=\"/usr/local/bin\"\n elif [ \"$(id -u)\" = \"0\" ]; then\n PREFIX=\"/usr/local/bin\"\n else\n echo \"install.sh: /usr/local/bin is not writable. Options:\"\n echo \" • Run with sudo: curl ... | sudo bash\"\n echo \" • User install: curl ... | bash -s -- --user\"\n exit 1\n fi\nfi\n\nmkdir -p \"$PREFIX\"\n\necho \"install.sh: installing to $PREFIX\"\n\n# ---- Get the scripts -------------------------------------------------------\nREPO_DIR=\"\"\n# If we're already inside a repo clone, use it directly.\nself_dir=\"$(cd \"$(dirname \"$0\")\" 2>/dev/null && pwd || true)\"\nif [ -n \"${self_dir:-}\" ] && [ -f \"$self_dir/dsclaude\" ] && [ -d \"$self_dir/.git\" ]; then\n REPO_DIR=\"$self_dir\"\n echo \"install.sh: using local repo at $REPO_DIR\"\nelse\n TMP_DIR=\"$(mktemp -d -t dsclaude-install.XXXXXX)\"\n echo \"install.sh: cloning $REPO_URL ...\"\n git clone --depth 1 \"$REPO_URL\" \"$TMP_DIR\" >/dev/null 2>&1 || {\n echo \"install.sh: git clone failed. Check your network or install git.\" >&2\n exit 1\n }\n REPO_DIR=\"$TMP_DIR\"\nfi\n\n# ---- Install CLI launchers (no extension) ----------------------------------\ncount=0\necho \"install.sh: installing CLI launchers...\"\nfor script in \"$REPO_DIR\"/*claude; do\n name=\"$(basename \"$script\")\"\n # Skip .ps1 files and desktop configurators.\n case \"$name\" in\n *.ps1|*-desktop) continue ;;\n esac\n # Skip non-files.\n [ ! -f \"$script\" ] && continue\n cp \"$script\" \"$PREFIX/$name\"\n chmod +x \"$PREFIX/$name\"\n echo \" $name\"\n count=$((count + 1))\ndone\n\n# ---- Install desktop configurators -----------------------------------------\necho \"install.sh: installing desktop configurators...\"\nfor script in \"$REPO_DIR\"/*-desktop; do\n name=\"$(basename \"$script\")\"\n [ ! -f \"$script\" ] && continue\n cp \"$script\" \"$PREFIX/$name\"\n chmod +x \"$PREFIX/$name\"\n echo \" $name\"\n count=$((count + 1))\ndone\n\necho \"\"\necho \"✓ Installed $count scripts to $PREFIX\"\n\n# ---- PATH reminder ----------------------------------------------------------\nif [ \"$PREFIX\" = \"$HOME/.local/bin\" ]; then\n if ! echo \"$PATH\" | tr ':' '\\n' | grep -qFx \"$PREFIX\"; then\n echo \"\"\n echo \"⚠️ $PREFIX is not in your PATH. Add this to your ~/.zshrc or ~/.bashrc:\"\n echo \" export PATH=\\\"\\$HOME/.local/bin:\\$PATH\\\"\"\n fi\nfi\n\necho \"\"\necho \"Now set an API key and run xclaude (auto-detect) or any launcher directly:\"\necho \" export DEEPSEEK_API_KEY=sk-...\"\necho \" xclaude\"\n"}}, "lib/common.sh": {"c07db31916dca8077b9124f5c098258f9607b016": {"t": 1785745937.3398902, "n": 5579, "h": "14341077f29081fc", "c": "#!/usr/bin/env bash\n# lib/common.sh — shared functions sourced by all *claude launcher scripts.\n# This file is not meant to be executed directly.\n#\n# Each launcher must set this variable before sourcing this file:\n# SELF_DIR — absolute path to the directory containing the launcher script\n#\n# Before calling export_anthropic_base the launcher must set:\n# BASE_URL, API_KEY, MAIN_MODEL, FLASH_MODEL\n\n# ---- find_repo: locate the xxclaude repository checkout -----------------\n# Usage: repo=\"$(find_repo \"DSCLAUDE_HOME\")\"\nfind_repo() {\n\tlocal home_var=\"$1\"\n\tif [ -d \"$SELF_DIR/.git\" ]; then\n\t\techo \"$SELF_DIR\"\n\t\treturn 0\n\tfi\n\tif [ -n \"${!home_var:-}\" ] && [ -d \"${!home_var}/.git\" ]; then\n\t\techo \"${!home_var}\"\n\t\treturn 0\n\tfi\n\tif [ -d \"$HOME/github/xxclaude/.git\" ]; then\n\t\techo \"$HOME/github/xxclaude\"\n\t\treturn 0\n\tfi\n\techo \"\"\n}\n\n# ---- do_update: git pull latest from the repo ---------------------------\n# Usage: do_update \"dsclaude\" \"DSCLAUDE_HOME\"\ndo_update() {\n\tlocal name=\"$1\" home_var=\"$2\"\n\tlocal repo\n\trepo=\"$(find_repo \"$home_var\")\"\n\tif [ -z \"$repo\" ]; then\n\t\techo \"$name: cannot find the xxclaude repo for self-update.\" >&2\n\t\techo \" Set $home_var=/path/to/xxclaude or cd into the repo and run ./$name update\" >&2\n\t\texit 1\n\tfi\n\techo \"$name: pulling latest from $repo ...\"\n\tgit -C \"$repo\" pull && echo \"$name: updated.\" || {\n\t\techo \"$name: git pull failed. Check network or resolve conflicts manually.\" >&2\n\t\texit 1\n\t}\n\texit 0\n}\n\n# ---- extract_key_from_file: get an API key value from a shell rc file ---\n# Skips commented-out lines (starting with # after optional whitespace).\n# Usage: key=\"$(extract_key_from_file \"$HOME/.zshrc\" \"DEEPSEEK_API_KEY\")\"\nextract_key_from_file() {\n\tlocal file=\"$1\" var=\"$2\"\n\t[ -f \"$file\" ] || return 1\n\tgrep -v '^[[:space:]]*#' \"$file\" |\n\t\tgrep -E \"^[[:space:]]*(export[[:space:]]+)?${var}=\" |\n\t\ttail -n1 |\n\t\tsed -E \"s/^[[:space:]]*(export[[:space:]]+)?${var}=//\" |\n\t\tsed -E 's/^\"(.*)\"$/\\1/; s/^'\"'\"'(.*)'\"'\"'$/\\1/'\n}\n\n# ---- resolve_api_key: env var first, then shell rc files ----------------\n# Usage: API_KEY=\"$(resolve_api_key \"DEEPSEEK_API_KEY\")\"\nresolve_api_key() {\n\tlocal var=\"$1\"\n\t# 1) Already in environment\n\tif [ -n \"${!var:-}\" ]; then\n\t\tprintf '%s' \"${!var}\"\n\t\treturn 0\n\tfi\n\t# 2) Shell rc files\n\tlocal f candidate\n\tfor f in \"$HOME/.zshrc\" \"$HOME/.bashrc\" \"$HOME/.bash_profile\" \"$HOME/.profile\"; do\n\t\tcandidate=\"$(extract_key_from_file \"$f\" \"$var\" || true)\"\n\t\tif [ -n \"${candidate:-}\" ]; then\n\t\t\tprintf '%s' \"$candidate\"\n\t\t\treturn 0\n\t\tfi\n\tdone\n\t# Return 0 even when not found: callers use API_KEY=\"$(resolve_api_key ...)\"\n\t# under `set -e`, and a nonzero status would kill the launcher silently\n\t# before its friendly \"key not found\" message can print.\n\treturn 0\n}\n\n# ---- export_anthropic_base: set the common ANTHROPIC_* env vars ---------\n# Caller must set BASE_URL, API_KEY, MAIN_MODEL, FLASH_MODEL first.\nexport_anthropic_base() {\n\t# Clear lingering official Anthropic credentials before launching,\n\t# otherwise they shadow ANTHROPIC_AUTH_TOKEN and traffic hits api.anthropic.com.\n\tunset ANTHROPIC_API_KEY 2>/dev/null || true\n\n\texport ANTHROPIC_BASE_URL=\"$BASE_URL\"\n\texport ANTHROPIC_AUTH_TOKEN=\"$API_KEY\"\n\texport ANTHROPIC_MODEL=\"$MAIN_MODEL\"\n\texport ANTHROPIC_DEFAULT_OPUS_MODEL=\"$MAIN_MODEL\"\n\texport ANTHROPIC_DEFAULT_SONNET_MODEL=\"$MAIN_MODEL\"\n\texport ANTHROPIC_DEFAULT_HAIKU_MODEL=\"$FLASH_MODEL\"\n\n\t# Prevent Claude Code from pinging api.anthropic.com for non-essential\n\t# features (billing check, feature flags) — those always fail on third-\n\t# party backends and produce noisy connection-error logs.\n\texport CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1\n}\n\n# ---- check_version: handle --version / -V flag -------------------------\n# Usage: check_version \"dsclaude\" \"$@\"\n# If the first arg is --version or -V, prints version info and exits.\ncheck_version() {\n\tlocal name=\"$1\"\n\tshift\n\tif [ $# -gt 0 ] && { [ \"$1\" = \"--version\" ] || [ \"$1\" = \"-V\" ]; }; then\n\t\tlocal repo ver=\"unknown\"\n\t\trepo=\"$(find_repo \"DUMMY\" 2>/dev/null || true)\"\n\t\t[ -n \"$repo\" ] && ver=\"$(git -C \"$repo\" describe --tags --always --dirty 2>/dev/null || echo \"unknown\")\"\n\t\techo \"$name $ver\"\n\t\texit 0\n\tfi\n}\n\n# ---- set_custom_model: expose alternate model in /model picker ----------\n# Usage: set_custom_model \"$OTHER_MODEL\" \"$MAIN_MODEL\" \"$OTHER_DESC\"\nset_custom_model() {\n\tlocal other=\"$1\" main=\"$2\" desc=\"$3\"\n\tif [ \"$other\" != \"$main\" ]; then\n\t\texport ANTHROPIC_CUSTOM_MODEL_OPTION=\"$other\"\n\t\texport ANTHROPIC_CUSTOM_MODEL_OPTION_NAME=\"$other\"\n\t\texport ANTHROPIC_CUSTOM_MODEL_OPTION_DESCRIPTION=\"$desc\"\n\tfi\n}\n\n# ---- apply_context_and_effort: set CTX/output/effort env vars -----------\n# Caller must set CTX, OUTPUT_CAP, EFFORT, LONG_CTX before calling.\napply_context_and_effort() {\n\tif [ -n \"${EFFORT:-}\" ]; then export CLAUDE_CODE_EFFORT_LEVEL=\"$EFFORT\"; fi\n\n\tlocal ctx=\"${CTX:-}\"\n\tif [ -z \"$ctx\" ] && [ \"${LONG_CTX:-0}\" = \"1\" ]; then ctx=\"1048576\"; fi\n\tif [ -n \"$ctx\" ]; then\n\t\texport CLAUDE_CODE_MAX_CONTEXT_TOKENS=\"$ctx\"\n\t\texport DISABLE_COMPACT=1\n\tfi\n\n\tif [ -n \"${OUTPUT_CAP:-}\" ]; then export CLAUDE_CODE_MAX_OUTPUT_TOKENS=\"$OUTPUT_CAP\"; fi\n}\n\n# ---- show_banner_and_launch: print banner and exec claude ----------------\n# Usage: show_banner_and_launch \"DeepSeek\" \"$@\"\nshow_banner_and_launch() {\n\tlocal label=\"$1\"\n\tshift\n\tlocal banner=\"🚀 Claude Code on $label → $MAIN_MODEL ($BASE_URL)\"\n\t[ -n \"${CTX:-}\" ] && banner=\"$banner | ctx=$CTX\"\n\t[ -n \"${EFFORT:-}\" ] && banner=\"$banner | effort=$EFFORT\"\n\t[ \"${OTHER_MODEL:-}\" != \"$MAIN_MODEL\" ] && banner=\"$banner (switch mid-session via /model)\"\n\techo \"$banner\"\n\texec claude \"$@\"\n}\n"}, "c1f2e8a064922fce5be8b17bfba2cd0b5758cb64": {"t": 1785758056.2260745, "n": 5579, "h": "14341077f29081fc", "c": "#!/usr/bin/env bash\n# lib/common.sh — shared functions sourced by all *claude launcher scripts.\n# This file is not meant to be executed directly.\n#\n# Each launcher must set this variable before sourcing this file:\n# SELF_DIR — absolute path to the directory containing the launcher script\n#\n# Before calling export_anthropic_base the launcher must set:\n# BASE_URL, API_KEY, MAIN_MODEL, FLASH_MODEL\n\n# ---- find_repo: locate the xxclaude repository checkout -----------------\n# Usage: repo=\"$(find_repo \"DSCLAUDE_HOME\")\"\nfind_repo() {\n\tlocal home_var=\"$1\"\n\tif [ -d \"$SELF_DIR/.git\" ]; then\n\t\techo \"$SELF_DIR\"\n\t\treturn 0\n\tfi\n\tif [ -n \"${!home_var:-}\" ] && [ -d \"${!home_var}/.git\" ]; then\n\t\techo \"${!home_var}\"\n\t\treturn 0\n\tfi\n\tif [ -d \"$HOME/github/xxclaude/.git\" ]; then\n\t\techo \"$HOME/github/xxclaude\"\n\t\treturn 0\n\tfi\n\techo \"\"\n}\n\n# ---- do_update: git pull latest from the repo ---------------------------\n# Usage: do_update \"dsclaude\" \"DSCLAUDE_HOME\"\ndo_update() {\n\tlocal name=\"$1\" home_var=\"$2\"\n\tlocal repo\n\trepo=\"$(find_repo \"$home_var\")\"\n\tif [ -z \"$repo\" ]; then\n\t\techo \"$name: cannot find the xxclaude repo for self-update.\" >&2\n\t\techo \" Set $home_var=/path/to/xxclaude or cd into the repo and run ./$name update\" >&2\n\t\texit 1\n\tfi\n\techo \"$name: pulling latest from $repo ...\"\n\tgit -C \"$repo\" pull && echo \"$name: updated.\" || {\n\t\techo \"$name: git pull failed. Check network or resolve conflicts manually.\" >&2\n\t\texit 1\n\t}\n\texit 0\n}\n\n# ---- extract_key_from_file: get an API key value from a shell rc file ---\n# Skips commented-out lines (starting with # after optional whitespace).\n# Usage: key=\"$(extract_key_from_file \"$HOME/.zshrc\" \"DEEPSEEK_API_KEY\")\"\nextract_key_from_file() {\n\tlocal file=\"$1\" var=\"$2\"\n\t[ -f \"$file\" ] || return 1\n\tgrep -v '^[[:space:]]*#' \"$file\" |\n\t\tgrep -E \"^[[:space:]]*(export[[:space:]]+)?${var}=\" |\n\t\ttail -n1 |\n\t\tsed -E \"s/^[[:space:]]*(export[[:space:]]+)?${var}=//\" |\n\t\tsed -E 's/^\"(.*)\"$/\\1/; s/^'\"'\"'(.*)'\"'\"'$/\\1/'\n}\n\n# ---- resolve_api_key: env var first, then shell rc files ----------------\n# Usage: API_KEY=\"$(resolve_api_key \"DEEPSEEK_API_KEY\")\"\nresolve_api_key() {\n\tlocal var=\"$1\"\n\t# 1) Already in environment\n\tif [ -n \"${!var:-}\" ]; then\n\t\tprintf '%s' \"${!var}\"\n\t\treturn 0\n\tfi\n\t# 2) Shell rc files\n\tlocal f candidate\n\tfor f in \"$HOME/.zshrc\" \"$HOME/.bashrc\" \"$HOME/.bash_profile\" \"$HOME/.profile\"; do\n\t\tcandidate=\"$(extract_key_from_file \"$f\" \"$var\" || true)\"\n\t\tif [ -n \"${candidate:-}\" ]; then\n\t\t\tprintf '%s' \"$candidate\"\n\t\t\treturn 0\n\t\tfi\n\tdone\n\t# Return 0 even when not found: callers use API_KEY=\"$(resolve_api_key ...)\"\n\t# under `set -e`, and a nonzero status would kill the launcher silently\n\t# before its friendly \"key not found\" message can print.\n\treturn 0\n}\n\n# ---- export_anthropic_base: set the common ANTHROPIC_* env vars ---------\n# Caller must set BASE_URL, API_KEY, MAIN_MODEL, FLASH_MODEL first.\nexport_anthropic_base() {\n\t# Clear lingering official Anthropic credentials before launching,\n\t# otherwise they shadow ANTHROPIC_AUTH_TOKEN and traffic hits api.anthropic.com.\n\tunset ANTHROPIC_API_KEY 2>/dev/null || true\n\n\texport ANTHROPIC_BASE_URL=\"$BASE_URL\"\n\texport ANTHROPIC_AUTH_TOKEN=\"$API_KEY\"\n\texport ANTHROPIC_MODEL=\"$MAIN_MODEL\"\n\texport ANTHROPIC_DEFAULT_OPUS_MODEL=\"$MAIN_MODEL\"\n\texport ANTHROPIC_DEFAULT_SONNET_MODEL=\"$MAIN_MODEL\"\n\texport ANTHROPIC_DEFAULT_HAIKU_MODEL=\"$FLASH_MODEL\"\n\n\t# Prevent Claude Code from pinging api.anthropic.com for non-essential\n\t# features (billing check, feature flags) — those always fail on third-\n\t# party backends and produce noisy connection-error logs.\n\texport CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1\n}\n\n# ---- check_version: handle --version / -V flag -------------------------\n# Usage: check_version \"dsclaude\" \"$@\"\n# If the first arg is --version or -V, prints version info and exits.\ncheck_version() {\n\tlocal name=\"$1\"\n\tshift\n\tif [ $# -gt 0 ] && { [ \"$1\" = \"--version\" ] || [ \"$1\" = \"-V\" ]; }; then\n\t\tlocal repo ver=\"unknown\"\n\t\trepo=\"$(find_repo \"DUMMY\" 2>/dev/null || true)\"\n\t\t[ -n \"$repo\" ] && ver=\"$(git -C \"$repo\" describe --tags --always --dirty 2>/dev/null || echo \"unknown\")\"\n\t\techo \"$name $ver\"\n\t\texit 0\n\tfi\n}\n\n# ---- set_custom_model: expose alternate model in /model picker ----------\n# Usage: set_custom_model \"$OTHER_MODEL\" \"$MAIN_MODEL\" \"$OTHER_DESC\"\nset_custom_model() {\n\tlocal other=\"$1\" main=\"$2\" desc=\"$3\"\n\tif [ \"$other\" != \"$main\" ]; then\n\t\texport ANTHROPIC_CUSTOM_MODEL_OPTION=\"$other\"\n\t\texport ANTHROPIC_CUSTOM_MODEL_OPTION_NAME=\"$other\"\n\t\texport ANTHROPIC_CUSTOM_MODEL_OPTION_DESCRIPTION=\"$desc\"\n\tfi\n}\n\n# ---- apply_context_and_effort: set CTX/output/effort env vars -----------\n# Caller must set CTX, OUTPUT_CAP, EFFORT, LONG_CTX before calling.\napply_context_and_effort() {\n\tif [ -n \"${EFFORT:-}\" ]; then export CLAUDE_CODE_EFFORT_LEVEL=\"$EFFORT\"; fi\n\n\tlocal ctx=\"${CTX:-}\"\n\tif [ -z \"$ctx\" ] && [ \"${LONG_CTX:-0}\" = \"1\" ]; then ctx=\"1048576\"; fi\n\tif [ -n \"$ctx\" ]; then\n\t\texport CLAUDE_CODE_MAX_CONTEXT_TOKENS=\"$ctx\"\n\t\texport DISABLE_COMPACT=1\n\tfi\n\n\tif [ -n \"${OUTPUT_CAP:-}\" ]; then export CLAUDE_CODE_MAX_OUTPUT_TOKENS=\"$OUTPUT_CAP\"; fi\n}\n\n# ---- show_banner_and_launch: print banner and exec claude ----------------\n# Usage: show_banner_and_launch \"DeepSeek\" \"$@\"\nshow_banner_and_launch() {\n\tlocal label=\"$1\"\n\tshift\n\tlocal banner=\"🚀 Claude Code on $label → $MAIN_MODEL ($BASE_URL)\"\n\t[ -n \"${CTX:-}\" ] && banner=\"$banner | ctx=$CTX\"\n\t[ -n \"${EFFORT:-}\" ] && banner=\"$banner | effort=$EFFORT\"\n\t[ \"${OTHER_MODEL:-}\" != \"$MAIN_MODEL\" ] && banner=\"$banner (switch mid-session via /model)\"\n\techo \"$banner\"\n\texec claude \"$@\"\n}\n"}, "6e7f604972cf57ad3d384559760f9c7467bc71b6": {"t": 1785758058.3288758, "n": 5671, "h": "a121509fcb8bb099", "c": "#!/usr/bin/env bash\n# lib/common.sh — shared functions sourced by all *claude launcher scripts.\n# This file is not meant to be executed directly.\n#\n# Each launcher must set this variable before sourcing this file:\n# SELF_DIR — absolute path to the directory containing the launcher script\n#\n# Before calling export_anthropic_base the launcher must set:\n# BASE_URL, API_KEY, MAIN_MODEL, FLASH_MODEL\n\n# ---- find_repo: locate the xxclaude repository checkout -----------------\n# Usage: repo=\"$(find_repo \"DSCLAUDE_HOME\")\"\nfind_repo() {\n local home_var=\"$1\"\n if [ -d \"$SELF_DIR/.git\" ]; then echo \"$SELF_DIR\"; return 0; fi\n if [ -n \"${!home_var:-}\" ] && [ -d \"${!home_var}/.git\" ]; then echo \"${!home_var}\"; return 0; fi\n if [ -d \"$HOME/github/xxclaude/.git\" ]; then echo \"$HOME/github/xxclaude\"; return 0; fi\n echo \"\"\n}\n\n# ---- do_update: git pull latest from the repo ---------------------------\n# Usage: do_update \"dsclaude\" \"DSCLAUDE_HOME\"\ndo_update() {\n local name=\"$1\" home_var=\"$2\"\n local repo\n repo=\"$(find_repo \"$home_var\")\"\n if [ -z \"$repo\" ]; then\n echo \"$name: cannot find the xxclaude repo for self-update.\" >&2\n echo \" Set $home_var=/path/to/xxclaude or cd into the repo and run ./$name update\" >&2\n exit 1\n fi\n echo \"$name: pulling latest from $repo ...\"\n git -C \"$repo\" pull && echo \"$name: updated.\" || {\n echo \"$name: git pull failed. Check network or resolve conflicts manually.\" >&2\n exit 1\n }\n exit 0\n}\n\n# ---- extract_key_from_file: get an API key value from a shell rc file ---\n# Skips commented-out lines (starting with # after optional whitespace).\n# Usage: key=\"$(extract_key_from_file \"$HOME/.zshrc\" \"DEEPSEEK_API_KEY\")\"\nextract_key_from_file() {\n local file=\"$1\" var=\"$2\"\n [ -f \"$file\" ] || return 1\n grep -v '^[[:space:]]*#' \"$file\" \\\n | grep -E \"^[[:space:]]*(export[[:space:]]+)?${var}=\" \\\n | tail -n1 \\\n | sed -E \"s/^[[:space:]]*(export[[:space:]]+)?${var}=//\" \\\n | sed -E 's/^\"(.*)\"$/\\1/; s/^'\"'\"'(.*)'\"'\"'$/\\1/'\n}\n\n# ---- resolve_api_key: env var first, then shell rc files ----------------\n# Usage: API_KEY=\"$(resolve_api_key \"DEEPSEEK_API_KEY\")\"\nresolve_api_key() {\n local var=\"$1\"\n # 1) Already in environment\n if [ -n \"${!var:-}\" ]; then printf '%s' \"${!var}\"; return 0; fi\n # 2) Shell rc files\n local f candidate\n for f in \"$HOME/.zshrc\" \"$HOME/.bashrc\" \"$HOME/.bash_profile\" \"$HOME/.profile\"; do\n candidate=\"$(extract_key_from_file \"$f\" \"$var\" || true)\"\n if [ -n \"${candidate:-}\" ]; then printf '%s' \"$candidate\"; return 0; fi\n done\n # Return 0 even when not found: callers use API_KEY=\"$(resolve_api_key ...)\"\n # under `set -e`, and a nonzero status would kill the launcher silently\n # before its friendly \"key not found\" message can print.\n return 0\n}\n\n# ---- export_anthropic_base: set the common ANTHROPIC_* env vars ---------\n# Caller must set BASE_URL, API_KEY, MAIN_MODEL, FLASH_MODEL first.\nexport_anthropic_base() {\n # Clear lingering official Anthropic credentials before launching,\n # otherwise they shadow ANTHROPIC_AUTH_TOKEN and traffic hits api.anthropic.com.\n unset ANTHROPIC_API_KEY 2>/dev/null || true\n\n export ANTHROPIC_BASE_URL=\"$BASE_URL\"\n export ANTHROPIC_AUTH_TOKEN=\"$API_KEY\"\n export ANTHROPIC_MODEL=\"$MAIN_MODEL\"\n export ANTHROPIC_DEFAULT_OPUS_MODEL=\"$MAIN_MODEL\"\n export ANTHROPIC_DEFAULT_SONNET_MODEL=\"$MAIN_MODEL\"\n export ANTHROPIC_DEFAULT_HAIKU_MODEL=\"$FLASH_MODEL\"\n\n # Prevent Claude Code from pinging api.anthropic.com for non-essential\n # features (billing check, feature flags) — those always fail on third-\n # party backends and produce noisy connection-error logs.\n export CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1\n}\n\n# ---- check_version: handle --version / -V flag -------------------------\n# Usage: check_version \"dsclaude\" \"$@\"\n# If the first arg is --version or -V, prints version info and exits.\ncheck_version() {\n local name=\"$1\"; shift\n if [ $# -gt 0 ] && { [ \"$1\" = \"--version\" ] || [ \"$1\" = \"-V\" ]; }; then\n local repo ver=\"unknown\"\n repo=\"$(find_repo \"DUMMY\" 2>/dev/null || true)\"\n [ -n \"$repo\" ] && ver=\"$(git -C \"$repo\" describe --tags --always --dirty 2>/dev/null || echo \"unknown\")\"\n echo \"$name $ver\"\n exit 0\n fi\n}\n\n# ---- set_custom_model: expose alternate model in /model picker ----------\n# Usage: set_custom_model \"$OTHER_MODEL\" \"$MAIN_MODEL\" \"$OTHER_DESC\"\nset_custom_model() {\n local other=\"$1\" main=\"$2\" desc=\"$3\"\n if [ \"$other\" != \"$main\" ]; then\n export ANTHROPIC_CUSTOM_MODEL_OPTION=\"$other\"\n export ANTHROPIC_CUSTOM_MODEL_OPTION_NAME=\"$other\"\n export ANTHROPIC_CUSTOM_MODEL_OPTION_DESCRIPTION=\"$desc\"\n fi\n}\n\n# ---- apply_context_and_effort: set CTX/output/effort env vars -----------\n# Caller must set CTX, OUTPUT_CAP, EFFORT, LONG_CTX before calling.\napply_context_and_effort() {\n if [ -n \"${EFFORT:-}\" ]; then export CLAUDE_CODE_EFFORT_LEVEL=\"$EFFORT\"; fi\n\n local ctx=\"${CTX:-}\"\n if [ -z \"$ctx\" ] && [ \"${LONG_CTX:-0}\" = \"1\" ]; then ctx=\"1048576\"; fi\n if [ -n \"$ctx\" ]; then\n export CLAUDE_CODE_MAX_CONTEXT_TOKENS=\"$ctx\"\n export DISABLE_COMPACT=1\n fi\n\n if [ -n \"${OUTPUT_CAP:-}\" ]; then export CLAUDE_CODE_MAX_OUTPUT_TOKENS=\"$OUTPUT_CAP\"; fi\n}\n\n# ---- show_banner_and_launch: print banner and exec claude ----------------\n# Usage: show_banner_and_launch \"DeepSeek\" \"$@\"\nshow_banner_and_launch() {\n local label=\"$1\"; shift\n local banner=\"🚀 Claude Code on $label → $MAIN_MODEL ($BASE_URL)\"\n [ -n \"${CTX:-}\" ] && banner=\"$banner | ctx=$CTX\"\n [ -n \"${EFFORT:-}\" ] && banner=\"$banner | effort=$EFFORT\"\n [ \"${OTHER_MODEL:-}\" != \"$MAIN_MODEL\" ] && banner=\"$banner (switch mid-session via /model)\"\n echo \"$banner\"\n exec claude \"$@\"\n}\n"}, "2525882659f2c26f4e2221ba062878ff8234b7c3": {"t": 1785758060.262947, "n": 5459, "h": "fe12d4d33d83aab2", "c": "#!/usr/bin/env bash\n# lib/common.sh — shared functions sourced by all *claude launcher scripts.\n# This file is not meant to be executed directly.\n#\n# Each launcher must set this variable before sourcing this file:\n# SELF_DIR — absolute path to the directory containing the launcher script\n#\n# Before calling export_anthropic_base the launcher must set:\n# BASE_URL, API_KEY, MAIN_MODEL, FLASH_MODEL\n\n# ---- find_repo: locate the xxclaude repository checkout -----------------\n# Usage: repo=\"$(find_repo \"DSCLAUDE_HOME\")\"\nfind_repo() {\n local home_var=\"$1\"\n if [ -d \"$SELF_DIR/.git\" ]; then echo \"$SELF_DIR\"; return 0; fi\n if [ -n \"${!home_var:-}\" ] && [ -d \"${!home_var}/.git\" ]; then echo \"${!home_var}\"; return 0; fi\n if [ -d \"$HOME/github/xxclaude/.git\" ]; then echo \"$HOME/github/xxclaude\"; return 0; fi\n echo \"\"\n}\n\n# ---- do_update: git pull latest from the repo ---------------------------\n# Usage: do_update \"dsclaude\" \"DSCLAUDE_HOME\"\ndo_update() {\n local name=\"$1\" home_var=\"$2\"\n local repo\n repo=\"$(find_repo \"$home_var\")\"\n if [ -z \"$repo\" ]; then\n echo \"$name: cannot find the xxclaude repo for self-update.\" >&2\n echo \" Set $home_var=/path/to/xxclaude or cd into the repo and run ./$name update\" >&2\n exit 1\n fi\n echo \"$name: pulling latest from $repo ...\"\n git -C \"$repo\" pull && echo \"$name: updated.\" || {\n echo \"$name: git pull failed. Check network or resolve conflicts manually.\" >&2\n exit 1\n }\n exit 0\n}\n\n# ---- extract_key_from_file: get an API key value from a shell rc file ---\n# Skips commented-out lines (starting with # after optional whitespace).\n# Usage: key=\"$(extract_key_from_file \"$HOME/.zshrc\" \"DEEPSEEK_API_KEY\")\"\nextract_key_from_file() {\n local file=\"$1\" var=\"$2\"\n [ -f \"$file\" ] || return 1\n grep -v '^[[:space:]]*#' \"$file\" \\\n | grep -E \"^[[:space:]]*(export[[:space:]]+)?${var}=\" \\\n | tail -n1 \\\n | sed -E \"s/^[[:space:]]*(export[[:space:]]+)?${var}=//\" \\\n | sed -E 's/^\"(.*)\"$/\\1/; s/^'\"'\"'(.*)'\"'\"'$/\\1/'\n}\n\n# ---- resolve_api_key: env var first, then shell rc files ----------------\n# Usage: API_KEY=\"$(resolve_api_key \"DEEPSEEK_API_KEY\")\"\nresolve_api_key() {\n local var=\"$1\"\n # 1) Already in environment\n if [ -n \"${!var:-}\" ]; then printf '%s' \"${!var}\"; return 0; fi\n # 2) Shell rc files\n local f candidate\n for f in \"$HOME/.zshrc\" \"$HOME/.bashrc\" \"$HOME/.bash_profile\" \"$HOME/.profile\"; do\n candidate=\"$(extract_key_from_file \"$f\" \"$var\" || true)\"\n if [ -n \"${candidate:-}\" ]; then printf '%s' \"$candidate\"; return 0; fi\n done\n return 1\n}\n\n# ---- export_anthropic_base: set the common ANTHROPIC_* env vars ---------\n# Caller must set BASE_URL, API_KEY, MAIN_MODEL, FLASH_MODEL first.\nexport_anthropic_base() {\n # Clear lingering official Anthropic credentials before launching,\n # otherwise they shadow ANTHROPIC_AUTH_TOKEN and traffic hits api.anthropic.com.\n unset ANTHROPIC_API_KEY 2>/dev/null || true\n\n export ANTHROPIC_BASE_URL=\"$BASE_URL\"\n export ANTHROPIC_AUTH_TOKEN=\"$API_KEY\"\n export ANTHROPIC_MODEL=\"$MAIN_MODEL\"\n export ANTHROPIC_DEFAULT_OPUS_MODEL=\"$MAIN_MODEL\"\n export ANTHROPIC_DEFAULT_SONNET_MODEL=\"$MAIN_MODEL\"\n export ANTHROPIC_DEFAULT_HAIKU_MODEL=\"$FLASH_MODEL\"\n\n # Prevent Claude Code from pinging api.anthropic.com for non-essential\n # features (billing check, feature flags) — those always fail on third-\n # party backends and produce noisy connection-error logs.\n export CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1\n}\n\n# ---- check_version: handle --version / -V flag -------------------------\n# Usage: check_version \"dsclaude\" \"$@\"\n# If the first arg is --version or -V, prints version info and exits.\ncheck_version() {\n local name=\"$1\"; shift\n if [ $# -gt 0 ] && { [ \"$1\" = \"--version\" ] || [ \"$1\" = \"-V\" ]; }; then\n local repo ver=\"unknown\"\n repo=\"$(find_repo \"DUMMY\" 2>/dev/null || true)\"\n [ -n \"$repo\" ] && ver=\"$(git -C \"$repo\" describe --tags --always --dirty 2>/dev/null || echo \"unknown\")\"\n echo \"$name $ver\"\n exit 0\n fi\n}\n\n# ---- set_custom_model: expose alternate model in /model picker ----------\n# Usage: set_custom_model \"$OTHER_MODEL\" \"$MAIN_MODEL\" \"$OTHER_DESC\"\nset_custom_model() {\n local other=\"$1\" main=\"$2\" desc=\"$3\"\n if [ \"$other\" != \"$main\" ]; then\n export ANTHROPIC_CUSTOM_MODEL_OPTION=\"$other\"\n export ANTHROPIC_CUSTOM_MODEL_OPTION_NAME=\"$other\"\n export ANTHROPIC_CUSTOM_MODEL_OPTION_DESCRIPTION=\"$desc\"\n fi\n}\n\n# ---- apply_context_and_effort: set CTX/output/effort env vars -----------\n# Caller must set CTX, OUTPUT_CAP, EFFORT, LONG_CTX before calling.\napply_context_and_effort() {\n if [ -n \"${EFFORT:-}\" ]; then export CLAUDE_CODE_EFFORT_LEVEL=\"$EFFORT\"; fi\n\n local ctx=\"${CTX:-}\"\n if [ -z \"$ctx\" ] && [ \"${LONG_CTX:-0}\" = \"1\" ]; then ctx=\"1048576\"; fi\n if [ -n \"$ctx\" ]; then\n export CLAUDE_CODE_MAX_CONTEXT_TOKENS=\"$ctx\"\n export DISABLE_COMPACT=1\n fi\n\n if [ -n \"${OUTPUT_CAP:-}\" ]; then export CLAUDE_CODE_MAX_OUTPUT_TOKENS=\"$OUTPUT_CAP\"; fi\n}\n\n# ---- show_banner_and_launch: print banner and exec claude ----------------\n# Usage: show_banner_and_launch \"DeepSeek\" \"$@\"\nshow_banner_and_launch() {\n local label=\"$1\"; shift\n local banner=\"🚀 Claude Code on $label → $MAIN_MODEL ($BASE_URL)\"\n [ -n \"${CTX:-}\" ] && banner=\"$banner | ctx=$CTX\"\n [ -n \"${EFFORT:-}\" ] && banner=\"$banner | effort=$EFFORT\"\n [ \"${OTHER_MODEL:-}\" != \"$MAIN_MODEL\" ] && banner=\"$banner (switch mid-session via /model)\"\n echo \"$banner\"\n exec claude \"$@\"\n}\n"}, "ea2a57d1593b741035a3e943052d52e07f75f119": {"t": 1785758061.8349183, "n": 4667, "h": "9ea278078e590e8b", "c": "#!/usr/bin/env bash\n# lib/common.sh — shared functions sourced by all *claude launcher scripts.\n# This file is not meant to be executed directly.\n#\n# Each launcher must set this variable before sourcing this file:\n# SELF_DIR — absolute path to the directory containing the launcher script\n#\n# Before calling export_anthropic_base the launcher must set:\n# BASE_URL, API_KEY, MAIN_MODEL, FLASH_MODEL\n\n# ---- find_repo: locate the xxclaude repository checkout -----------------\n# Usage: repo=\"$(find_repo \"DSCLAUDE_HOME\")\"\nfind_repo() {\n local home_var=\"$1\"\n if [ -d \"$SELF_DIR/.git\" ]; then echo \"$SELF_DIR\"; return 0; fi\n if [ -n \"${!home_var:-}\" ] && [ -d \"${!home_var}/.git\" ]; then echo \"${!home_var}\"; return 0; fi\n if [ -d \"$HOME/github/xxclaude/.git\" ]; then echo \"$HOME/github/xxclaude\"; return 0; fi\n echo \"\"\n}\n\n# ---- do_update: git pull latest from the repo ---------------------------\n# Usage: do_update \"dsclaude\" \"DSCLAUDE_HOME\"\ndo_update() {\n local name=\"$1\" home_var=\"$2\"\n local repo\n repo=\"$(find_repo \"$home_var\")\"\n if [ -z \"$repo\" ]; then\n echo \"$name: cannot find the xxclaude repo for self-update.\" >&2\n echo \" Set $home_var=/path/to/xxclaude or cd into the repo and run ./$name update\" >&2\n exit 1\n fi\n echo \"$name: pulling latest from $repo ...\"\n git -C \"$repo\" pull && echo \"$name: updated.\" || {\n echo \"$name: git pull failed. Check network or resolve conflicts manually.\" >&2\n exit 1\n }\n exit 0\n}\n\n# ---- extract_key_from_file: get an API key value from a shell rc file ---\n# Skips commented-out lines (starting with # after optional whitespace).\n# Usage: key=\"$(extract_key_from_file \"$HOME/.zshrc\" \"DEEPSEEK_API_KEY\")\"\nextract_key_from_file() {\n local file=\"$1\" var=\"$2\"\n [ -f \"$file\" ] || return 1\n grep -v '^[[:space:]]*#' \"$file\" \\\n | grep -E \"^[[:space:]]*(export[[:space:]]+)?${var}=\" \\\n | tail -n1 \\\n | sed -E \"s/^[[:space:]]*(export[[:space:]]+)?${var}=//\" \\\n | sed -E 's/^\"(.*)\"$/\\1/; s/^'\"'\"'(.*)'\"'\"'$/\\1/'\n}\n\n# ---- resolve_api_key: env var first, then shell rc files ----------------\n# Usage: API_KEY=\"$(resolve_api_key \"DEEPSEEK_API_KEY\")\"\nresolve_api_key() {\n local var=\"$1\"\n # 1) Already in environment\n if [ -n \"${!var:-}\" ]; then printf '%s' \"${!var}\"; return 0; fi\n # 2) Shell rc files\n local f candidate\n for f in \"$HOME/.zshrc\" \"$HOME/.bashrc\" \"$HOME/.bash_profile\" \"$HOME/.profile\"; do\n candidate=\"$(extract_key_from_file \"$f\" \"$var\" || true)\"\n if [ -n \"${candidate:-}\" ]; then printf '%s' \"$candidate\"; return 0; fi\n done\n return 1\n}\n\n# ---- export_anthropic_base: set the common ANTHROPIC_* env vars ---------\n# Caller must set BASE_URL, API_KEY, MAIN_MODEL, FLASH_MODEL first.\nexport_anthropic_base() {\n # Clear lingering official Anthropic credentials before launching,\n # otherwise they shadow ANTHROPIC_AUTH_TOKEN and traffic hits api.anthropic.com.\n unset ANTHROPIC_API_KEY 2>/dev/null || true\n\n export ANTHROPIC_BASE_URL=\"$BASE_URL\"\n export ANTHROPIC_AUTH_TOKEN=\"$API_KEY\"\n export ANTHROPIC_MODEL=\"$MAIN_MODEL\"\n export ANTHROPIC_DEFAULT_OPUS_MODEL=\"$MAIN_MODEL\"\n export ANTHROPIC_DEFAULT_SONNET_MODEL=\"$MAIN_MODEL\"\n export ANTHROPIC_DEFAULT_HAIKU_MODEL=\"$FLASH_MODEL\"\n}\n\n# ---- set_custom_model: expose alternate model in /model picker ----------\n# Usage: set_custom_model \"$OTHER_MODEL\" \"$MAIN_MODEL\" \"$OTHER_DESC\"\nset_custom_model() {\n local other=\"$1\" main=\"$2\" desc=\"$3\"\n if [ \"$other\" != \"$main\" ]; then\n export ANTHROPIC_CUSTOM_MODEL_OPTION=\"$other\"\n export ANTHROPIC_CUSTOM_MODEL_OPTION_NAME=\"$other\"\n export ANTHROPIC_CUSTOM_MODEL_OPTION_DESCRIPTION=\"$desc\"\n fi\n}\n\n# ---- apply_context_and_effort: set CTX/output/effort env vars -----------\n# Caller must set CTX, OUTPUT_CAP, EFFORT, LONG_CTX before calling.\napply_context_and_effort() {\n if [ -n \"${EFFORT:-}\" ]; then export CLAUDE_CODE_EFFORT_LEVEL=\"$EFFORT\"; fi\n\n local ctx=\"${CTX:-}\"\n if [ -z \"$ctx\" ] && [ \"${LONG_CTX:-0}\" = \"1\" ]; then ctx=\"1048576\"; fi\n if [ -n \"$ctx\" ]; then\n export CLAUDE_CODE_MAX_CONTEXT_TOKENS=\"$ctx\"\n export DISABLE_COMPACT=1\n fi\n\n if [ -n \"${OUTPUT_CAP:-}\" ]; then export CLAUDE_CODE_MAX_OUTPUT_TOKENS=\"$OUTPUT_CAP\"; fi\n}\n\n# ---- show_banner_and_launch: print banner and exec claude ----------------\n# Usage: show_banner_and_launch \"DeepSeek\" \"$@\"\nshow_banner_and_launch() {\n local label=\"$1\"; shift\n local banner=\"🚀 Claude Code on $label → $MAIN_MODEL ($BASE_URL)\"\n [ -n \"${CTX:-}\" ] && banner=\"$banner | ctx=$CTX\"\n [ -n \"${EFFORT:-}\" ] && banner=\"$banner | effort=$EFFORT\"\n [ \"${OTHER_MODEL:-}\" != \"$MAIN_MODEL\" ] && banner=\"$banner (switch mid-session via /model)\"\n echo \"$banner\"\n exec claude \"$@\"\n}\n"}}, "codex-setup.sh": {"c07db31916dca8077b9124f5c098258f9607b016": {"t": 1785745938.6689203, "n": 7814, "h": "cf3c20fa9b70ca02", "c": "#!/usr/bin/env bash\n# codex-setup.sh — generate ~/.codex/config.toml with all your available backends.\n#\n# Detects which API keys you've set (env or shell rc), then writes a Codex\n# config.toml pre-filled with provider blocks for every backend you can use.\n# The first detected key becomes the default provider.\n#\n# Codex only speaks the OpenAI Responses API (Chat Completions support was\n# removed in early 2026). Providers are wired accordingly:\n# - Native Responses (direct): dashscope, ark, longcat, minimax\n# - Chat-only (via local adapter codex-adapter.mjs): deepseek, moonshot,\n# zhipu, tokenhub, siliconflow\n# For adapter-backed providers, start the adapter before running codex:\n# nohup node codex-adapter.mjs > ~/.codex/adapter.log 2>&1 &\n#\n# Usage:\n# ./codex-setup.sh # interactive: pick from detected keys\n# ./codex-setup.sh --dry-run # print the config, don't write it\n# ./codex-setup.sh --force deepseek # set deepseek as default\n\nset -euo pipefail\n\nDRY_RUN=0; FORCE=\"\"\nwhile [ $# -gt 0 ]; do\n case \"$1\" in\n --dry-run) DRY_RUN=1 ;; --force) FORCE=\"$2\"; shift ;;\n *) echo \"codex-setup.sh: unknown option: $1\" >&2; exit 1 ;;\n esac; shift\ndone\n\nget_key() {\n local var=\"$1\"\n if [ -n \"${!var:-}\" ]; then printf '%s' \"${!var}\"; return 0; fi\n local f candidate\n for f in \"$HOME/.zshrc\" \"$HOME/.bashrc\" \"$HOME/.bash_profile\" \"$HOME/.profile\"; do\n [ -f \"$f\" ] || continue\n candidate=\"$(grep -v '^[[:space:]]*#' \"$f\" 2>/dev/null|grep -E \"^[[:space:]]*(export[[:space:]]+)?${var}=\"|tail -1|sed -E \"s/^[[:space:]]*(export[[:space:]]+)?${var}=//\"|sed -E 's/^\"(.*)\"$/\\1/; s/^'\"'\"'(.*)'\"'\"'$/\\1/'||true)\"\n if [ -n \"${candidate:-}\" ]; then printf '%s' \"$candidate\"; return 0; fi\n done; return 1\n}\n\n# Adapter port for chat-only providers (codex-adapter.mjs).\nADAPTER_PORT=\"${CODEX_ADAPTER_PORT:-8317}\"\nSCRIPT_DIR=\"$(cd \"$(dirname \"$0\")\" && pwd)\"\n\n# Provider data: id label base_url key_var model need_noauth mode\n# mode: responses = provider natively supports the OpenAI Responses API\n# adapter = chat-only; routed through the local codex-adapter.mjs\n# Separated by | for easy parsing.\nPROVIDERS_DATA=(\n \"deepseek|DeepSeek|http://127.0.0.1:${ADAPTER_PORT}/deepseek/v1|DEEPSEEK_API_KEY|deepseek-v4-pro|no|adapter\"\n \"dashscope|Qwen (Bailian)|https://dashscope.aliyuncs.com/compatible-mode/v1|DASHSCOPE_API_KEY|qwen-plus|no|responses\"\n \"moonshot|Moonshot Kimi|http://127.0.0.1:${ADAPTER_PORT}/moonshot/v1|KIMI_API_KEY|kimi-k2.5|no|adapter\"\n \"zhipu|ZhipuAI GLM|http://127.0.0.1:${ADAPTER_PORT}/zhipu/v1|GLM_API_KEY|glm-5.2|yes|adapter\"\n \"ark|Volcengine Ark|https://ark.cn-beijing.volces.com/api/v3|ARK_API_KEY|doubao-seed-2.0-code|yes|responses\"\n \"longcat|Meituan LongCat|https://api.longcat.chat/openai/v1|LONGCAT_API_KEY|LongCat-2.0|yes|responses\"\n \"minimax|MiniMax|https://api.minimaxi.com/v1|MINIMAX_API_KEY|MiniMax-M3|yes|responses\"\n \"tokenhub|Tencent TokenHub|http://127.0.0.1:${ADAPTER_PORT}/tokenhub/v1|HY_API_KEY|hy3-preview|yes|adapter\"\n \"siliconflow|SiliconFlow|http://127.0.0.1:${ADAPTER_PORT}/siliconflow/v1|SF_API_KEY|deepseek-ai/DeepSeek-V4-PRO|yes|adapter\"\n)\n\n# Detect available providers.\navailable_ids=()\navailable_labels=()\nfor entry in \"${PROVIDERS_DATA[@]}\"; do\n IFS='|' read -r pid plabel purl pkey pmodel pnoauth pmode <<< \"$entry\"\n k=\"$(get_key \"$pkey\" || true)\"\n if [ -n \"${k:-}\" ]; then available_ids+=(\"$pid\"); available_labels+=(\"$plabel\"); fi\ndone\n\nif [ ${#available_ids[@]} -eq 0 ]; then\n echo \"codex-setup.sh: no known API keys found. Set one in your ~/.zshrc:\" >&2\n echo \" export DEEPSEEK_API_KEY=sk-...\" >&2\n echo \" export KIMI_API_KEY=sk-...\" >&2\n exit 1\nfi\n\n# Pick default.\nDEFAULT_ID=\"${available_ids[0]}\"; DEFAULT_LABEL=\"${available_labels[0]}\"\nif [ -n \"$FORCE\" ]; then\n found=0; for i in \"${!available_ids[@]}\"; do\n if [ \"${available_ids[$i]}\" = \"$FORCE\" ]; then DEFAULT_ID=\"$FORCE\"; DEFAULT_LABEL=\"${available_labels[$i]}\"; found=1; break; fi\n done\n if [ \"$found\" = \"0\" ]; then echo \"codex-setup.sh: provider '$FORCE' key not set.\" >&2; exit 1; fi\nelif [ ${#available_ids[@]} -gt 1 ] && [ ! -t 0 ]; then\n # Non-interactive with multiple keys — use first.\n :\nelif [ ${#available_ids[@]} -gt 1 ]; then\n echo \"Multiple API keys detected. Which default provider?\"\n for i in \"${!available_ids[@]}\"; do echo \" $((i+1))) ${available_labels[$i]}\"; done\n read -r -p \"Choice [1-${#available_ids[@]}] (default 1): \" choice\n idx=\"${choice:-1}\"\n if [ \"$idx\" -ge 1 ] 2>/dev/null && [ \"$idx\" -le \"${#available_ids[@]}\" ]; then\n DEFAULT_ID=\"${available_ids[$((idx-1))]}\"; DEFAULT_LABEL=\"${available_labels[$((idx-1))]}\"\n fi\nfi\n\n# Find default model.\nDEFAULT_MODEL=\"\"; for entry in \"${PROVIDERS_DATA[@]}\"; do\n IFS='|' read -r pid plabel purl pkey pmodel pnoauth pmode <<< \"$entry\"\n [ \"$pid\" = \"$DEFAULT_ID\" ] && { DEFAULT_MODEL=\"$pmodel\"; break; }\ndone\n\n# ---- Generate config.toml --------------------------------------------------\nCONFIG_PATH=\"$HOME/.codex/config.toml\"\n\ngenerate_toml() {\n echo \"# Generated by codex-setup.sh — $(date +%Y-%m-%d)\"\n echo \"# Re-run codex-setup.sh to refresh when you add new API keys.\"\n echo \"\"\n echo \"model = \\\"$DEFAULT_MODEL\\\"\"\n echo \"model_provider = \\\"$DEFAULT_ID\\\"\"\n echo \"\"\n\n for entry in \"${PROVIDERS_DATA[@]}\"; do\n IFS='|' read -r pid plabel purl pkey pmodel pnoauth pmode <<< \"$entry\"\n # Only include if available.\n found=0; for aid in \"${available_ids[@]}\"; do [ \"$aid\" = \"$pid\" ] && found=1; done\n [ \"$found\" = \"0\" ] && continue\n\n echo \"# ---- $plabel ----\"\n if [ \"$pmode\" = \"adapter\" ]; then\n echo \"# Chat-only upstream: routed through the local codex-adapter.mjs proxy.\"\n echo \"# Start it first: nohup node ${SCRIPT_DIR}/codex-adapter.mjs > ~/.codex/adapter.log 2>&1 &\"\n fi\n echo \"[model_providers.$pid]\"\n echo \"name = \\\"$plabel\\\"\"\n echo \"base_url = \\\"$purl\\\"\"\n echo \"env_key = \\\"$pkey\\\"\"\n echo \"wire_api = \\\"responses\\\"\"\n if [ \"$pnoauth\" = \"yes\" ]; then echo \"requires_openai_auth = false\"; fi\n echo \"\"\n done\n}\n\n# Modern Codex profiles live in separate files (~/.codex/.config.toml);\n# the legacy [profiles.*] tables in config.toml are rejected by current Codex.\nwrite_profile_files() {\n for entry in \"${PROVIDERS_DATA[@]}\"; do\n IFS='|' read -r pid plabel purl pkey pmodel pnoauth pmode <<< \"$entry\"\n found=0; for aid in \"${available_ids[@]}\"; do [ \"$aid\" = \"$pid\" ] && found=1; done\n [ \"$found\" = \"0\" ] && continue\n printf 'model = \"%s\"\\nmodel_provider = \"%s\"\\n' \"$pmodel\" \"$pid\" > \"$HOME/.codex/$pid.config.toml\"\n done\n}\n\n# True if any available provider is adapter-backed.\nneeds_adapter() {\n for entry in \"${PROVIDERS_DATA[@]}\"; do\n IFS='|' read -r pid plabel purl pkey pmodel pnoauth pmode <<< \"$entry\"\n for aid in \"${available_ids[@]}\"; do\n [ \"$aid\" = \"$pid\" ] && [ \"$pmode\" = \"adapter\" ] && return 0\n done\n done\n return 1\n}\n\nif [ \"$DRY_RUN\" = \"1\" ]; then\n generate_toml\n echo \"# Dry run — no file written.\"\nelse\n mkdir -p \"$HOME/.codex\"\n if [ -f \"$CONFIG_PATH\" ]; then\n cp \"$CONFIG_PATH\" \"${CONFIG_PATH}.bak.$(date +%Y%m%d%H%M%S)\"\n echo \"Backed up existing config.\"\n fi\n generate_toml > \"$CONFIG_PATH\"\n write_profile_files\n echo \"✓ Wrote $CONFIG_PATH (default: $DEFAULT_LABEL)\"\n echo \"✓ Wrote profile files: $(for id in \"${available_ids[@]}\"; do printf '%s.config.toml ' \"$id\"; done)\"\n echo \"\"\n echo \"Quick-switch profiles:\"\n for id in \"${available_ids[@]}\"; do echo \" codex --profile $id\"; done\n if needs_adapter; then\n echo \"\"\n echo \"⚠ Some of your providers are chat-only and need the local adapter.\"\n echo \" Start it once (survives until reboot):\"\n echo \" nohup node ${SCRIPT_DIR}/codex-adapter.mjs > ~/.codex/adapter.log 2>&1 &\"\n echo \" Check: curl http://127.0.0.1:${ADAPTER_PORT}/health\"\n fi\nfi\n"}, "ea2a57d1593b741035a3e943052d52e07f75f119": {"t": 1785758056.1875136, "n": 7814, "h": "cf3c20fa9b70ca02", "c": "#!/usr/bin/env bash\n# codex-setup.sh — generate ~/.codex/config.toml with all your available backends.\n#\n# Detects which API keys you've set (env or shell rc), then writes a Codex\n# config.toml pre-filled with provider blocks for every backend you can use.\n# The first detected key becomes the default provider.\n#\n# Codex only speaks the OpenAI Responses API (Chat Completions support was\n# removed in early 2026). Providers are wired accordingly:\n# - Native Responses (direct): dashscope, ark, longcat, minimax\n# - Chat-only (via local adapter codex-adapter.mjs): deepseek, moonshot,\n# zhipu, tokenhub, siliconflow\n# For adapter-backed providers, start the adapter before running codex:\n# nohup node codex-adapter.mjs > ~/.codex/adapter.log 2>&1 &\n#\n# Usage:\n# ./codex-setup.sh # interactive: pick from detected keys\n# ./codex-setup.sh --dry-run # print the config, don't write it\n# ./codex-setup.sh --force deepseek # set deepseek as default\n\nset -euo pipefail\n\nDRY_RUN=0; FORCE=\"\"\nwhile [ $# -gt 0 ]; do\n case \"$1\" in\n --dry-run) DRY_RUN=1 ;; --force) FORCE=\"$2\"; shift ;;\n *) echo \"codex-setup.sh: unknown option: $1\" >&2; exit 1 ;;\n esac; shift\ndone\n\nget_key() {\n local var=\"$1\"\n if [ -n \"${!var:-}\" ]; then printf '%s' \"${!var}\"; return 0; fi\n local f candidate\n for f in \"$HOME/.zshrc\" \"$HOME/.bashrc\" \"$HOME/.bash_profile\" \"$HOME/.profile\"; do\n [ -f \"$f\" ] || continue\n candidate=\"$(grep -v '^[[:space:]]*#' \"$f\" 2>/dev/null|grep -E \"^[[:space:]]*(export[[:space:]]+)?${var}=\"|tail -1|sed -E \"s/^[[:space:]]*(export[[:space:]]+)?${var}=//\"|sed -E 's/^\"(.*)\"$/\\1/; s/^'\"'\"'(.*)'\"'\"'$/\\1/'||true)\"\n if [ -n \"${candidate:-}\" ]; then printf '%s' \"$candidate\"; return 0; fi\n done; return 1\n}\n\n# Adapter port for chat-only providers (codex-adapter.mjs).\nADAPTER_PORT=\"${CODEX_ADAPTER_PORT:-8317}\"\nSCRIPT_DIR=\"$(cd \"$(dirname \"$0\")\" && pwd)\"\n\n# Provider data: id label base_url key_var model need_noauth mode\n# mode: responses = provider natively supports the OpenAI Responses API\n# adapter = chat-only; routed through the local codex-adapter.mjs\n# Separated by | for easy parsing.\nPROVIDERS_DATA=(\n \"deepseek|DeepSeek|http://127.0.0.1:${ADAPTER_PORT}/deepseek/v1|DEEPSEEK_API_KEY|deepseek-v4-pro|no|adapter\"\n \"dashscope|Qwen (Bailian)|https://dashscope.aliyuncs.com/compatible-mode/v1|DASHSCOPE_API_KEY|qwen-plus|no|responses\"\n \"moonshot|Moonshot Kimi|http://127.0.0.1:${ADAPTER_PORT}/moonshot/v1|KIMI_API_KEY|kimi-k2.5|no|adapter\"\n \"zhipu|ZhipuAI GLM|http://127.0.0.1:${ADAPTER_PORT}/zhipu/v1|GLM_API_KEY|glm-5.2|yes|adapter\"\n \"ark|Volcengine Ark|https://ark.cn-beijing.volces.com/api/v3|ARK_API_KEY|doubao-seed-2.0-code|yes|responses\"\n \"longcat|Meituan LongCat|https://api.longcat.chat/openai/v1|LONGCAT_API_KEY|LongCat-2.0|yes|responses\"\n \"minimax|MiniMax|https://api.minimaxi.com/v1|MINIMAX_API_KEY|MiniMax-M3|yes|responses\"\n \"tokenhub|Tencent TokenHub|http://127.0.0.1:${ADAPTER_PORT}/tokenhub/v1|HY_API_KEY|hy3-preview|yes|adapter\"\n \"siliconflow|SiliconFlow|http://127.0.0.1:${ADAPTER_PORT}/siliconflow/v1|SF_API_KEY|deepseek-ai/DeepSeek-V4-PRO|yes|adapter\"\n)\n\n# Detect available providers.\navailable_ids=()\navailable_labels=()\nfor entry in \"${PROVIDERS_DATA[@]}\"; do\n IFS='|' read -r pid plabel purl pkey pmodel pnoauth pmode <<< \"$entry\"\n k=\"$(get_key \"$pkey\" || true)\"\n if [ -n \"${k:-}\" ]; then available_ids+=(\"$pid\"); available_labels+=(\"$plabel\"); fi\ndone\n\nif [ ${#available_ids[@]} -eq 0 ]; then\n echo \"codex-setup.sh: no known API keys found. Set one in your ~/.zshrc:\" >&2\n echo \" export DEEPSEEK_API_KEY=sk-...\" >&2\n echo \" export KIMI_API_KEY=sk-...\" >&2\n exit 1\nfi\n\n# Pick default.\nDEFAULT_ID=\"${available_ids[0]}\"; DEFAULT_LABEL=\"${available_labels[0]}\"\nif [ -n \"$FORCE\" ]; then\n found=0; for i in \"${!available_ids[@]}\"; do\n if [ \"${available_ids[$i]}\" = \"$FORCE\" ]; then DEFAULT_ID=\"$FORCE\"; DEFAULT_LABEL=\"${available_labels[$i]}\"; found=1; break; fi\n done\n if [ \"$found\" = \"0\" ]; then echo \"codex-setup.sh: provider '$FORCE' key not set.\" >&2; exit 1; fi\nelif [ ${#available_ids[@]} -gt 1 ] && [ ! -t 0 ]; then\n # Non-interactive with multiple keys — use first.\n :\nelif [ ${#available_ids[@]} -gt 1 ]; then\n echo \"Multiple API keys detected. Which default provider?\"\n for i in \"${!available_ids[@]}\"; do echo \" $((i+1))) ${available_labels[$i]}\"; done\n read -r -p \"Choice [1-${#available_ids[@]}] (default 1): \" choice\n idx=\"${choice:-1}\"\n if [ \"$idx\" -ge 1 ] 2>/dev/null && [ \"$idx\" -le \"${#available_ids[@]}\" ]; then\n DEFAULT_ID=\"${available_ids[$((idx-1))]}\"; DEFAULT_LABEL=\"${available_labels[$((idx-1))]}\"\n fi\nfi\n\n# Find default model.\nDEFAULT_MODEL=\"\"; for entry in \"${PROVIDERS_DATA[@]}\"; do\n IFS='|' read -r pid plabel purl pkey pmodel pnoauth pmode <<< \"$entry\"\n [ \"$pid\" = \"$DEFAULT_ID\" ] && { DEFAULT_MODEL=\"$pmodel\"; break; }\ndone\n\n# ---- Generate config.toml --------------------------------------------------\nCONFIG_PATH=\"$HOME/.codex/config.toml\"\n\ngenerate_toml() {\n echo \"# Generated by codex-setup.sh — $(date +%Y-%m-%d)\"\n echo \"# Re-run codex-setup.sh to refresh when you add new API keys.\"\n echo \"\"\n echo \"model = \\\"$DEFAULT_MODEL\\\"\"\n echo \"model_provider = \\\"$DEFAULT_ID\\\"\"\n echo \"\"\n\n for entry in \"${PROVIDERS_DATA[@]}\"; do\n IFS='|' read -r pid plabel purl pkey pmodel pnoauth pmode <<< \"$entry\"\n # Only include if available.\n found=0; for aid in \"${available_ids[@]}\"; do [ \"$aid\" = \"$pid\" ] && found=1; done\n [ \"$found\" = \"0\" ] && continue\n\n echo \"# ---- $plabel ----\"\n if [ \"$pmode\" = \"adapter\" ]; then\n echo \"# Chat-only upstream: routed through the local codex-adapter.mjs proxy.\"\n echo \"# Start it first: nohup node ${SCRIPT_DIR}/codex-adapter.mjs > ~/.codex/adapter.log 2>&1 &\"\n fi\n echo \"[model_providers.$pid]\"\n echo \"name = \\\"$plabel\\\"\"\n echo \"base_url = \\\"$purl\\\"\"\n echo \"env_key = \\\"$pkey\\\"\"\n echo \"wire_api = \\\"responses\\\"\"\n if [ \"$pnoauth\" = \"yes\" ]; then echo \"requires_openai_auth = false\"; fi\n echo \"\"\n done\n}\n\n# Modern Codex profiles live in separate files (~/.codex/.config.toml);\n# the legacy [profiles.*] tables in config.toml are rejected by current Codex.\nwrite_profile_files() {\n for entry in \"${PROVIDERS_DATA[@]}\"; do\n IFS='|' read -r pid plabel purl pkey pmodel pnoauth pmode <<< \"$entry\"\n found=0; for aid in \"${available_ids[@]}\"; do [ \"$aid\" = \"$pid\" ] && found=1; done\n [ \"$found\" = \"0\" ] && continue\n printf 'model = \"%s\"\\nmodel_provider = \"%s\"\\n' \"$pmodel\" \"$pid\" > \"$HOME/.codex/$pid.config.toml\"\n done\n}\n\n# True if any available provider is adapter-backed.\nneeds_adapter() {\n for entry in \"${PROVIDERS_DATA[@]}\"; do\n IFS='|' read -r pid plabel purl pkey pmodel pnoauth pmode <<< \"$entry\"\n for aid in \"${available_ids[@]}\"; do\n [ \"$aid\" = \"$pid\" ] && [ \"$pmode\" = \"adapter\" ] && return 0\n done\n done\n return 1\n}\n\nif [ \"$DRY_RUN\" = \"1\" ]; then\n generate_toml\n echo \"# Dry run — no file written.\"\nelse\n mkdir -p \"$HOME/.codex\"\n if [ -f \"$CONFIG_PATH\" ]; then\n cp \"$CONFIG_PATH\" \"${CONFIG_PATH}.bak.$(date +%Y%m%d%H%M%S)\"\n echo \"Backed up existing config.\"\n fi\n generate_toml > \"$CONFIG_PATH\"\n write_profile_files\n echo \"✓ Wrote $CONFIG_PATH (default: $DEFAULT_LABEL)\"\n echo \"✓ Wrote profile files: $(for id in \"${available_ids[@]}\"; do printf '%s.config.toml ' \"$id\"; done)\"\n echo \"\"\n echo \"Quick-switch profiles:\"\n for id in \"${available_ids[@]}\"; do echo \" codex --profile $id\"; done\n if needs_adapter; then\n echo \"\"\n echo \"⚠ Some of your providers are chat-only and need the local adapter.\"\n echo \" Start it once (survives until reboot):\"\n echo \" nohup node ${SCRIPT_DIR}/codex-adapter.mjs > ~/.codex/adapter.log 2>&1 &\"\n echo \" Check: curl http://127.0.0.1:${ADAPTER_PORT}/health\"\n fi\nfi\n"}, "886c26a598a8e72ae1a38b4f2e3141cff9e5ba93": {"t": 1785758058.103616, "n": 7789, "h": "0e2d7705c044e507", "c": "#!/usr/bin/env bash\n# codex-setup.sh — generate ~/.codex/config.toml with all your available backends.\n#\n# Detects which API keys you've set (env or shell rc), then writes a Codex\n# config.toml pre-filled with provider blocks for every backend you can use.\n# The first detected key becomes the default provider.\n#\n# Codex only speaks the OpenAI Responses API (Chat Completions support was\n# removed in early 2026). Providers are wired accordingly:\n# - Native Responses (direct): dashscope, ark, longcat, minimax\n# - Chat-only (via local adapter codex-adapter.mjs): deepseek, moonshot,\n# zhipu, tokenhub, siliconflow\n# For adapter-backed providers, start the adapter before running codex:\n# nohup node codex-adapter.mjs > ~/.codex/adapter.log 2>&1 &\n#\n# Usage:\n# ./codex-setup.sh # interactive: pick from detected keys\n# ./codex-setup.sh --dry-run # print the config, don't write it\n# ./codex-setup.sh --force deepseek # set deepseek as default\n\nset -euo pipefail\n\nDRY_RUN=0; FORCE=\"\"\nwhile [ $# -gt 0 ]; do\n case \"$1\" in\n --dry-run) DRY_RUN=1 ;; --force) FORCE=\"$2\"; shift ;;\n *) echo \"codex-setup.sh: unknown option: $1\" >&2; exit 1 ;;\n esac; shift\ndone\n\nget_key() {\n local var=\"$1\"\n if [ -n \"${!var:-}\" ]; then printf '%s' \"${!var}\"; return 0; fi\n local f candidate\n for f in \"$HOME/.zshrc\" \"$HOME/.bashrc\" \"$HOME/.bash_profile\" \"$HOME/.profile\"; do\n [ -f \"$f\" ] || continue\n candidate=\"$(grep -E \"^[[:space:]]*(export[[:space:]]+)?${var}=\" \"$f\" 2>/dev/null|tail -1|sed -E \"s/^[[:space:]]*(export[[:space:]]+)?${var}=//\"|sed -E 's/^\"(.*)\"$/\\1/; s/^'\"'\"'(.*)'\"'\"'$/\\1/'||true)\"\n if [ -n \"${candidate:-}\" ]; then printf '%s' \"$candidate\"; return 0; fi\n done; return 1\n}\n\n# Adapter port for chat-only providers (codex-adapter.mjs).\nADAPTER_PORT=\"${CODEX_ADAPTER_PORT:-8317}\"\nSCRIPT_DIR=\"$(cd \"$(dirname \"$0\")\" && pwd)\"\n\n# Provider data: id label base_url key_var model need_noauth mode\n# mode: responses = provider natively supports the OpenAI Responses API\n# adapter = chat-only; routed through the local codex-adapter.mjs\n# Separated by | for easy parsing.\nPROVIDERS_DATA=(\n \"deepseek|DeepSeek|http://127.0.0.1:${ADAPTER_PORT}/deepseek/v1|DEEPSEEK_API_KEY|deepseek-v4-pro|no|adapter\"\n \"dashscope|Qwen (Bailian)|https://dashscope.aliyuncs.com/compatible-mode/v1|DASHSCOPE_API_KEY|qwen-plus|no|responses\"\n \"moonshot|Moonshot Kimi|http://127.0.0.1:${ADAPTER_PORT}/moonshot/v1|KIMI_API_KEY|kimi-k2.5|no|adapter\"\n \"zhipu|ZhipuAI GLM|http://127.0.0.1:${ADAPTER_PORT}/zhipu/v1|GLM_API_KEY|glm-5.2|yes|adapter\"\n \"ark|Volcengine Ark|https://ark.cn-beijing.volces.com/api/v3|ARK_API_KEY|doubao-seed-2.0-code|yes|responses\"\n \"longcat|Meituan LongCat|https://api.longcat.chat/openai/v1|LONGCAT_API_KEY|LongCat-2.0|yes|responses\"\n \"minimax|MiniMax|https://api.minimaxi.com/v1|MINIMAX_API_KEY|MiniMax-M3|yes|responses\"\n \"tokenhub|Tencent TokenHub|http://127.0.0.1:${ADAPTER_PORT}/tokenhub/v1|HY_API_KEY|hy3-preview|yes|adapter\"\n \"siliconflow|SiliconFlow|http://127.0.0.1:${ADAPTER_PORT}/siliconflow/v1|SF_API_KEY|deepseek-ai/DeepSeek-V4-PRO|yes|adapter\"\n)\n\n# Detect available providers.\navailable_ids=()\navailable_labels=()\nfor entry in \"${PROVIDERS_DATA[@]}\"; do\n IFS='|' read -r pid plabel purl pkey pmodel pnoauth pmode <<< \"$entry\"\n k=\"$(get_key \"$pkey\" || true)\"\n if [ -n \"${k:-}\" ]; then available_ids+=(\"$pid\"); available_labels+=(\"$plabel\"); fi\ndone\n\nif [ ${#available_ids[@]} -eq 0 ]; then\n echo \"codex-setup.sh: no known API keys found. Set one in your ~/.zshrc:\" >&2\n echo \" export DEEPSEEK_API_KEY=sk-...\" >&2\n echo \" export KIMI_API_KEY=sk-...\" >&2\n exit 1\nfi\n\n# Pick default.\nDEFAULT_ID=\"${available_ids[0]}\"; DEFAULT_LABEL=\"${available_labels[0]}\"\nif [ -n \"$FORCE\" ]; then\n found=0; for i in \"${!available_ids[@]}\"; do\n if [ \"${available_ids[$i]}\" = \"$FORCE\" ]; then DEFAULT_ID=\"$FORCE\"; DEFAULT_LABEL=\"${available_labels[$i]}\"; found=1; break; fi\n done\n if [ \"$found\" = \"0\" ]; then echo \"codex-setup.sh: provider '$FORCE' key not set.\" >&2; exit 1; fi\nelif [ ${#available_ids[@]} -gt 1 ] && [ ! -t 0 ]; then\n # Non-interactive with multiple keys — use first.\n :\nelif [ ${#available_ids[@]} -gt 1 ]; then\n echo \"Multiple API keys detected. Which default provider?\"\n for i in \"${!available_ids[@]}\"; do echo \" $((i+1))) ${available_labels[$i]}\"; done\n read -r -p \"Choice [1-${#available_ids[@]}] (default 1): \" choice\n idx=\"${choice:-1}\"\n if [ \"$idx\" -ge 1 ] 2>/dev/null && [ \"$idx\" -le \"${#available_ids[@]}\" ]; then\n DEFAULT_ID=\"${available_ids[$((idx-1))]}\"; DEFAULT_LABEL=\"${available_labels[$((idx-1))]}\"\n fi\nfi\n\n# Find default model.\nDEFAULT_MODEL=\"\"; for entry in \"${PROVIDERS_DATA[@]}\"; do\n IFS='|' read -r pid plabel purl pkey pmodel pnoauth pmode <<< \"$entry\"\n [ \"$pid\" = \"$DEFAULT_ID\" ] && { DEFAULT_MODEL=\"$pmodel\"; break; }\ndone\n\n# ---- Generate config.toml --------------------------------------------------\nCONFIG_PATH=\"$HOME/.codex/config.toml\"\n\ngenerate_toml() {\n echo \"# Generated by codex-setup.sh — $(date +%Y-%m-%d)\"\n echo \"# Re-run codex-setup.sh to refresh when you add new API keys.\"\n echo \"\"\n echo \"model = \\\"$DEFAULT_MODEL\\\"\"\n echo \"model_provider = \\\"$DEFAULT_ID\\\"\"\n echo \"\"\n\n for entry in \"${PROVIDERS_DATA[@]}\"; do\n IFS='|' read -r pid plabel purl pkey pmodel pnoauth pmode <<< \"$entry\"\n # Only include if available.\n found=0; for aid in \"${available_ids[@]}\"; do [ \"$aid\" = \"$pid\" ] && found=1; done\n [ \"$found\" = \"0\" ] && continue\n\n echo \"# ---- $plabel ----\"\n if [ \"$pmode\" = \"adapter\" ]; then\n echo \"# Chat-only upstream: routed through the local codex-adapter.mjs proxy.\"\n echo \"# Start it first: nohup node ${SCRIPT_DIR}/codex-adapter.mjs > ~/.codex/adapter.log 2>&1 &\"\n fi\n echo \"[model_providers.$pid]\"\n echo \"name = \\\"$plabel\\\"\"\n echo \"base_url = \\\"$purl\\\"\"\n echo \"env_key = \\\"$pkey\\\"\"\n echo \"wire_api = \\\"responses\\\"\"\n if [ \"$pnoauth\" = \"yes\" ]; then echo \"requires_openai_auth = false\"; fi\n echo \"\"\n done\n}\n\n# Modern Codex profiles live in separate files (~/.codex/.config.toml);\n# the legacy [profiles.*] tables in config.toml are rejected by current Codex.\nwrite_profile_files() {\n for entry in \"${PROVIDERS_DATA[@]}\"; do\n IFS='|' read -r pid plabel purl pkey pmodel pnoauth pmode <<< \"$entry\"\n found=0; for aid in \"${available_ids[@]}\"; do [ \"$aid\" = \"$pid\" ] && found=1; done\n [ \"$found\" = \"0\" ] && continue\n printf 'model = \"%s\"\\nmodel_provider = \"%s\"\\n' \"$pmodel\" \"$pid\" > \"$HOME/.codex/$pid.config.toml\"\n done\n}\n\n# True if any available provider is adapter-backed.\nneeds_adapter() {\n for entry in \"${PROVIDERS_DATA[@]}\"; do\n IFS='|' read -r pid plabel purl pkey pmodel pnoauth pmode <<< \"$entry\"\n for aid in \"${available_ids[@]}\"; do\n [ \"$aid\" = \"$pid\" ] && [ \"$pmode\" = \"adapter\" ] && return 0\n done\n done\n return 1\n}\n\nif [ \"$DRY_RUN\" = \"1\" ]; then\n generate_toml\n echo \"# Dry run — no file written.\"\nelse\n mkdir -p \"$HOME/.codex\"\n if [ -f \"$CONFIG_PATH\" ]; then\n cp \"$CONFIG_PATH\" \"${CONFIG_PATH}.bak.$(date +%Y%m%d%H%M%S)\"\n echo \"Backed up existing config.\"\n fi\n generate_toml > \"$CONFIG_PATH\"\n write_profile_files\n echo \"✓ Wrote $CONFIG_PATH (default: $DEFAULT_LABEL)\"\n echo \"✓ Wrote profile files: $(for id in \"${available_ids[@]}\"; do printf '%s.config.toml ' \"$id\"; done)\"\n echo \"\"\n echo \"Quick-switch profiles:\"\n for id in \"${available_ids[@]}\"; do echo \" codex --profile $id\"; done\n if needs_adapter; then\n echo \"\"\n echo \"⚠ Some of your providers are chat-only and need the local adapter.\"\n echo \" Start it once (survives until reboot):\"\n echo \" nohup node ${SCRIPT_DIR}/codex-adapter.mjs > ~/.codex/adapter.log 2>&1 &\"\n echo \" Check: curl http://127.0.0.1:${ADAPTER_PORT}/health\"\n fi\nfi\n"}, "cb94935e63131305afbfe7fb1ed68f5fb4ec0045": {"t": 1785758059.8834555, "n": 5434, "h": "4769cdfaedc5bf10", "c": "#!/usr/bin/env bash\n# codex-setup.sh — generate ~/.codex/config.toml with all your available backends.\n#\n# Detects which API keys you've set (env or shell rc), then writes a Codex\n# config.toml pre-filled with provider blocks for every backend you can use.\n# The first detected key becomes the default provider.\n#\n# Usage:\n# ./codex-setup.sh # interactive: pick from detected keys\n# ./codex-setup.sh --dry-run # print the config, don't write it\n# ./codex-setup.sh --force deepseek # set deepseek as default\n\nset -euo pipefail\n\nDRY_RUN=0; FORCE=\"\"\nwhile [ $# -gt 0 ]; do\n case \"$1\" in\n --dry-run) DRY_RUN=1 ;; --force) FORCE=\"$2\"; shift ;;\n *) echo \"codex-setup.sh: unknown option: $1\" >&2; exit 1 ;;\n esac; shift\ndone\n\nget_key() {\n local var=\"$1\"\n if [ -n \"${!var:-}\" ]; then printf '%s' \"${!var}\"; return 0; fi\n local f candidate\n for f in \"$HOME/.zshrc\" \"$HOME/.bashrc\" \"$HOME/.bash_profile\" \"$HOME/.profile\"; do\n [ -f \"$f\" ] || continue\n candidate=\"$(grep -E \"^[[:space:]]*(export[[:space:]]+)?${var}=\" \"$f\" 2>/dev/null|tail -1|sed -E \"s/^[[:space:]]*(export[[:space:]]+)?${var}=//\"|sed -E 's/^\"(.*)\"$/\\1/; s/^'\"'\"'(.*)'\"'\"'$/\\1/'||true)\"\n if [ -n \"${candidate:-}\" ]; then printf '%s' \"$candidate\"; return 0; fi\n done; return 1\n}\n\n# Provider data: id label base_url key_var model need_noauth\n# Separated by | for easy parsing.\nPROVIDERS_DATA=(\n \"deepseek|DeepSeek|https://api.deepseek.com/v1|DEEPSEEK_API_KEY|deepseek-chat|no\"\n \"dashscope|Qwen (Bailian)|https://dashscope.aliyuncs.com/compatible-mode/v1|DASHSCOPE_API_KEY|qwen-plus|no\"\n \"moonshot|Moonshot Kimi|https://api.moonshot.cn/v1|KIMI_API_KEY|kimi-k2.5|no\"\n \"zhipu|ZhipuAI GLM|https://open.bigmodel.cn/api/paas/v4|GLM_API_KEY|glm-4-flash|yes\"\n \"ark|Volcengine Ark|https://ark.cn-beijing.volces.com/api/v3|ARK_API_KEY|doubao-seed-2.0-code|yes\"\n \"longcat|Meituan LongCat|https://api.longcat.chat/openai|LONGCAT_API_KEY|LongCat-2.0|yes\"\n \"minimax|MiniMax|https://api.minimaxi.com/v1|MINIMAX_API_KEY|MiniMax-M3|yes\"\n \"tokenhub|Tencent TokenHub|https://api.lkeap.cloud.tencent.com/v1|HY_API_KEY|hy3-preview|yes\"\n \"siliconflow|SiliconFlow|https://api.siliconflow.cn/v1|SF_API_KEY|deepseek-ai/DeepSeek-V4-PRO|yes\"\n)\n\n# Detect available providers.\navailable_ids=()\navailable_labels=()\nfor entry in \"${PROVIDERS_DATA[@]}\"; do\n IFS='|' read -r pid plabel purl pkey pmodel pnoauth <<< \"$entry\"\n k=\"$(get_key \"$pkey\" || true)\"\n if [ -n \"${k:-}\" ]; then available_ids+=(\"$pid\"); available_labels+=(\"$plabel\"); fi\ndone\n\nif [ ${#available_ids[@]} -eq 0 ]; then\n echo \"codex-setup.sh: no known API keys found. Set one in your ~/.zshrc:\" >&2\n echo \" export DEEPSEEK_API_KEY=sk-...\" >&2\n echo \" export KIMI_API_KEY=sk-...\" >&2\n exit 1\nfi\n\n# Pick default.\nDEFAULT_ID=\"${available_ids[0]}\"; DEFAULT_LABEL=\"${available_labels[0]}\"\nif [ -n \"$FORCE\" ]; then\n found=0; for i in \"${!available_ids[@]}\"; do\n if [ \"${available_ids[$i]}\" = \"$FORCE\" ]; then DEFAULT_ID=\"$FORCE\"; DEFAULT_LABEL=\"${available_labels[$i]}\"; found=1; break; fi\n done\n if [ \"$found\" = \"0\" ]; then echo \"codex-setup.sh: provider '$FORCE' key not set.\" >&2; exit 1; fi\nelif [ ${#available_ids[@]} -gt 1 ] && [ ! -t 0 ]; then\n # Non-interactive with multiple keys — use first.\n :\nelif [ ${#available_ids[@]} -gt 1 ]; then\n echo \"Multiple API keys detected. Which default provider?\"\n for i in \"${!available_ids[@]}\"; do echo \" $((i+1))) ${available_labels[$i]}\"; done\n read -r -p \"Choice [1-${#available_ids[@]}] (default 1): \" choice\n idx=\"${choice:-1}\"\n if [ \"$idx\" -ge 1 ] 2>/dev/null && [ \"$idx\" -le \"${#available_ids[@]}\" ]; then\n DEFAULT_ID=\"${available_ids[$((idx-1))]}\"; DEFAULT_LABEL=\"${available_labels[$((idx-1))]}\"\n fi\nfi\n\n# Find default model.\nDEFAULT_MODEL=\"\"; for entry in \"${PROVIDERS_DATA[@]}\"; do\n IFS='|' read -r pid plabel purl pkey pmodel pnoauth <<< \"$entry\"\n [ \"$pid\" = \"$DEFAULT_ID\" ] && { DEFAULT_MODEL=\"$pmodel\"; break; }\ndone\n\n# ---- Generate config.toml --------------------------------------------------\nCONFIG_PATH=\"$HOME/.codex/config.toml\"\n\ngenerate_toml() {\n echo \"# Generated by codex-setup.sh — $(date +%Y-%m-%d)\"\n echo \"# Re-run codex-setup.sh to refresh when you add new API keys.\"\n echo \"\"\n echo \"model = \\\"$DEFAULT_MODEL\\\"\"\n echo \"model_provider = \\\"$DEFAULT_ID\\\"\"\n echo \"\"\n\n for entry in \"${PROVIDERS_DATA[@]}\"; do\n IFS='|' read -r pid plabel purl pkey pmodel pnoauth <<< \"$entry\"\n # Only include if available.\n found=0; for aid in \"${available_ids[@]}\"; do [ \"$aid\" = \"$pid\" ] && found=1; done\n [ \"$found\" = \"0\" ] && continue\n\n echo \"# ---- $plabel ----\"\n echo \"[model_providers.$pid]\"\n echo \"name = \\\"$plabel\\\"\"\n echo \"base_url = \\\"$purl\\\"\"\n echo \"env_key = \\\"$pkey\\\"\"\n echo \"wire_api = \\\"chat\\\"\"\n if [ \"$pnoauth\" = \"yes\" ]; then echo \"requires_openai_auth = false\"; fi\n echo \"\"\n echo \"[profiles.$pid]\"\n echo \"model_provider = \\\"$pid\\\"\"\n echo \"model = \\\"$pmodel\\\"\"\n echo \"\"\n done\n}\n\nif [ \"$DRY_RUN\" = \"1\" ]; then\n generate_toml\n echo \"# Dry run — no file written.\"\nelse\n mkdir -p \"$HOME/.codex\"\n if [ -f \"$CONFIG_PATH\" ]; then\n cp \"$CONFIG_PATH\" \"${CONFIG_PATH}.bak.$(date +%Y%m%d%H%M%S)\"\n echo \"Backed up existing config.\"\n fi\n generate_toml > \"$CONFIG_PATH\"\n echo \"✓ Wrote $CONFIG_PATH (default: $DEFAULT_LABEL)\"\n echo \"\"\n echo \"Quick-switch profiles:\"\n for id in \"${available_ids[@]}\"; do echo \" codex --profile $id\"; done\nfi\n"}}, "hyclaude": {"c07db31916dca8077b9124f5c098258f9607b016": {"t": 1785809840.6835127, "n": 5124, "h": "0dc509f92e74911a", "c": "#!/usr/bin/env bash\n# shellcheck disable=SC2034 # variables consumed by lib/common.sh\n# hyclaude — launch Claude Code on Tencent TokenHub's Anthropic-compatible API.\n#\n# Tencent TokenHub is a multi-model aggregator — one subscription gives access\n# to Hunyuan (HY3), DeepSeek, GLM, Kimi, MiniMax, Qwen, and more.\n#\n# Endpoint:\n# - Token Plan (recommended): https://api.lkeap.cloud.tencent.com/plan/anthropic\n# - Coding Plan: https://api.lkeap.cloud.tencent.com/coding/anthropic\n#\n# Reads HY_API_KEY from the environment first, then falls back to\n# ~/.zshrc / ~/.bashrc / ~/.bash_profile / ~/.profile if not already exported.\n#\n# Quick start (no install needed):\n# chmod +x hyclaude\n# ./hyclaude\n#\n# Optional — make it globally available:\n# sudo mv hyclaude /usr/local/bin/ && sudo chmod +x /usr/local/bin/hyclaude\n#\n# Use:\n# hyclaude # hy3-preview (Tencent default)\n# hyclaude fast # hy-mt2-lite (cheap / fast)\n# hyclaude deepseek # deepseek-v4-pro\n# hyclaude kimi # kimi-k2.7-code\n# hyclaude glm # glm-5.2\n# hyclaude minimax # minimax-m3\n# hyclaude qwen # qwen3.5-plus\n# hyclaude long # request max context window\n# hyclaude effort max # set reasoning effort (low|medium|high|xhigh|max)\n# hyclaude update # git pull latest from this repo\n# hyclaude --help # any remaining flag is forwarded to claude\n#\n# Optional env overrides:\n# HY_MODEL=hy3-preview # main model (any model on TokenHub)\n# HY_FLASH_MODEL=hy-mt2-lite # flash / haiku / subagent tier\n# HY_BASE_URL=https://.../anthropic # custom Anthropic-compatible base URL\n# HY_CTX=1048576 # max context tokens\n# HY_OUTPUT=8000 # cap output tokens\n# HY_EFFORT=max # CLAUDE_CODE_EFFORT_LEVEL\n#\n# Get your API key: https://cloud.tencent.com/product/lkeap\n\nset -euo pipefail\n\n# Resolve symlink to find the real script directory.\n_SELF=\"$0\"\nif [ -L \"$_SELF\" ]; then\n _LINK=\"$(readlink \"$_SELF\")\"\n case \"$_LINK\" in\n /*) _SELF=\"$_LINK\" ;;\n *) _SELF=\"$(cd \"$(dirname \"$_SELF\")\" && pwd)/$_LINK\" ;;\n esac\nfi\nSELF_DIR=\"$(cd \"$(dirname \"$_SELF\")\" && pwd)\"\nif [ -f \"$SELF_DIR/lib/common.sh\" ]; then source \"$SELF_DIR/lib/common.sh\"\nelif [ -f \"$SELF_DIR/../lib/common.sh\" ]; then source \"$SELF_DIR/../lib/common.sh\"\nelse echo \"hyclaude: cannot find lib/common.sh. Reinstall or cd to repo.\" >&2; exit 1; fi\n\ncheck_version \"hyclaude\" \"$@\"\n\nPRO_MODEL=\"${HY_MODEL:-hy3-preview}\"\nFLASH_MODEL=\"${HY_FLASH_MODEL:-hy-mt2-lite}\"\n\nif [ $# -gt 0 ] && [ \"$1\" = \"update\" ]; then\n do_update \"hyclaude\" \"HYCLAUDE_HOME\"\nfi\n\nAPI_KEY=\"$(resolve_api_key \"HY_API_KEY\")\"\nif [ -z \"$API_KEY\" ]; then\n echo \"❌ HY_API_KEY not found.\" >&2\n echo \" Add one line to ~/.zshrc or ~/.bashrc: export HY_API_KEY=your_api_key\" >&2\n echo \" Get your key at: https://cloud.tencent.com/product/lkeap\" >&2\n exit 1\nfi\n\nBASE_URL=\"${HY_BASE_URL:-https://api.lkeap.cloud.tencent.com/plan/anthropic}\"\n\nLONG_CTX=0\nEFFORT=\"${HY_EFFORT:-}\"\n\nMAIN_MODEL=\"\"\nwhile [ $# -gt 0 ]; do\n case \"$1\" in\n # Tier aliases\n max|pro|code) MAIN_MODEL=\"$PRO_MODEL\"; shift ;;\n fast|flash|lite) MAIN_MODEL=\"$FLASH_MODEL\"; shift ;;\n # Provider aliases\n kimi) MAIN_MODEL=\"kimi-k2.7-code\"; shift ;;\n kimi-pro|kimi-k2) MAIN_MODEL=\"kimi-k2.6\"; shift ;;\n deepseek) MAIN_MODEL=\"deepseek-v4-pro\"; shift ;;\n deepseek-flash) MAIN_MODEL=\"deepseek-v4-flash\"; shift ;;\n glm) MAIN_MODEL=\"glm-5.2\"; shift ;;\n minimax) MAIN_MODEL=\"minimax-m3\"; shift ;;\n qwen) MAIN_MODEL=\"qwen3.5-plus\"; shift ;;\n # Context & effort\n long) LONG_CTX=1; shift ;;\n effort)\n case \"${2:-}\" in\n low|medium|high|xhigh|max) EFFORT=\"$2\"; shift 2 ;;\n *) echo \"hyclaude: invalid effort level '${2:-}'. Use: low medium high xhigh max\" >&2; exit 1 ;;\n esac\n ;;\n --) shift; break ;;\n *) break ;;\n esac\ndone\n\nif [ -z \"$MAIN_MODEL\" ]; then MAIN_MODEL=\"$PRO_MODEL\"; fi\n\n# Pick a smart alternate for the /model picker.\ncase \"$MAIN_MODEL\" in\n \"$PRO_MODEL\") OTHER_MODEL=\"$FLASH_MODEL\"; OTHER_DESC=\"HY MT2 Lite — fast / cheap tier\" ;;\n \"$FLASH_MODEL\") OTHER_MODEL=\"$PRO_MODEL\"; OTHER_DESC=\"HY3 Preview — Tencent flagship\" ;;\n kimi-k2.7-code) OTHER_MODEL=\"kimi-k2.6\"; OTHER_DESC=\"Kimi K2.6 — full reasoning\" ;;\n kimi-k2.6) OTHER_MODEL=\"kimi-k2.7-code\"; OTHER_DESC=\"Kimi K2.7 Code — code specialist\" ;;\n deepseek-v4-pro) OTHER_MODEL=\"deepseek-v4-flash\"; OTHER_DESC=\"DeepSeek V4 Flash\" ;;\n deepseek-v4-flash) OTHER_MODEL=\"deepseek-v4-pro\"; OTHER_DESC=\"DeepSeek V4 Pro\" ;;\n *) OTHER_MODEL=\"$PRO_MODEL\"; OTHER_DESC=\"HY3 Preview — Tencent flagship\" ;;\nesac\n\nexport_anthropic_base\nexport CLAUDE_CODE_SUBAGENT_MODEL=\"$FLASH_MODEL\"\nset_custom_model \"$OTHER_MODEL\" \"$MAIN_MODEL\" \"$OTHER_DESC\"\n\nCTX=\"${HY_CTX:-}\"\nOUTPUT_CAP=\"${HY_OUTPUT:-}\"\napply_context_and_effort\n\nshow_banner_and_launch \"TokenHub\" \"$@\"\n"}}, "hyclaude.ps1": {"c07db31916dca8077b9124f5c098258f9607b016": {"t": 1785809841.2305827, "n": 6800, "h": "b9bc4931150b2a82", "c": "#!/usr/bin/env pwsh\n# hyclaude.ps1 — launch Claude Code on Tencent TokenHub's Anthropic-compatible API (Windows port).\n#\n# Tencent TokenHub aggregates Hunyuan, DeepSeek, GLM, Kimi, MiniMax, Qwen.\n# One subscription, one endpoint, many models.\n#\n# Endpoint: https://api.lkeap.cloud.tencent.com/plan/anthropic\n# Reads HY_API_KEY from process env first, then User/Machine env vars.\n#\n# Use:\n# pwsh -File ./hyclaude.ps1 # hy3-preview (Tencent default)\n# pwsh -File ./hyclaude.ps1 fast # hy-mt2-lite\n# pwsh -File ./hyclaude.ps1 kimi # kimi-k2.7-code\n# pwsh -File ./hyclaude.ps1 deepseek # deepseek-v4-pro\n# pwsh -File ./hyclaude.ps1 glm # glm-5.2\n# pwsh -File ./hyclaude.ps1 minimax # minimax-m3\n# pwsh -File ./hyclaude.ps1 qwen # qwen3.5-plus\n# pwsh -File ./hyclaude.ps1 long # max context window\n# pwsh -File ./hyclaude.ps1 effort max # set effort (low|medium|high|xhigh|max)\n# pwsh -File ./hyclaude.ps1 update # git pull\n#\n# Optional env overrides:\n# $env:HY_MODEL = 'hy3-preview' # main model\n# $env:HY_FLASH_MODEL = 'hy-mt2-lite' # flash tier\n# $env:HY_BASE_URL = 'https://.../anthropic' # custom base URL\n# $env:HY_CTX = '1048576' # max context tokens\n# $env:HY_OUTPUT = '8000' # cap output tokens\n# $env:HY_EFFORT = 'max' # CLAUDE_CODE_EFFORT_LEVEL\n\n[CmdletBinding()]\nparam(\n [Parameter(ValueFromRemainingArguments = $true)]\n [string[]]$Rest\n)\n\n$ErrorActionPreference = 'Stop'\n\nif ($PSVersionTable.PSVersion.Major -lt 7) {\n Write-Error @\"\nhyclaude.ps1: PowerShell 7+ required (you're on $($PSVersionTable.PSVersion)).\nInstall once: winget install Microsoft.PowerShell\nThen: pwsh -File .\\hyclaude.ps1\n\"@\n exit 1\n}\n\nfunction Invoke-HyclaudeUpdate {\n $repo = $null; $selfDir = Split-Path -Parent $PSCommandPath\n if (Test-Path (Join-Path $selfDir '.git')) { $repo = $selfDir }\n if (-not $repo -and $env:HYCLAUDE_HOME) { $repo = $env:HYCLAUDE_HOME }\n if (-not $repo) { $c = Join-Path $env:USERPROFILE 'github\\xxclaude'; if (Test-Path (Join-Path $c '.git')) { $repo = $c } }\n if (-not $repo) { Write-Error \"hyclaude: cannot find xxclaude repo.\"; exit 1 }\n Write-Host \"hyclaude: pulling latest from $repo ...\"\n git -C $repo pull; if ($LASTEXITCODE -ne 0) { Write-Error 'hyclaude: git pull failed.'; exit 1 }\n Write-Host 'hyclaude: updated.'; exit 0\n}\n\nfunction Resolve-ApiKey {\n if ($env:HY_API_KEY) { return $env:HY_API_KEY }\n foreach ($scope in 'User','Machine') { $v=[Environment]::GetEnvironmentVariable('HY_API_KEY',$scope); if($v){return $v} }\n Write-Error \"HY_API_KEY not found.`n setx HY_API_KEY `\"your_api_key`\"`n Get your key: https://cloud.tencent.com/product/lkeap\"; exit 1\n}\n\n$mainModel = $null; $LongCtx = $false; $Effort = if($env:HY_EFFORT){$env:HY_EFFORT}else{''}\n$remaining = @(); $rest = @($Rest); $i = 0\n:argloop while ($i -lt $rest.Count) {\n $a = $rest[$i]\n switch -CaseSensitive ($a) {\n 'update' { Invoke-HyclaudeUpdate }\n 'max' { $i++; break }; 'pro' { $i++; break }; 'code' { $i++; break }\n 'fast' { $mainModel = 'hy-mt2-lite'; $i++; break }\n 'flash' { $mainModel = 'hy-mt2-lite'; $i++; break }\n 'lite' { $mainModel = 'hy-mt2-lite'; $i++; break }\n 'kimi' { $mainModel = 'kimi-k2.7-code'; $i++; break }\n 'kimi-pro' { $mainModel = 'kimi-k2.6'; $i++; break }\n 'kimi-k2' { $mainModel = 'kimi-k2.6'; $i++; break }\n 'deepseek' { $mainModel = 'deepseek-v4-pro'; $i++; break }\n 'deepseek-flash'{ $mainModel = 'deepseek-v4-flash'; $i++; break }\n 'glm' { $mainModel = 'glm-5.2'; $i++; break }\n 'minimax' { $mainModel = 'minimax-m3'; $i++; break }\n 'qwen' { $mainModel = 'qwen3.5-plus'; $i++; break }\n 'long' { $LongCtx=$true; $i++; break }\n 'effort' { $i++; if($i -lt $rest.Count){$l=$rest[$i];if($l -in 'low','medium','high','xhigh','max'){$Effort=$l;$i++;break}else{Write-Error \"hyclaude: invalid effort level '$l'. Use: low medium high xhigh max\";exit 1}}else{Write-Error \"hyclaude: 'effort' requires a level\";exit 1} }\n '--' { $i++; if($i -lt $rest.Count){$remaining+=$rest[$i..($rest.Count-1)]}; break argloop }\n default { $remaining+=$rest[$i..($rest.Count-1)]; break argloop }\n }\n}\n\n$apiKey = Resolve-ApiKey\n$baseUrl = if($env:HY_BASE_URL) {$env:HY_BASE_URL} else{'https://api.lkeap.cloud.tencent.com/plan/anthropic'}\n$proModel = if($env:HY_MODEL) {$env:HY_MODEL} else{'hy3-preview'}\n$flashModel = if($env:HY_FLASH_MODEL){$env:HY_FLASH_MODEL} else{'hy-mt2-lite'}\nif(-not $mainModel){$mainModel=$proModel}\n\nswitch -Wildcard ($mainModel) {\n $proModel { $otherModel=$flashModel; $otherDesc='HY MT2 Lite — fast / cheap tier' }\n $flashModel { $otherModel=$proModel; $otherDesc='HY3 Preview — Tencent flagship' }\n 'kimi-k2.7-code' { $otherModel='kimi-k2.6'; $otherDesc='Kimi K2.6' }\n 'kimi-k2.6' { $otherModel='kimi-k2.7-code'; $otherDesc='Kimi K2.7 Code' }\n 'deepseek-v4-pro' { $otherModel='deepseek-v4-flash'; $otherDesc='DeepSeek V4 Flash' }\n 'deepseek-v4-flash'{ $otherModel='deepseek-v4-pro'; $otherDesc='DeepSeek V4 Pro' }\n default { $otherModel=$proModel; $otherDesc='HY3 Preview' }\n}\n\n$env:ANTHROPIC_API_KEY=$null\n$env:ANTHROPIC_BASE_URL=$baseUrl; $env:ANTHROPIC_AUTH_TOKEN=$apiKey\n$env:ANTHROPIC_MODEL=$mainModel; $env:ANTHROPIC_DEFAULT_OPUS_MODEL=$mainModel; $env:ANTHROPIC_DEFAULT_SONNET_MODEL=$mainModel\n$env:ANTHROPIC_DEFAULT_HAIKU_MODEL=$flashModel; $env:CLAUDE_CODE_SUBAGENT_MODEL=$flashModel\n$env:CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC='1'\nif($otherModel -ne $mainModel){\n $env:ANTHROPIC_CUSTOM_MODEL_OPTION=$otherModel; $env:ANTHROPIC_CUSTOM_MODEL_OPTION_NAME=$otherModel\n $env:ANTHROPIC_CUSTOM_MODEL_OPTION_DESCRIPTION=$otherDesc\n}\nif($Effort){$env:CLAUDE_CODE_EFFORT_LEVEL=$Effort}\n$ctx=if($env:HY_CTX){$env:HY_CTX}elseif($LongCtx){'1048576'}else{''}\nif($ctx){$env:CLAUDE_CODE_MAX_CONTEXT_TOKENS=$ctx;$env:DISABLE_COMPACT='1'}\nif($env:HY_OUTPUT){$env:CLAUDE_CODE_MAX_OUTPUT_TOKENS=$env:HY_OUTPUT}\n\nif(-not(Get-Command claude -ErrorAction SilentlyContinue)){Write-Error \"hyclaude: `claude` CLI not found.`n Install: npm install -g @anthropic-ai/claude-code\";exit 1}\n\n$banner=\"🚀 Claude Code on TokenHub → $mainModel ($baseUrl)\"\nif($ctx){$banner+=\" | ctx=$ctx\"}; if($Effort){$banner+=\" | effort=$Effort\"}\nif($otherModel -ne $mainModel){$banner+=' (switch mid-session via /model)'}\nWrite-Host $banner; & claude @remaining; exit $LASTEXITCODE\n"}}, "hyclaude-desktop": {"c07db31916dca8077b9124f5c098258f9607b016": {"t": 1785809841.2772586, "n": 5655, "h": "ea690797839ee745", "c": "#!/usr/bin/env bash\n# hyclaude-desktop — configure Claude Desktop to use Tencent TokenHub as inference backend.\n#\n# Edits ~/Library/Application Support/Claude-3p/configLibrary/{_meta,}.json\n# and restarts Claude Desktop. macOS only.\n#\n# Usage:\n# hyclaude-desktop # configure to HY3 Preview and restart\n# hyclaude-desktop kimi # use kimi-k2.7-code\n# hyclaude-desktop deepseek # use deepseek-v4-pro\n# hyclaude-desktop glm # use glm-5.2\n# hyclaude-desktop minimax # use minimax-m3\n# hyclaude-desktop qwen # use qwen3.5-plus\n# hyclaude-desktop update # git pull\n# hyclaude-desktop -h # help\n#\n# Reads HY_API_KEY from env or ~/.zshrc & friends (else prompts).\n# Base URL: https://api.lkeap.cloud.tencent.com/plan/anthropic\n\nset -euo pipefail\n\nCONFIG_DIR=\"$HOME/Library/Application Support/Claude-3p/configLibrary\"\nMETA=\"$CONFIG_DIR/_meta.json\"\nENTRY_NAME=\"hyclaude-desktop\"\nAUTH_SCHEME=\"bearer\"\nMAIN_MODEL=\"hy3-preview\"\nFAST_MODEL=\"hy-mt2-lite\"\n\nwhile [[ $# -gt 0 ]]; do\n case \"$1\" in\n -h|--help) sed -n '2,17p' \"$0\" | sed 's/^# \\{0,1\\}//'; exit 0 ;;\n update) SELF_DIR=\"$(cd \"$(dirname \"$0\")\" && pwd)\"\n echo \"hyclaude-desktop: pulling latest from $SELF_DIR ...\"\n git -C \"$SELF_DIR\" pull && echo \"hyclaude-desktop: updated.\" || { echo \"git pull failed.\" >&2; exit 1; }; exit 0 ;;\n max|pro|code) MAIN_MODEL=\"hy3-preview\"; FAST_MODEL=\"hy-mt2-lite\"; shift ;;\n fast|flash|lite) MAIN_MODEL=\"hy-mt2-lite\"; FAST_MODEL=\"hy-mt2-lite\"; shift ;;\n kimi) MAIN_MODEL=\"kimi-k2.7-code\"; FAST_MODEL=\"hy-mt2-lite\"; shift ;;\n kimi-pro|kimi-k2) MAIN_MODEL=\"kimi-k2.6\"; FAST_MODEL=\"kimi-k2.6\"; shift ;;\n deepseek) MAIN_MODEL=\"deepseek-v4-pro\"; FAST_MODEL=\"deepseek-v4-flash\"; shift ;;\n deepseek-flash) MAIN_MODEL=\"deepseek-v4-flash\"; FAST_MODEL=\"deepseek-v4-flash\"; shift ;;\n glm) MAIN_MODEL=\"glm-5.2\"; FAST_MODEL=\"glm-5.2\"; shift ;;\n minimax) MAIN_MODEL=\"minimax-m3\"; FAST_MODEL=\"minimax-m3\"; shift ;;\n qwen) MAIN_MODEL=\"qwen3.5-plus\"; FAST_MODEL=\"qwen3.5-plus\"; shift ;;\n *) echo \"hyclaude-desktop: unknown argument: $1\" >&2; exit 2 ;;\n esac\ndone\n\npreflight() {\n [[ \"$(uname)\" == \"Darwin\" ]] || { echo \"macOS only.\" >&2; exit 1; }\n [[ -d \"/Applications/Claude.app\" ]] || { echo \"Claude.app not found.\" >&2; exit 1; }\n [[ -x \"/usr/bin/jq\" ]] || { echo \"jq not found.\" >&2; exit 1; }\n local ds=\"$HOME/Library/Application Support/Claude/developer_settings.json\"\n if [[ ! -f \"$ds\" ]] || ! /usr/bin/jq -e '.allowDevTools==true' \"$ds\" >/dev/null 2>&1; then\n echo \"hyclaude-desktop: Enable Developer Mode first (Help → Troubleshooting → Enable Developer Mode)\" >&2; exit 1\n fi\n}\n\nresolve_api_key() {\n if [[ -n \"${HY_API_KEY:-}\" ]]; then printf '%s' \"$HY_API_KEY\"; return 0; fi\n local rc found=\"\"\n for rc in \"$HOME/.zshrc\" \"$HOME/.bashrc\" \"$HOME/.bash_profile\" \"$HOME/.profile\"; do\n [[ -r \"$rc\" ]] || continue\n 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)\"\n if [[ -n \"$found\" ]]; then printf '%s' \"$found\"; return 0; fi\n done\n local key\n key=\"$(osascript 2>/dev/null <<'APPLESCRIPT'||true\ntry;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\nAPPLESCRIPT\n)\"\n if [[ -z \"$key\" ]]; then echo \"hyclaude-desktop: no API Key provided. Aborting.\" >&2; exit 1; fi\n printf '%s' \"$key\"\n}\n\nconfirm_or_abort() { echo; echo \"About to: $1\"; echo \"Press Enter to continue, Ctrl-C to abort.\"; read -r _; }\n\nwrite_entry() {\n local uuid=\"$1\"; local entry_path=\"$CONFIG_DIR/${uuid}.json\"; local tmp=\"${entry_path}.tmp\"\n local content\n content=\"$(jq -n --arg baseUrl \"$BASE_URL\" --arg apiKey \"$HY_KEY\" --arg auth \"$AUTH_SCHEME\" --arg main \"$MAIN_MODEL\" --arg fast \"$FAST_MODEL\" \\\n '{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))}')\"\n printf '%s' \"$content\" > \"$tmp\"; chmod 600 \"$tmp\"; mv \"$tmp\" \"$entry_path\"\n}\n\nensure_meta_entry() {\n mkdir -p \"$CONFIG_DIR\"\n local existing_uuid=\"\"\n if [[ -f \"$META\" ]]; then existing_uuid=\"$(jq -r --arg name \"$ENTRY_NAME\" '.entries[]?|select(.name==$name)|.id' \"$META\" 2>/dev/null|head -1)\"; fi\n local uuid; if [[ -n \"$existing_uuid\" ]]; then uuid=\"$existing_uuid\"; else uuid=\"$(uuidgen | tr 'A-Z' 'a-z')\"; fi\n local tmp=\"${META}.tmp\" content\n if [[ -f \"$META\" ]]; then\n content=\"$(jq --arg id \"$uuid\" --arg name \"$ENTRY_NAME\" '.appliedId=$id|.entries=((.entries//[])|map(select(.name!=$name))+[{id:$id,name:$name}])' \"$META\")\"\n else content=\"$(jq -n --arg id \"$uuid\" --arg name \"$ENTRY_NAME\" '{appliedId:$id,entries:[{id:$id,name:$name}]}')\"; fi\n printf '%s' \"$content\" > \"$tmp\"; chmod 600 \"$tmp\"; mv \"$tmp\" \"$META\"; printf '%s' \"$uuid\"\n}\n\nrestart_claude() { killall Claude 2>/dev/null || true; sleep 1; open -a Claude; }\n\nBASE_URL=\"${HY_BASE_URL:-https://api.lkeap.cloud.tencent.com/plan/anthropic}\"\npreflight; HY_KEY=\"$(resolve_api_key)\"\nconfirm_or_abort \"configure Claude Desktop to use Tencent TokenHub ($BASE_URL, $MAIN_MODEL) and restart.\"\nUUID=\"$(ensure_meta_entry)\"; write_entry \"$UUID\"; restart_claude\n\ncat <<'EOF'\n\nDone. Claude Desktop is restarting with Tencent TokenHub as the inference backend.\nRe-run hyclaude-desktop any time to refresh the gateway config.\nEOF\n"}}, "codex-adapter.mjs": {"c07db31916dca8077b9124f5c098258f9607b016": {"t": 1785809845.4331455, "n": 18425, "h": "64d9d0c18ce50c81", "c": "#!/usr/bin/env node\n// codex-adapter.mjs — local OpenAI Responses→Chat Completions translation proxy.\n//\n// Codex CLI only speaks the OpenAI Responses API, but several providers\n// (DeepSeek, Kimi, Zhipu GLM, Tencent TokenHub, SiliconFlow) only expose\n// Chat Completions. This adapter sits between them:\n//\n// Codex --Responses--> http://127.0.0.1:8317//v1/responses\n// --Chat------> https:///chat/completions\n//\n// Zero dependencies; requires Node 18+ (global fetch). The Authorization\n// header from Codex is forwarded upstream as-is, so keys stay in Codex's\n// env_key mechanism and never touch this file.\n//\n// Usage:\n// node codex-adapter.mjs # listen on 127.0.0.1:8317\n// node codex-adapter.mjs --port 9000\n// CODEX_ADAPTER_PORT=9000 node codex-adapter.mjs\n//\n// Run in background:\n// nohup node codex-adapter.mjs > ~/.codex/adapter.log 2>&1 &\n//\n// Health check:\n// curl http://127.0.0.1:8317/health\n//\n// Notes:\n// - Reasoning output (reasoning_content) is streamed back to Codex as\n// reasoning summary deltas, so thinking is visible and the stream stays\n// alive during long thinking phases.\n// - `reasoning.effort` from Codex is dropped (providers differ on the\n// parameter; models default to their own thinking behavior).\n\nimport http from 'node:http';\n\nconst PORT = (() => {\n const i = process.argv.indexOf('--port');\n if (i !== -1 && process.argv[i + 1]) return Number(process.argv[i + 1]);\n return Number(process.env.CODEX_ADAPTER_PORT || 8317);\n})();\n\nconst MAX_BODY_SIZE = 10 * 1024 * 1024; // 10 MB\nconst UPSTREAM_TIMEOUT_MS = 10 * 60 * 1000; // 10 minutes\n\n// Chat-only upstreams. Override any URL with ADAPTER__URL (uppercased id).\nconst UPSTREAMS = {\n deepseek: 'https://api.deepseek.com/chat/completions',\n moonshot: 'https://api.moonshot.cn/v1/chat/completions',\n zhipu: 'https://open.bigmodel.cn/api/paas/v4/chat/completions',\n tokenhub: 'https://api.lkeap.cloud.tencent.com/v1/chat/completions',\n siliconflow: 'https://api.siliconflow.cn/v1/chat/completions',\n};\nfor (const id of Object.keys(UPSTREAMS)) {\n const env = process.env[`ADAPTER_${id.toUpperCase()}_URL`];\n if (env) UPSTREAMS[id] = env;\n}\n\n// ---- Request translation: Responses body -> Chat body ----------------------\n\nfunction toChatBody(body) {\n const messages = [];\n if (body.instructions) messages.push({ role: 'system', content: body.instructions });\n\n const items = typeof body.input === 'string'\n ? [{ type: 'message', role: 'user', content: body.input }]\n : Array.isArray(body.input) ? body.input : [];\n\n for (const item of items) {\n const type = item.type || 'message';\n if (type === 'message') {\n const role = item.role === 'developer' ? 'system' : item.role;\n const content = typeof item.content === 'string'\n ? item.content\n : (item.content || []).map(p => p.text || '').join('');\n messages.push({ role, content });\n } else if (type === 'function_call') {\n const call = {\n id: item.call_id || item.id,\n type: 'function',\n function: { name: item.name, arguments: item.arguments || '' },\n };\n const last = messages[messages.length - 1];\n // Merge consecutive tool calls into one assistant turn (parallel calls).\n if (last && last.role === 'assistant' && last.tool_calls) last.tool_calls.push(call);\n else messages.push({ role: 'assistant', content: null, tool_calls: [call] });\n } else if (type === 'function_call_output') {\n const out = typeof item.output === 'string' ? item.output : JSON.stringify(item.output);\n messages.push({ role: 'tool', tool_call_id: item.call_id, content: out });\n }\n // reasoning / item_reference / other item types: nothing to send upstream.\n }\n\n const chat = { model: body.model, messages };\n\n if (Array.isArray(body.tools)) {\n const fns = body.tools.filter(t => t.type === 'function');\n if (fns.length) {\n chat.tools = fns.map(t => ({\n type: 'function',\n function: { name: t.name, description: t.description, parameters: t.parameters },\n }));\n }\n }\n if (body.tool_choice && body.tool_choice !== 'auto') chat.tool_choice = body.tool_choice;\n if (typeof body.parallel_tool_calls === 'boolean') chat.parallel_tool_calls = body.parallel_tool_calls;\n if (body.temperature != null) chat.temperature = body.temperature;\n if (body.top_p != null) chat.top_p = body.top_p;\n if (body.max_output_tokens != null) chat.max_tokens = body.max_output_tokens;\n if (body.text?.format?.type === 'json_schema') {\n chat.response_format = {\n type: 'json_schema',\n json_schema: {\n name: body.text.format.name,\n schema: body.text.format.schema,\n strict: body.text.format.strict,\n },\n };\n }\n if (body.stream) {\n chat.stream = true;\n chat.stream_options = { include_usage: true };\n }\n return chat;\n}\n\n// ---- Response translation helpers ------------------------------------------\n\nfunction mapUsage(u) {\n if (!u) return null;\n return {\n input_tokens: u.prompt_tokens || 0,\n input_tokens_details: { cached_tokens: u.prompt_tokens_details?.cached_tokens || 0 },\n output_tokens: u.completion_tokens || 0,\n output_tokens_details: { reasoning_tokens: u.completion_tokens_details?.reasoning_tokens || 0 },\n total_tokens: u.total_tokens || 0,\n };\n}\n\nlet respCounter = 0;\n\nfunction buildOutput(msg) {\n const output = [];\n let n = 0;\n if (msg.reasoning_content) {\n output.push({\n type: 'reasoning', id: `rs_${++n}`,\n summary: [{ type: 'summary_text', text: msg.reasoning_content }], content: [],\n });\n }\n if (msg.content) {\n output.push({\n type: 'message', id: `msg_${++n}`, status: 'completed', role: 'assistant',\n content: [{ type: 'output_text', annotations: [], text: msg.content }],\n });\n }\n for (const tc of msg.tool_calls || []) {\n output.push({\n type: 'function_call', id: `fc_${++n}`, status: 'completed',\n call_id: tc.id, name: tc.function?.name, arguments: tc.function?.arguments || '',\n });\n }\n return output;\n}\n\nfunction toResponseObject(chatResp) {\n const choice = chatResp.choices?.[0] || {};\n const msg = choice.message || {};\n const incomplete = choice.finish_reason === 'length';\n return {\n id: `resp_${chatResp.id || ++respCounter}`,\n object: 'response',\n created_at: chatResp.created || Math.floor(Date.now() / 1000),\n status: incomplete ? 'incomplete' : 'completed',\n incomplete_details: incomplete ? { reason: 'max_output_tokens' } : null,\n error: null,\n model: chatResp.model,\n output: buildOutput(msg),\n usage: mapUsage(chatResp.usage),\n };\n}\n\n// ---- Streaming: Chat SSE -> Responses SSE -----------------------------------\n\n// Tracks the currently-open output item and emits properly ordered\n// Responses events as chat deltas arrive.\nclass StreamTranslator {\n constructor(write) {\n this.write = write;\n this.seq = 0;\n this.outputIndex = -1;\n this.current = null; // 'reasoning' | 'message' | 'function_call'\n this.itemId = null;\n this.text = '';\n this.reasoning = '';\n this.calls = new Map(); // upstream tool_call index -> {itemId, callId, name, args, outputIndex}\n this.output = []; // completed items, for response.completed\n this.usage = null;\n this.model = '';\n this.respId = `resp_${Date.now().toString(36)}${(++respCounter).toString(36)}`;\n this.created = Math.floor(Date.now() / 1000);\n this.started = false;\n }\n\n emit(type, extra) {\n this.write(`event: ${type}\\ndata: ${JSON.stringify({ type, sequence_number: this.seq++, ...extra })}\\n\\n`);\n }\n\n snapshot(status, final = false) {\n return {\n id: this.respId, object: 'response', created_at: this.created, status,\n error: null, incomplete_details: null, model: this.model,\n output: final ? this.output : [],\n usage: final ? this.usage : null,\n };\n }\n\n start(model) {\n if (this.started) return;\n this.started = true;\n this.model = model || '';\n this.emit('response.created', { response: this.snapshot('in_progress') });\n this.emit('response.in_progress', { response: this.snapshot('in_progress') });\n }\n\n closeCurrent() {\n if (this.current === 'reasoning') {\n const item = {\n type: 'reasoning', id: this.itemId,\n summary: [{ type: 'summary_text', text: this.reasoning }], content: [],\n };\n this.emit('response.reasoning_summary_text.done', {\n item_id: this.itemId, output_index: this.outputIndex, summary_index: 0, text: this.reasoning,\n });\n this.emit('response.reasoning_summary_part.done', {\n item_id: this.itemId, output_index: this.outputIndex, summary_index: 0,\n part: { type: 'summary_text', text: this.reasoning },\n });\n this.emit('response.output_item.done', { output_index: this.outputIndex, item });\n this.output.push(item);\n this.reasoning = '';\n } else if (this.current === 'message') {\n const item = {\n type: 'message', id: this.itemId, status: 'completed', role: 'assistant',\n content: [{ type: 'output_text', annotations: [], text: this.text }],\n };\n this.emit('response.output_text.done', {\n item_id: this.itemId, output_index: this.outputIndex, content_index: 0, text: this.text,\n });\n this.emit('response.content_part.done', {\n item_id: this.itemId, output_index: this.outputIndex, content_index: 0,\n part: { type: 'output_text', annotations: [], text: this.text },\n });\n this.emit('response.output_item.done', { output_index: this.outputIndex, item });\n this.output.push(item);\n this.text = '';\n }\n this.current = null;\n }\n\n openItem(kind) {\n if (this.current === kind) return;\n this.closeCurrent();\n this.current = kind;\n this.outputIndex++;\n if (kind === 'reasoning') {\n this.itemId = `rs_${this.outputIndex}`;\n this.emit('response.output_item.added', {\n output_index: this.outputIndex,\n item: { type: 'reasoning', id: this.itemId, summary: [], content: [] },\n });\n this.emit('response.reasoning_summary_part.added', {\n item_id: this.itemId, output_index: this.outputIndex, summary_index: 0,\n part: { type: 'summary_text', text: '' },\n });\n } else if (kind === 'message') {\n this.itemId = `msg_${this.outputIndex}`;\n this.emit('response.output_item.added', {\n output_index: this.outputIndex,\n item: { type: 'message', id: this.itemId, status: 'in_progress', role: 'assistant', content: [] },\n });\n this.emit('response.content_part.added', {\n item_id: this.itemId, output_index: this.outputIndex, content_index: 0,\n part: { type: 'output_text', annotations: [], text: '' },\n });\n }\n }\n\n onChunk(chunk) {\n this.start(chunk.model);\n if (chunk.usage) this.usage = mapUsage(chunk.usage);\n const delta = chunk.choices?.[0]?.delta;\n if (!delta) return;\n\n if (delta.reasoning_content) {\n this.openItem('reasoning');\n this.reasoning += delta.reasoning_content;\n this.emit('response.reasoning_summary_text.delta', {\n item_id: this.itemId, output_index: this.outputIndex, summary_index: 0,\n delta: delta.reasoning_content,\n });\n }\n if (delta.content) {\n this.openItem('message');\n this.text += delta.content;\n this.emit('response.output_text.delta', {\n item_id: this.itemId, output_index: this.outputIndex, content_index: 0,\n delta: delta.content,\n });\n }\n for (const tc of delta.tool_calls || []) {\n const idx = tc.index ?? 0;\n let call = this.calls.get(idx);\n if (!call) {\n this.closeCurrent();\n this.outputIndex++;\n call = {\n itemId: `fc_${this.outputIndex}`,\n callId: tc.id || `call_${this.outputIndex}`,\n name: tc.function?.name || '',\n args: '',\n outputIndex: this.outputIndex,\n };\n this.calls.set(idx, call);\n this.emit('response.output_item.added', {\n output_index: call.outputIndex,\n item: {\n type: 'function_call', id: call.itemId, status: 'in_progress',\n call_id: call.callId, name: call.name, arguments: '',\n },\n });\n } else if (tc.function?.name) {\n call.name += tc.function.name;\n }\n // Upstream may send the real id after our placeholder was created.\n if (tc.id && tc.id !== call.callId && call.callId.startsWith('call_')) {\n call.callId = tc.id;\n }\n if (tc.function?.arguments) {\n call.args += tc.function.arguments;\n this.emit('response.function_call_arguments.delta', {\n item_id: call.itemId, output_index: call.outputIndex, delta: tc.function.arguments,\n });\n }\n }\n }\n\n finish(finishReason) {\n this.closeCurrent();\n for (const call of this.calls.values()) {\n const item = {\n type: 'function_call', id: call.itemId, status: 'completed',\n call_id: call.callId, name: call.name, arguments: call.args,\n };\n this.emit('response.function_call_arguments.done', {\n item_id: call.itemId, output_index: call.outputIndex, arguments: call.args,\n });\n this.emit('response.output_item.done', { output_index: call.outputIndex, item });\n this.output.push(item);\n }\n this.calls.clear();\n const status = finishReason === 'length' ? 'incomplete' : 'completed';\n const response = this.snapshot(status, true);\n if (status === 'incomplete') response.incomplete_details = { reason: 'max_output_tokens' };\n this.emit(`response.${status}`, { response });\n }\n\n fail(message) {\n this.start('');\n const response = this.snapshot('failed', true);\n response.error = { code: 'upstream_error', message };\n this.emit('response.failed', { response });\n }\n}\n\n// ---- HTTP server -------------------------------------------------------------\n\nasync function handleResponses(provider, body, req, res) {\n const upstream = UPSTREAMS[provider];\n const chatBody = toChatBody(body);\n const t0 = Date.now();\n\n const upstreamRes = await fetch(upstream, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': req.headers['authorization'] || '',\n },\n body: JSON.stringify(chatBody),\n signal: AbortSignal.timeout(UPSTREAM_TIMEOUT_MS),\n });\n\n if (!upstreamRes.ok) {\n const errText = await upstreamRes.text();\n console.log(`[${provider}] ${chatBody.model} -> HTTP ${upstreamRes.status} (${Date.now() - t0}ms)`);\n res.writeHead(upstreamRes.status, { 'Content-Type': 'application/json' });\n let message = errText;\n try { message = JSON.parse(errText).error?.message || errText; } catch {}\n res.end(JSON.stringify({ error: { type: 'upstream_error', code: String(upstreamRes.status), message } }));\n return;\n }\n\n if (!chatBody.stream) {\n const chatResp = await upstreamRes.json();\n console.log(`[${provider}] ${chatBody.model} -> 200 non-stream (${Date.now() - t0}ms)`);\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(toResponseObject(chatResp)));\n return;\n }\n\n res.writeHead(200, {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n 'Connection': 'keep-alive',\n });\n const translator = new StreamTranslator(s => res.write(s));\n let finishReason = null;\n let buffer = '';\n const decoder = new TextDecoder();\n\n try {\n for await (const raw of upstreamRes.body) {\n buffer += decoder.decode(raw, { stream: true });\n let nl;\n while ((nl = buffer.indexOf('\\n')) !== -1) {\n const line = buffer.slice(0, nl).trim();\n buffer = buffer.slice(nl + 1);\n if (!line.startsWith('data:')) continue;\n const data = line.slice(5).trim();\n if (data === '[DONE]') continue;\n let chunk;\n try { chunk = JSON.parse(data); } catch { continue; }\n if (chunk.choices?.[0]?.finish_reason) finishReason = chunk.choices[0].finish_reason;\n translator.onChunk(chunk);\n }\n }\n translator.finish(finishReason);\n console.log(`[${provider}] ${chatBody.model} -> 200 stream done (${Date.now() - t0}ms)`);\n } catch (err) {\n translator.fail(String(err?.message || err));\n console.log(`[${provider}] ${chatBody.model} -> stream error: ${err?.message} (${Date.now() - t0}ms)`);\n }\n res.end();\n}\n\nconst server = http.createServer((req, res) => {\n if (req.method === 'GET' && req.url === '/health') {\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ ok: true, providers: Object.keys(UPSTREAMS) }));\n return;\n }\n\n const m = req.method === 'POST' && req.url.match(/^\\/([a-z]+)\\/v1\\/responses$/);\n if (!m || !UPSTREAMS[m[1]]) {\n res.writeHead(404, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: { type: 'not_found', message: `Unknown route ${req.method} ${req.url}. Providers: ${Object.keys(UPSTREAMS).join(', ')}` } }));\n return;\n }\n\n const chunks = [];\n let bodySize = 0;\n req.on('data', c => {\n bodySize += c.length;\n if (bodySize > MAX_BODY_SIZE) {\n if (!res.headersSent) {\n res.writeHead(413, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: { type: 'too_large', message: `Body exceeds ${MAX_BODY_SIZE / 1024 / 1024} MB limit` } }));\n }\n req.destroy();\n return;\n }\n chunks.push(c);\n });\n req.on('end', () => {\n let body;\n try { body = JSON.parse(Buffer.concat(chunks).toString('utf8')); }\n catch {\n res.writeHead(400, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: { type: 'invalid_request', message: 'Body is not valid JSON' } }));\n return;\n }\n handleResponses(m[1], body, req, res).catch(err => {\n console.error(`[${m[1]}] fatal:`, err);\n if (!res.headersSent) {\n res.writeHead(502, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: { type: 'adapter_error', message: String(err?.message || err) } }));\n } else {\n res.end();\n }\n });\n });\n});\n\nserver.listen(PORT, '127.0.0.1', () => {\n console.log(`codex-adapter listening on http://127.0.0.1:${PORT}`);\n console.log(`providers: ${Object.keys(UPSTREAMS).join(', ')}`);\n console.log(`route: POST //v1/responses`);\n});\n"}}, "kmclaude": {"c07db31916dca8077b9124f5c098258f9607b016": {"t": 1785846824.453782, "n": 4037, "h": "e839ee54e8d8ba0b", "c": "#!/usr/bin/env bash\n# shellcheck disable=SC2034 # variables consumed by lib/common.sh\n# kmclaude — launch Claude Code on Moonshot AI Kimi's Anthropic-compatible API.\n#\n# Uses the official Kimi Anthropic-compatible endpoint:\n# https://api.moonshot.cn/anthropic\n#\n# Reads KIMI_API_KEY (or MOONSHOT_API_KEY) from the environment first,\n# then falls back to ~/.zshrc / ~/.bashrc / ~/.bash_profile / ~/.profile.\n#\n# Quick start (no install needed):\n# chmod +x kmclaude\n# ./kmclaude\n#\n# Optional — make it globally available:\n# sudo mv kmclaude /usr/local/bin/ && sudo chmod +x /usr/local/bin/kmclaude\n#\n# Use:\n# kmclaude # start on kimi-k3 (Kimi flagship)\n# kmclaude fast # start on kimi-k2.5 (cheaper / faster tier)\n# kmclaude long # (no-op; 1M context is the default)\n# kmclaude effort max # set reasoning effort (low|medium|high|xhigh|max)\n# kmclaude update # git pull latest from this repo\n# kmclaude --help # any remaining flag is forwarded to claude\n#\n# Optional env overrides:\n# KIMI_MODEL=kimi-k3 # main model\n# KIMI_FLASH_MODEL=kimi-k2.5 # flash / haiku / subagent tier\n# KIMI_BASE_URL=https://.../anthropic # custom Anthropic-compatible base URL\n# KIMI_CTX=1048576 # max context tokens (default: 1M)\n# KIMI_OUTPUT=8000 # cap output tokens\n# KIMI_EFFORT=max # CLAUDE_CODE_EFFORT_LEVEL\n#\n# In-session switch:\n# /model kimi-k2.5 # switch to the flash tier\n# /model kimi-k3 # switch back to pro\n#\nset -euo pipefail\n\n# Resolve symlink to find the real script directory.\n_SELF=\"$0\"\nif [ -L \"$_SELF\" ]; then\n _LINK=\"$(readlink \"$_SELF\")\"\n case \"$_LINK\" in\n /*) _SELF=\"$_LINK\" ;;\n *) _SELF=\"$(cd \"$(dirname \"$_SELF\")\" && pwd)/$_LINK\" ;;\n esac\nfi\nSELF_DIR=\"$(cd \"$(dirname \"$_SELF\")\" && pwd)\"\nif [ -f \"$SELF_DIR/lib/common.sh\" ]; then source \"$SELF_DIR/lib/common.sh\"\nelif [ -f \"$SELF_DIR/../lib/common.sh\" ]; then source \"$SELF_DIR/../lib/common.sh\"\nelse echo \"kmclaude: cannot find lib/common.sh. Reinstall or cd to repo.\" >&2; exit 1; fi\n\ncheck_version \"kmclaude\" \"$@\"\n\nPRO_MODEL=\"${KIMI_MODEL:-kimi-k3}\"\nFLASH_MODEL=\"${KIMI_FLASH_MODEL:-kimi-k2.5}\"\n\n# Handle the update subcommand before the API-key check so it works key-less.\nif [ $# -gt 0 ] && [ \"$1\" = \"update\" ]; then\n do_update \"kmclaude\" \"KMCLAUDE_HOME\"\nfi\n\nAPI_KEY=\"$(resolve_api_key \"KIMI_API_KEY\")\"\n[ -z \"$API_KEY\" ] && API_KEY=\"$(resolve_api_key \"MOONSHOT_API_KEY\")\"\nif [ -z \"$API_KEY\" ]; then\n echo \"❌ Neither KIMI_API_KEY nor MOONSHOT_API_KEY found.\" >&2\n echo \" Add one line to ~/.zshrc or ~/.bashrc:\" >&2\n echo \" export MOONSHOT_API_KEY=sk-xxxxxxxxxxxxxxxxxx\" >&2\n echo \" Get your key at: https://platform.moonshot.cn/console/api-keys\" >&2\n exit 1\nfi\n\nBASE_URL=\"${KIMI_BASE_URL:-https://api.moonshot.cn/anthropic}\"\n\nLONG_CTX=0\nEFFORT=\"${KIMI_EFFORT:-}\"\n\n# Positional alias: `fast`/`flash` runs the flash tier as the main model.\nMAIN_MODEL=\"$PRO_MODEL\"\nwhile [ $# -gt 0 ]; do\n case \"$1\" in\n fast|flash) MAIN_MODEL=\"$FLASH_MODEL\"; shift ;;\n long) LONG_CTX=1; shift ;;\n effort)\n case \"${2:-}\" in\n low|medium|high|xhigh|max) EFFORT=\"$2\"; shift 2 ;;\n *) echo \"kmclaude: invalid effort level '${2:-}'. Use: low medium high xhigh max\" >&2; exit 1 ;;\n esac\n ;;\n --) shift; break ;;\n *) break ;;\n esac\ndone\n\n# Surface the other model in Claude Code's /model picker for mid-session switching.\nif [ \"$MAIN_MODEL\" = \"$PRO_MODEL\" ]; then\n OTHER_MODEL=\"$FLASH_MODEL\"\n OTHER_DESC=\"Kimi K2.5 — fast / cheap tier\"\nelse\n OTHER_MODEL=\"$PRO_MODEL\"\n OTHER_DESC=\"Kimi K3 — full reasoning\"\nfi\n\nexport_anthropic_base\n# Subagents run on the cheaper flash tier.\nexport CLAUDE_CODE_SUBAGENT_MODEL=\"$FLASH_MODEL\"\nset_custom_model \"$OTHER_MODEL\" \"$MAIN_MODEL\" \"$OTHER_DESC\"\n\nCTX=\"${KIMI_CTX:-1048576}\"\nOUTPUT_CAP=\"${KIMI_OUTPUT:-}\"\napply_context_and_effort\n\nshow_banner_and_launch \"Kimi\" \"$@\"\n"}}}}