feat: support configurable provider config dirs

This commit is contained in:
xixu-me committed 2026-04-17 15:30:42 +08:00
1 parent 2e97513e60
commit aab3f567f1
7 files changed
+105 -25

No files matched your search

+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 Xi Xu
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+31 -21
View File
@@ -8,7 +8,7 @@
会自动完成以下操作: 会自动完成以下操作:
- 写入 `~/.codex/config.toml` - 写入 Codex 配置文件
- 设置 provider 为 `xixu` - 设置 provider 为 `xixu`
- 配置 `XIXU_API_KEY` 环境变量 - 配置 `XIXU_API_KEY` 环境变量
@@ -16,20 +16,18 @@
会自动完成以下操作: 会自动完成以下操作:
- 写入 `~/.claude/settings.json` - 写入 Claude Code 配置文件
- 配置 `ANTHROPIC_AUTH_TOKEN` - 配置 `ANTHROPIC_AUTH_TOKEN`
- 配置 `ANTHROPIC_BASE_URL` - 配置 `ANTHROPIC_BASE_URL`
- 配置默认模型为 `gpt-5.4` - 配置默认模型为 `gpt-5.4`
---
## Codex ## Codex
### Linux/macOS ### Linux/macOS
```bash ```bash
bash <(curl -fsSL https://github.com/xixu-me/provider-setup/raw/refs/heads/main/codex.sh) bash <(curl -fsSL https://github.com/xixu-me/provider-setup/raw/refs/heads/main/codex.sh)
```` ```
### Windows PowerShell ### Windows PowerShell
@@ -37,8 +35,6 @@ bash <(curl -fsSL https://github.com/xixu-me/provider-setup/raw/refs/heads/main/
powershell -ExecutionPolicy Bypass -Command "& ([scriptblock]::Create((Invoke-WebRequest -UseBasicParsing 'https://github.com/xixu-me/provider-setup/raw/refs/heads/main/codex.ps1').Content))" powershell -ExecutionPolicy Bypass -Command "& ([scriptblock]::Create((Invoke-WebRequest -UseBasicParsing 'https://github.com/xixu-me/provider-setup/raw/refs/heads/main/codex.ps1').Content))"
``` ```
---
## Claude Code ## Claude Code
### Linux/macOS ### Linux/macOS
@@ -53,8 +49,6 @@ bash <(curl -fsSL https://github.com/xixu-me/provider-setup/raw/refs/heads/main/
powershell -ExecutionPolicy Bypass -Command "& ([scriptblock]::Create((Invoke-WebRequest -UseBasicParsing 'https://github.com/xixu-me/provider-setup/raw/refs/heads/main/claude.ps1').Content))" powershell -ExecutionPolicy Bypass -Command "& ([scriptblock]::Create((Invoke-WebRequest -UseBasicParsing 'https://github.com/xixu-me/provider-setup/raw/refs/heads/main/claude.ps1').Content))"
``` ```
---
## 配置内容 ## 配置内容
### Codex ### Codex
@@ -72,7 +66,7 @@ env_key = "XIXU_API_KEY"
### Claude Code ### Claude Code
写入到 `~/.claude/settings.json` 的 `env`: 写入到目标 `settings.json` 的 `env`:
```json ```json
{ {
@@ -88,16 +82,19 @@ env_key = "XIXU_API_KEY"
} }
``` ```
---
## 说明 ## 说明
* 脚本默认会提示输入 API Key ### 路径规则
* 若对应配置文件已存在,会在保留其他配置的基础上更新目标字段
* Windows 下用户级环境变量会持久化保存
* Linux/macOS 下会写入当前 shell 配置文件以便后续生效
--- - Codex 使用 `CODEX_HOME/config.toml`;若未设置 `CODEX_HOME`,则回退到 `~/.codex/config.toml`
- Claude Code 使用 `CLAUDE_CONFIG_DIR/settings.json`;若未设置 `CLAUDE_CONFIG_DIR`,则回退到 `~/.claude/settings.json`
### 其他说明
- 脚本默认会提示输入 API Key
- 若对应配置文件已存在,会在保留其他配置的基础上更新目标字段
- Windows 下用户级环境变量会持久化保存
- Linux/macOS 下会写入当前 shell 配置文件以便后续生效
## 验证 ## 验证
@@ -106,14 +103,14 @@ env_key = "XIXU_API_KEY"
#### Linux/macOS #### Linux/macOS
```bash ```bash
cat ~/.codex/config.toml cat "${CODEX_HOME:-$HOME/.codex}/config.toml"
echo $XIXU_API_KEY echo $XIXU_API_KEY
``` ```
#### Windows PowerShell #### Windows PowerShell
```powershell ```powershell
Get-Content ~/.codex/config.toml Get-Content (Join-Path $(if ($env:CODEX_HOME) { $env:CODEX_HOME } else { Join-Path $HOME ".codex" }) "config.toml")
$env:XIXU_API_KEY $env:XIXU_API_KEY
[System.Environment]::GetEnvironmentVariable("XIXU_API_KEY","User") [System.Environment]::GetEnvironmentVariable("XIXU_API_KEY","User")
``` ```
@@ -123,11 +120,24 @@ $env:XIXU_API_KEY
#### Linux/macOS #### Linux/macOS
```bash ```bash
cat ~/.claude/settings.json python3 -c "import json, os, pathlib; config_dir = pathlib.Path(os.environ.get('CLAUDE_CONFIG_DIR', str(pathlib.Path.home() / '.claude'))); settings_file = config_dir / 'settings.json'; data = json.loads(settings_file.read_text(encoding='utf-8')); env = data.get('env', {}); keys = ['ANTHROPIC_AUTH_TOKEN', 'ANTHROPIC_BASE_URL', 'ANTHROPIC_DEFAULT_HAIKU_MODEL', 'ANTHROPIC_DEFAULT_OPUS_MODEL', 'ANTHROPIC_DEFAULT_SONNET_MODEL', 'CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC', 'CLAUDE_CODE_SUBAGENT_MODEL']; print(settings_file); [print(f'{key}={env.get(key)}') for key in keys]"
``` ```
#### Windows PowerShell #### Windows PowerShell
```powershell ```powershell
Get-Content ~/.claude/settings.json $settingsFile = Join-Path $(if ($env:CLAUDE_CONFIG_DIR) { $env:CLAUDE_CONFIG_DIR } else { Join-Path $HOME ".claude" }) "settings.json"
$envConfig = (Get-Content $settingsFile -Raw | ConvertFrom-Json).env
$settingsFile
"ANTHROPIC_AUTH_TOKEN=$($envConfig.ANTHROPIC_AUTH_TOKEN)"
"ANTHROPIC_BASE_URL=$($envConfig.ANTHROPIC_BASE_URL)"
"ANTHROPIC_DEFAULT_HAIKU_MODEL=$($envConfig.ANTHROPIC_DEFAULT_HAIKU_MODEL)"
"ANTHROPIC_DEFAULT_OPUS_MODEL=$($envConfig.ANTHROPIC_DEFAULT_OPUS_MODEL)"
"ANTHROPIC_DEFAULT_SONNET_MODEL=$($envConfig.ANTHROPIC_DEFAULT_SONNET_MODEL)"
"CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=$($envConfig.CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC)"
"CLAUDE_CODE_SUBAGENT_MODEL=$($envConfig.CLAUDE_CODE_SUBAGENT_MODEL)"
``` ```
## License
MIT. See [LICENSE](LICENSE).
+5 -1
View File
@@ -13,7 +13,11 @@ if ([string]::IsNullOrWhiteSpace($ApiKey)) {
} }
} }
$SettingsDir = Join-Path $HOME ".claude" $SettingsDir = if ([string]::IsNullOrWhiteSpace($env:CLAUDE_CONFIG_DIR)) {
Join-Path $HOME ".claude"
} else {
$env:CLAUDE_CONFIG_DIR
}
$SettingsFile = Join-Path $SettingsDir "settings.json" $SettingsFile = Join-Path $SettingsDir "settings.json"
New-Item -ItemType Directory -Force -Path $SettingsDir | Out-Null New-Item -ItemType Directory -Force -Path $SettingsDir | Out-Null
+1 -1
View File
@@ -13,7 +13,7 @@ if [[ -z "$API_KEY" ]]; then
echo echo
fi fi
SETTINGS_DIR="$HOME/.claude" SETTINGS_DIR="${CLAUDE_CONFIG_DIR:-$HOME/.claude}"
SETTINGS_FILE="$SETTINGS_DIR/settings.json" SETTINGS_FILE="$SETTINGS_DIR/settings.json"
mkdir -p "$SETTINGS_DIR" mkdir -p "$SETTINGS_DIR"
+5 -1
View File
@@ -13,7 +13,11 @@ if ([string]::IsNullOrWhiteSpace($ApiKey)) {
} }
} }
$ConfigDir = Join-Path $HOME ".codex" $ConfigDir = if ([string]::IsNullOrWhiteSpace($env:CODEX_HOME)) {
Join-Path $HOME ".codex"
} else {
$env:CODEX_HOME
}
$ConfigFile = Join-Path $ConfigDir "config.toml" $ConfigFile = Join-Path $ConfigDir "config.toml"
New-Item -ItemType Directory -Force -Path $ConfigDir | Out-Null New-Item -ItemType Directory -Force -Path $ConfigDir | Out-Null
+1 -1
View File
@@ -13,7 +13,7 @@ if [[ -z "$API_KEY" ]]; then
echo echo
fi fi
CONFIG_DIR="$HOME/.codex" CONFIG_DIR="${CODEX_HOME:-$HOME/.codex}"
CONFIG_FILE="$CONFIG_DIR/config.toml" CONFIG_FILE="$CONFIG_DIR/config.toml"
mkdir -p "$CONFIG_DIR" mkdir -p "$CONFIG_DIR"
+41
View File
@@ -0,0 +1,41 @@
import pathlib
import unittest
REPO_ROOT = pathlib.Path(__file__).resolve().parents[1]
class ConfigDirTests(unittest.TestCase):
def test_codex_ps1_prefers_codex_home(self) -> None:
content = (REPO_ROOT / "codex.ps1").read_text(encoding="utf-8")
self.assertIn('$ConfigDir = if ([string]::IsNullOrWhiteSpace($env:CODEX_HOME))', content)
self.assertIn('$env:CODEX_HOME', content)
self.assertIn('Join-Path $HOME ".codex"', content)
def test_codex_sh_prefers_codex_home(self) -> None:
content = (REPO_ROOT / "codex.sh").read_text(encoding="utf-8")
self.assertIn('CONFIG_DIR="${CODEX_HOME:-$HOME/.codex}"', content)
def test_claude_ps1_prefers_claude_config_dir(self) -> None:
content = (REPO_ROOT / "claude.ps1").read_text(encoding="utf-8")
self.assertIn('$SettingsDir = if ([string]::IsNullOrWhiteSpace($env:CLAUDE_CONFIG_DIR))', content)
self.assertIn('$env:CLAUDE_CONFIG_DIR', content)
self.assertIn('Join-Path $HOME ".claude"', content)
def test_claude_sh_prefers_claude_config_dir(self) -> None:
content = (REPO_ROOT / "claude.sh").read_text(encoding="utf-8")
self.assertIn('SETTINGS_DIR="${CLAUDE_CONFIG_DIR:-$HOME/.claude}"', content)
def test_readme_documents_environment_overrides(self) -> None:
content = (REPO_ROOT / "README.md").read_text(encoding="utf-8")
self.assertIn("`CODEX_HOME`", content)
self.assertIn("`CLAUDE_CONFIG_DIR`", content)
if __name__ == "__main__":
unittest.main()