Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions docs/users/configuration/auth.md
Original file line number Diff line number Diff line change
Expand Up @@ -266,12 +266,12 @@ This is the approach used in the [one-file setup example](#recommended-one-file-

**Priority summary:**

| Priority | Source | Override behavior |
| ----------- | ------------------------------ | ---------------------------------------- |
| 1 (highest) | CLI flags (`--openai-api-key`) | Always wins |
| 2 | System env (`export`, inline) | Overrides `.env` and `settings.env` |
| 3 | `.env` file | Only sets if not in system env |
| 4 (lowest) | `settings.json` → `env` | Only sets if not in system env or `.env` |
| Priority | Source | Override behavior |
| ----------- | ------------------------------ | -------------------------------------------- |
| 1 (highest) | CLI flags (`--openai-api-key`) | Always wins |
| 2 | System env (`export`, inline) | Overrides `.env` and `settings.json` → `env` |
| 3 | `.env` file | Only sets if not in system env |
| 4 (lowest) | `settings.json` → `env` | Only sets if not in system env or `.env` |

#### Step 3: Switch models with `/model`

Expand Down
2 changes: 1 addition & 1 deletion docs/users/configuration/model-providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ The region is selected during authentication and stored in `settings.json` under

### API Key Storage

When you configure Coding Plan through the `/auth` command, the API key is stored using the reserved environment variable name `BAILIAN_CODING_PLAN_API_KEY`. By default, it is stored in the `settings.env` field of your `settings.json` file.
When you configure Coding Plan through the `/auth` command, the API key is stored using the reserved environment variable name `BAILIAN_CODING_PLAN_API_KEY`. By default, it is stored in the `env` field of your `settings.json` file.

> [!warning]
> **Security Recommendation**: For better security, it is recommended to move the API key from `settings.json` to a separate `.env` file and load it as an environment variable. For example:
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/config/settingsSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ const SETTINGS_SCHEMA = {
requiresRestart: true,
default: {} as Record<string, string>,
description:
'Environment variables to set as fallback defaults. These are loaded with the lowest priority: system environment variables > .env files > settings.env.',
'Environment variables to set as fallback defaults. These are loaded with the lowest priority: system environment variables > .env files > settings.json env field.',
showInDialog: false,
mergeStrategy: MergeStrategy.SHALLOW_MERGE,
},
Expand Down
24 changes: 24 additions & 0 deletions packages/cli/src/constants/codingPlan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,19 +61,26 @@ export function generateCodingPlanTemplate(
extra_body: {
enable_thinking: true,
},
contextWindowSize: 1000000,
},
},
{
id: 'qwen3-coder-plus',
name: '[Bailian Coding Plan] qwen3-coder-plus',
baseUrl: 'https://coding.dashscope.aliyuncs.com/v1',
envKey: CODING_PLAN_ENV_KEY,
generationConfig: {
contextWindowSize: 1000000,
},
},
{
id: 'qwen3-coder-next',
name: '[Bailian Coding Plan] qwen3-coder-next',
baseUrl: 'https://coding.dashscope.aliyuncs.com/v1',
envKey: CODING_PLAN_ENV_KEY,
generationConfig: {
contextWindowSize: 262144,
},
},
{
id: 'qwen3-max-2026-01-23',
Expand All @@ -84,6 +91,7 @@ export function generateCodingPlanTemplate(
extra_body: {
enable_thinking: true,
},
contextWindowSize: 262144,
},
},
{
Expand All @@ -95,6 +103,7 @@ export function generateCodingPlanTemplate(
extra_body: {
enable_thinking: true,
},
contextWindowSize: 202752,
},
},
{
Expand All @@ -106,6 +115,7 @@ export function generateCodingPlanTemplate(
extra_body: {
enable_thinking: true,
},
contextWindowSize: 202752,
},
},
{
Expand All @@ -117,6 +127,7 @@ export function generateCodingPlanTemplate(
extra_body: {
enable_thinking: true,
},
contextWindowSize: 1000000,
},
},
{
Expand All @@ -128,6 +139,7 @@ export function generateCodingPlanTemplate(
extra_body: {
enable_thinking: true,
},
contextWindowSize: 262144,
},
},
];
Expand All @@ -144,19 +156,26 @@ export function generateCodingPlanTemplate(
extra_body: {
enable_thinking: true,
},
contextWindowSize: 1000000,
},
},
{
id: 'qwen3-coder-plus',
name: '[Bailian Coding Plan for Global/Intl] qwen3-coder-plus',
baseUrl: 'https://coding-intl.dashscope.aliyuncs.com/v1',
envKey: CODING_PLAN_ENV_KEY,
generationConfig: {
contextWindowSize: 1000000,
},
},
{
id: 'qwen3-coder-next',
name: '[Bailian Coding Plan for Global/Intl] qwen3-coder-next',
baseUrl: 'https://coding-intl.dashscope.aliyuncs.com/v1',
envKey: CODING_PLAN_ENV_KEY,
generationConfig: {
contextWindowSize: 262144,
},
},
{
id: 'qwen3-max-2026-01-23',
Expand All @@ -167,6 +186,7 @@ export function generateCodingPlanTemplate(
extra_body: {
enable_thinking: true,
},
contextWindowSize: 262144,
},
},
{
Expand All @@ -178,6 +198,7 @@ export function generateCodingPlanTemplate(
extra_body: {
enable_thinking: true,
},
contextWindowSize: 202752,
},
},
{
Expand All @@ -189,6 +210,7 @@ export function generateCodingPlanTemplate(
extra_body: {
enable_thinking: true,
},
contextWindowSize: 202752,
},
},
{
Expand All @@ -200,6 +222,7 @@ export function generateCodingPlanTemplate(
extra_body: {
enable_thinking: true,
},
contextWindowSize: 1000000,
},
},
{
Expand All @@ -211,6 +234,7 @@ export function generateCodingPlanTemplate(
extra_body: {
enable_thinking: true,
},
contextWindowSize: 262144,
},
},
];
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/src/i18n/locales/de.js
Original file line number Diff line number Diff line change
Expand Up @@ -1450,6 +1450,6 @@ export default {
'Neue Modellkonfigurationen sind für Coding Plan (Bailian, Global/Intl) verfügbar. Jetzt aktualisieren?',
'{{region}} configuration updated successfully. Model switched to "{{model}}".':
'{{region}}-Konfiguration erfolgreich aktualisiert. Modell auf "{{model}}" umgeschaltet.',
'Authenticated successfully with {{region}}. API key is stored in settings.env.':
'Erfolgreich mit {{region}} authentifiziert. API-Schlüssel ist in settings.env gespeichert.',
'Authenticated successfully with {{region}}. API key and model configs saved to settings.json (backed up).':
'Erfolgreich mit {{region}} authentifiziert. API-Schlüssel und Modellkonfigurationen wurden in settings.json gespeichert (gesichert).',
};
4 changes: 2 additions & 2 deletions packages/cli/src/i18n/locales/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -1449,6 +1449,6 @@ export default {
'New model configurations are available for Coding Plan (Bailian, Global/Intl). Update now?',
'{{region}} configuration updated successfully. Model switched to "{{model}}".':
'{{region}} configuration updated successfully. Model switched to "{{model}}".',
'Authenticated successfully with {{region}}. API key is stored in settings.env.':
'Authenticated successfully with {{region}}. API key is stored in settings.env.',
'Authenticated successfully with {{region}}. API key and model configs saved to settings.json (backed up).':
'Authenticated successfully with {{region}}. API key and model configs saved to settings.json (backed up).',
};
4 changes: 2 additions & 2 deletions packages/cli/src/i18n/locales/ja.js
Original file line number Diff line number Diff line change
Expand Up @@ -955,6 +955,6 @@ export default {
'Coding Plan (Bailian, グローバル/国際) の新しいモデル設定が利用可能です。今すぐ更新しますか?',
'{{region}} configuration updated successfully. Model switched to "{{model}}".':
'{{region}} の設定が正常に更新されました。モデルが "{{model}}" に切り替わりました。',
'Authenticated successfully with {{region}}. API key is stored in settings.env.':
'{{region}} での認証に成功しました。APIキーは settings.env に保存されています。',
'Authenticated successfully with {{region}}. API key and model configs saved to settings.json (backed up).':
'{{region}} での認証に成功しました。APIキーとモデル設定が settings.json に保存されました(バックアップ済み)。',
};
4 changes: 2 additions & 2 deletions packages/cli/src/i18n/locales/pt.js
Original file line number Diff line number Diff line change
Expand Up @@ -1458,6 +1458,6 @@ export default {
'Novas configurações de modelo estão disponíveis para o Coding Plan (Bailian, Global/Intl). Atualizar agora?',
'{{region}} configuration updated successfully. Model switched to "{{model}}".':
'Configuração do {{region}} atualizada com sucesso. Modelo alterado para "{{model}}".',
'Authenticated successfully with {{region}}. API key is stored in settings.env.':
'Autenticado com sucesso com {{region}}. A chave de API está armazenada em settings.env.',
'Authenticated successfully with {{region}}. API key and model configs saved to settings.json (backed up).':
'Autenticado com sucesso com {{region}}. Chave de API e configurações de modelo salvas em settings.json (com backup).',
};
4 changes: 2 additions & 2 deletions packages/cli/src/i18n/locales/ru.js
Original file line number Diff line number Diff line change
Expand Up @@ -1454,6 +1454,6 @@ export default {
'Доступны новые конфигурации моделей для Coding Plan (Bailian, Глобальный/Международный). Обновить сейчас?',
'{{region}} configuration updated successfully. Model switched to "{{model}}".':
'Конфигурация {{region}} успешно обновлена. Модель переключена на "{{model}}".',
'Authenticated successfully with {{region}}. API key is stored in settings.env.':
'Успешная аутентификация с {{region}}. API-ключ сохранён в settings.env.',
'Authenticated successfully with {{region}}. API key and model configs saved to settings.json (backed up).':
'Успешная аутентификация с {{region}}. API-ключ и конфигурации моделей сохранены в settings.json (резервная копия создана).',
};
4 changes: 2 additions & 2 deletions packages/cli/src/i18n/locales/zh.js
Original file line number Diff line number Diff line change
Expand Up @@ -1282,6 +1282,6 @@ export default {
'Coding Plan (百炼, 全球/国际) 有新的模型配置可用。是否立即更新?',
'{{region}} configuration updated successfully. Model switched to "{{model}}".':
'{{region}} 配置更新成功。模型已切换至 "{{model}}"。',
'Authenticated successfully with {{region}}. API key is stored in settings.env.':
'成功通过 {{region}} 认证。API Key 已存储在 settings.env 中。',
'Authenticated successfully with {{region}}. API key and model configs saved to settings.json (backed up).':
'成功通过 {{region}} 认证。API Key 和模型配置已保存至 settings.json(已备份)。',
};
7 changes: 6 additions & 1 deletion packages/cli/src/ui/auth/useAuth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import {
CodingPlanRegion,
CODING_PLAN_ENV_KEY,
} from '../../constants/codingPlan.js';
import { backupSettingsFile } from '../../utils/settingsUtils.js';

export type { QwenAuthState } from '../hooks/useQwenAuth.js';

Expand Down Expand Up @@ -304,6 +305,10 @@ export const useAuthCommand = (
// Get persist scope
const persistScope = getPersistScopeForModelSelection(settings);

// Backup settings file before modification
const settingsFile = settings.forScope(persistScope);
backupSettingsFile(settingsFile.path);

// Store api-key in settings.env (unified env key)
settings.setValue(persistScope, `env.${CODING_PLAN_ENV_KEY}`, apiKey);

Expand Down Expand Up @@ -384,7 +389,7 @@ export const useAuthCommand = (
{
type: MessageType.INFO,
text: t(
'Authenticated successfully with {{region}}. API key is stored in settings.env.',
'Authenticated successfully with {{region}}. API key and model configs saved to settings.json (backed up).',
{ region: regionName },
),
},
Expand Down
22 changes: 22 additions & 0 deletions packages/cli/src/utils/settingsUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

import * as fs from 'node:fs';
import type {
Settings,
SettingScope,
Expand Down Expand Up @@ -577,4 +578,25 @@ export function getEffectiveDisplayValue(
return getSettingValue(key, settings, mergedSettings);
}

/**
* Backup a settings file before modification.
* Creates a backup with `.orig` suffix if the file exists and backup doesn't already exist.
* @param filePath - Path to the settings file to backup
* @returns boolean indicating whether a backup was created
*/
export function backupSettingsFile(filePath: string): boolean {
try {
if (fs.existsSync(filePath)) {
const backupPath = `${filePath}.orig`;
if (!fs.existsSync(backupPath)) {
fs.renameSync(filePath, backupPath);
return true;
}
}
} catch (_e) {
// Ignore backup errors, proceed without backup
}
return false;
}

export const TEST_ONLY = { clearFlattenedSchema };