Skip to content
Draft
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
13 changes: 7 additions & 6 deletions src/cli/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ import {
recordDotenvOrigin,
} from '../utils/startup-env.js';
import { officialEnvOffers } from './env-credentials.js';
import { isZhLocale, setupCopy } from './cli-locale.js';
import { isZhLocale } from './cli-locale.js';
import { isDeviceTrustEnv, parseDeviceTrustList } from '../safety/device-trust.js';
import type { PricingConfig } from './model-pricing.js';
import type { StatusLineConfig } from './status-line.js';
Expand Down Expand Up @@ -2077,11 +2077,12 @@ export function resolveCliConfig(
baseUrl: offer.baseUrl,
};
autoEnvKey = { apiKey: offer.apiKey, source: `env:${offer.keyVar}` };
autoEnvNotice = setupCopy(undefined, '[moss] Using {key} → {provider} @ {baseUrl}', {
key: offer.keyVar,
provider: offer.provider,
baseUrl: offer.baseUrl,
});
// Config also initializes module defaults while cli-locale is importing it;
// its translation table is not initialized yet in that import order.
autoEnvNotice = uiText(
`[moss] Using ${offer.keyVar} → ${offer.provider} @ ${offer.baseUrl}`,
`[moss] 使用 ${offer.keyVar} → ${offer.provider} @ ${offer.baseUrl}`
);
autoEnvKeys.add('provider');
autoEnvKeys.add('model');
autoEnvKeys.add('baseUrl');
Expand Down
49 changes: 49 additions & 0 deletions test/cli-env-locale-import.spec.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import assert from 'node:assert/strict';
import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import { spawnSync } from 'node:child_process';
import test from 'node:test';

for (const locale of ['zh_CN.UTF-8', 'en_US.UTF-8']) {
test(`CLI module initializes with one environment provider in ${locale}`, () => {
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'moss-env-locale-'));
try {
const env = { ...process.env };
for (const name of Object.keys(env)) {
if (
name.startsWith('MOSS_') ||
/(?:API_KEY|API_TOKEN|ACCESS_TOKEN|BASE_URL)$/.test(name) ||
/^(?:MOSS_LANG|MOSS_LOCALE|HTTP_PROXY|HTTPS_PROXY|ALL_PROXY|http_proxy|https_proxy|all_proxy)$/.test(
name
)
)
delete env[name];
}
Object.assign(env, {
MOSS_CONFIG_DIR: dir,
LANG: locale,
LC_ALL: locale,
DEEPSEEK_API_KEY: 'fixture-key-never-send',
});
const target = new URL('../dist/cli/oneshot.js', import.meta.url).href;
const configModule = new URL('../dist/cli/config.js', import.meta.url).href;
const code = `globalThis.fetch = () => { throw new Error('Unexpected fetch during module initialization'); }; await import(${JSON.stringify(target)}); const {resolveCliConfig} = await import(${JSON.stringify(configModule)}); console.log(JSON.stringify({notice:resolveCliConfig(process.env,{},{}).autoEnvNotice}));`;
const result = spawnSync(process.execPath, ['--input-type=module', '-e', code], {
cwd: dir,
env,
encoding: 'utf8',
timeout: 10000,
});
assert.equal(result.status, 0, result.stderr);
const { notice } = JSON.parse(result.stdout);
assert.match(
notice,
locale.startsWith('zh') ? /使用 DEEPSEEK_API_KEY/ : /Using DEEPSEEK_API_KEY/
);
assert.doesNotMatch(result.stdout + result.stderr, /fixture-key-never-send/);
} finally {
fs.rmSync(dir, { recursive: true, force: true });
}
});
}
Loading