mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-09-30 01:51:20 +00:00
Merge eb94b41ea1 into 6bb99767ff
This commit is contained in:
commit
91a35fc5f2
10 changed files with 172 additions and 31 deletions
|
|
@ -890,6 +890,10 @@ gitnexus wiki --model gpt-4o
|
|||
gitnexus wiki --base-url https://api.anthropic.com/v1
|
||||
gitnexus wiki --provider grok # local Grok Build CLI (uses `grok login`, no API key)
|
||||
|
||||
# Use the Atlas Cloud preset
|
||||
export ATLASCLOUD_API_KEY=<key>
|
||||
gitnexus wiki --provider atlascloud
|
||||
|
||||
# Force full regeneration
|
||||
gitnexus wiki --force
|
||||
|
||||
|
|
|
|||
|
|
@ -290,6 +290,7 @@ gitnexus clean # Delete index for current repo
|
|||
gitnexus clean --all --force # Delete all indexes
|
||||
gitnexus wiki [path] # Generate LLM-powered docs from knowledge graph
|
||||
gitnexus wiki --model <model> # Wiki with custom LLM model (default: minimax/minimax-m2.5)
|
||||
ATLASCLOUD_API_KEY=<key> gitnexus wiki --provider atlascloud # Atlas Cloud preset
|
||||
gitnexus wiki --provider grok # Local Grok Build CLI (uses `grok login`, no API key)
|
||||
gitnexus wiki --base-url http://llama-box.local:8080/v1 --allow-insecure-connection llama-box.local
|
||||
# Allow an exact LAN/self-hosted HTTP LLM host; env: GITNEXUS_ALLOW_INSECURE_CONNECTION
|
||||
|
|
|
|||
|
|
@ -345,7 +345,7 @@ export const en = {
|
|||
'Delete the index left in <repo>/.gitnexus after this checkout moved into a shared store',
|
||||
'help.option.wiki.force': 'Force full regeneration even if up to date',
|
||||
'help.option.wiki.provider':
|
||||
'LLM provider: minimax, openai, openrouter, azure, custom, cursor, claude, codex, opencode, or grok (default: minimax)',
|
||||
'LLM provider: minimax, openai, openrouter, atlascloud, azure, custom, cursor, claude, codex, opencode, or grok (default: minimax)',
|
||||
'help.option.wiki.model': 'LLM model or deployment name (default: MiniMax-M3)',
|
||||
'help.option.wiki.baseUrl':
|
||||
'LLM API base URL. Azure v1: https://{resource}.openai.azure.com/openai/v1',
|
||||
|
|
|
|||
|
|
@ -314,7 +314,7 @@ export const zhCN = {
|
|||
'help.option.clean.localIndex': '删除此检出迁入共享存储后遗留在 <repo>/.gitnexus 中的索引',
|
||||
'help.option.wiki.force': '即使已是最新也强制完整重新生成',
|
||||
'help.option.wiki.provider':
|
||||
'LLM 提供商:minimax、openai、openrouter、azure、custom、cursor、claude、codex、opencode 或 grok(默认:minimax)',
|
||||
'LLM 提供商:minimax、openai、openrouter、atlascloud、azure、custom、cursor、claude、codex、opencode 或 grok(默认:minimax)',
|
||||
'help.option.wiki.model': 'LLM 模型或 deployment 名称(默认:MiniMax-M3)',
|
||||
'help.option.wiki.baseUrl':
|
||||
'LLM API base URL。Azure v1:https://{resource}.openai.azure.com/openai/v1',
|
||||
|
|
|
|||
|
|
@ -391,7 +391,7 @@ program
|
|||
.option('-f, --force', 'Force full regeneration even if up to date')
|
||||
.option(
|
||||
'--provider <provider>',
|
||||
'LLM provider: minimax, openai, openrouter, azure, custom, cursor, claude, codex, opencode, or grok (default: minimax)',
|
||||
'LLM provider: minimax, openai, openrouter, atlascloud, azure, custom, cursor, claude, codex, opencode, or grok (default: minimax)',
|
||||
)
|
||||
.option('--model <model>', 'LLM model or deployment name (default: MiniMax-M3)')
|
||||
.option(
|
||||
|
|
|
|||
|
|
@ -19,6 +19,9 @@ import {
|
|||
} from '../storage/storage-resolver.js';
|
||||
import { WikiGenerator, type WikiOptions } from '../core/wiki/generator.js';
|
||||
import {
|
||||
ATLAS_CLOUD_BASE_URL,
|
||||
ATLAS_CLOUD_DEFAULT_MODEL,
|
||||
getProviderEnvApiKey,
|
||||
MINIMAX_MODEL_IDS,
|
||||
MINIMAX_OPENAI_BASE_URLS,
|
||||
parseLLMAllowedInsecureHttpHosts,
|
||||
|
|
@ -220,6 +223,7 @@ const wikiCommandImpl = async (inputPath?: string, options?: WikiCommandOptions)
|
|||
|
||||
// ── Resolve LLM config (with interactive fallback) ─────────────────
|
||||
// Save any CLI overrides immediately
|
||||
let switchedToAtlasCloud = false;
|
||||
if (
|
||||
options?.apiKey ||
|
||||
options?.model ||
|
||||
|
|
@ -241,6 +245,11 @@ const wikiCommandImpl = async (inputPath?: string, options?: WikiCommandOptions)
|
|||
if (options.apiKey) updates.apiKey = options.apiKey;
|
||||
if (options.baseUrl) updates.baseUrl = options.baseUrl;
|
||||
if (options.provider) updates.provider = options.provider;
|
||||
if (options.provider === 'atlascloud' && existing.provider !== 'atlascloud') {
|
||||
switchedToAtlasCloud = true;
|
||||
if (!options.baseUrl) updates.baseUrl = ATLAS_CLOUD_BASE_URL;
|
||||
if (!options.model) updates.model = ATLAS_CLOUD_DEFAULT_MODEL;
|
||||
}
|
||||
if (options.apiVersion) updates.apiVersion = options.apiVersion;
|
||||
if (options.reasoningModel !== undefined) updates.isReasoningModel = options.reasoningModel;
|
||||
if (options.provider === 'minimax') {
|
||||
|
|
@ -290,6 +299,10 @@ const wikiCommandImpl = async (inputPath?: string, options?: WikiCommandOptions)
|
|||
isReasoningModel: options?.reasoningModel,
|
||||
allowedInsecureHttpHosts,
|
||||
});
|
||||
if (switchedToAtlasCloud && !options?.apiKey && !getProviderEnvApiKey('atlascloud')) {
|
||||
// Do not send a key saved for a different provider to Atlas Cloud.
|
||||
llmConfig.apiKey = '';
|
||||
}
|
||||
|
||||
// Run interactive setup if no saved config and no CLI flags provided
|
||||
// (even if env vars exist — let user explicitly choose their provider)
|
||||
|
|
@ -298,7 +311,9 @@ const wikiCommandImpl = async (inputPath?: string, options?: WikiCommandOptions)
|
|||
// Non-interactive mode — need either API key or Cursor CLI
|
||||
if (!llmConfig.apiKey && !isLocalProvider(llmConfig.provider)) {
|
||||
console.log(' Error: No LLM API key found.');
|
||||
console.log(' Set MINIMAX_API_KEY, GITNEXUS_API_KEY, or OPENAI_API_KEY,');
|
||||
console.log(
|
||||
' Set MINIMAX_API_KEY, ATLASCLOUD_API_KEY, GITNEXUS_API_KEY, or OPENAI_API_KEY,',
|
||||
);
|
||||
console.log(
|
||||
' or pass --api-key <key>, or use --provider cursor|claude|codex|opencode|grok.\n',
|
||||
);
|
||||
|
|
@ -308,7 +323,9 @@ const wikiCommandImpl = async (inputPath?: string, options?: WikiCommandOptions)
|
|||
// Non-interactive with env var or cursor — just use it
|
||||
} else {
|
||||
console.log(" No LLM configured. Let's set it up.\n");
|
||||
console.log(' Supports MiniMax, OpenAI-compatible APIs, and local agent CLIs.\n');
|
||||
console.log(
|
||||
' Supports MiniMax, OpenAI, OpenRouter, Atlas Cloud, Azure, custom OpenAI-compatible APIs, and local agent CLIs.\n',
|
||||
);
|
||||
|
||||
// Check if local agent CLIs are available.
|
||||
const hasCursor = detectCursorCLI();
|
||||
|
|
@ -325,10 +342,11 @@ const wikiCommandImpl = async (inputPath?: string, options?: WikiCommandOptions)
|
|||
console.log(' [1] OpenAI (api.openai.com)');
|
||||
console.log(' [2] OpenRouter (openrouter.ai)');
|
||||
console.log(' [3] Azure OpenAI');
|
||||
console.log(' [4] Custom endpoint');
|
||||
console.log(' [5] MiniMax Global (api.minimax.io)');
|
||||
console.log(' [6] MiniMax China (api.minimaxi.com)');
|
||||
let nextChoice = 7;
|
||||
console.log(' [4] Atlas Cloud (api.atlascloud.ai)');
|
||||
console.log(' [5] Custom endpoint');
|
||||
console.log(' [6] MiniMax Global (api.minimax.io)');
|
||||
console.log(' [7] MiniMax China (api.minimaxi.com)');
|
||||
let nextChoice = 8;
|
||||
if (hasCursor) {
|
||||
const choice = String(nextChoice++);
|
||||
localChoices.push({
|
||||
|
|
@ -463,6 +481,10 @@ const wikiCommandImpl = async (inputPath?: string, options?: WikiCommandOptions)
|
|||
defaultModel = '';
|
||||
provider = 'openrouter';
|
||||
} else if (choice === '4') {
|
||||
baseUrl = ATLAS_CLOUD_BASE_URL;
|
||||
defaultModel = ATLAS_CLOUD_DEFAULT_MODEL;
|
||||
provider = 'atlascloud';
|
||||
} else if (choice === '5') {
|
||||
baseUrl = await prompt(' Base URL (e.g. http://localhost:11434/v1): ');
|
||||
if (!baseUrl) {
|
||||
console.log('\n No URL provided. Aborting.\n');
|
||||
|
|
@ -471,9 +493,9 @@ const wikiCommandImpl = async (inputPath?: string, options?: WikiCommandOptions)
|
|||
}
|
||||
defaultModel = 'gpt-4o-mini';
|
||||
provider = 'custom';
|
||||
} else if (choice === '5' || choice === '6') {
|
||||
} else if (choice === '6' || choice === '7') {
|
||||
baseUrl =
|
||||
choice === '6' ? MINIMAX_OPENAI_BASE_URLS.cn_zh : MINIMAX_OPENAI_BASE_URLS.global_en;
|
||||
choice === '7' ? MINIMAX_OPENAI_BASE_URLS.cn_zh : MINIMAX_OPENAI_BASE_URLS.global_en;
|
||||
defaultModel = MINIMAX_MODEL_IDS[0];
|
||||
provider = 'minimax';
|
||||
} else {
|
||||
|
|
@ -494,11 +516,7 @@ const wikiCommandImpl = async (inputPath?: string, options?: WikiCommandOptions)
|
|||
}
|
||||
|
||||
// API key — pre-fill hint if env var exists
|
||||
const envKey =
|
||||
(provider === 'minimax' ? process.env.MINIMAX_API_KEY : undefined) ||
|
||||
process.env.GITNEXUS_API_KEY ||
|
||||
process.env.OPENAI_API_KEY ||
|
||||
'';
|
||||
const envKey = getProviderEnvApiKey(provider);
|
||||
if (envKey) {
|
||||
const masked = envKey.slice(0, 6) + '...' + envKey.slice(-4);
|
||||
const useEnv = await prompt(` Use existing env key (${masked})? (Y/n): `);
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { CircuitOpenError, ResilientFetchExhaustedError, resilientFetch } from '
|
|||
* LLM Client for Wiki Generation
|
||||
*
|
||||
* OpenAI-compatible API client using native fetch.
|
||||
* Supports MiniMax and other OpenAI-compatible endpoints.
|
||||
* Supports MiniMax, Atlas Cloud, and other OpenAI-compatible endpoints.
|
||||
*
|
||||
* Config priority: CLI flags > env vars > defaults
|
||||
*/
|
||||
|
|
@ -12,6 +12,7 @@ import { CircuitOpenError, ResilientFetchExhaustedError, resilientFetch } from '
|
|||
export type LLMProvider =
|
||||
| 'openai'
|
||||
| 'openrouter'
|
||||
| 'atlascloud'
|
||||
| 'azure'
|
||||
| 'custom'
|
||||
| 'cursor'
|
||||
|
|
@ -53,6 +54,9 @@ export type LLMUserContent =
|
|||
}
|
||||
>;
|
||||
|
||||
export const ATLAS_CLOUD_BASE_URL = 'https://api.atlascloud.ai/v1';
|
||||
export const ATLAS_CLOUD_DEFAULT_MODEL = 'deepseek-ai/deepseek-v4-pro';
|
||||
|
||||
export interface LLMConfig {
|
||||
apiKey: string;
|
||||
baseUrl: string;
|
||||
|
|
@ -79,6 +83,21 @@ export interface LLMResponse {
|
|||
completionTokens?: number;
|
||||
}
|
||||
|
||||
export function getProviderEnvApiKey(provider: LLMProvider | undefined): string {
|
||||
if (provider === 'atlascloud') {
|
||||
return process.env.ATLASCLOUD_API_KEY || process.env.GITNEXUS_API_KEY || '';
|
||||
}
|
||||
if (provider === 'minimax') {
|
||||
return (
|
||||
process.env.MINIMAX_API_KEY ||
|
||||
process.env.GITNEXUS_API_KEY ||
|
||||
process.env.OPENAI_API_KEY ||
|
||||
''
|
||||
);
|
||||
}
|
||||
return process.env.GITNEXUS_API_KEY || process.env.OPENAI_API_KEY || '';
|
||||
}
|
||||
|
||||
export function resolveMiniMaxThinkingMode(
|
||||
model: string,
|
||||
reasoningOverride?: boolean,
|
||||
|
|
@ -123,13 +142,24 @@ export async function resolveLLMConfig(overrides?: Partial<LLMConfig>): Promise<
|
|||
savedProvider === 'opencode' ||
|
||||
savedProvider === 'grok';
|
||||
|
||||
const envApiKey =
|
||||
savedProvider === 'minimax'
|
||||
? process.env.MINIMAX_API_KEY || ''
|
||||
: getProviderEnvApiKey(savedProvider);
|
||||
const apiKey =
|
||||
overrides?.apiKey ||
|
||||
(savedProvider === 'minimax' ? process.env.MINIMAX_API_KEY : undefined) ||
|
||||
(savedProvider !== 'minimax' ? process.env.GITNEXUS_API_KEY : undefined) ||
|
||||
(savedProvider !== 'minimax' ? process.env.OPENAI_API_KEY : undefined) ||
|
||||
(reuseSavedHttpConfig ? savedConfig.apiKey : undefined) ||
|
||||
'';
|
||||
overrides?.apiKey || envApiKey || (reuseSavedHttpConfig ? savedConfig.apiKey : undefined) || '';
|
||||
const defaultBaseUrl =
|
||||
savedProvider === 'atlascloud'
|
||||
? ATLAS_CLOUD_BASE_URL
|
||||
: savedProvider === 'minimax'
|
||||
? MINIMAX_OPENAI_BASE_URLS.global_en
|
||||
: 'https://openrouter.ai/api/v1';
|
||||
const defaultModel =
|
||||
savedProvider === 'atlascloud'
|
||||
? ATLAS_CLOUD_DEFAULT_MODEL
|
||||
: savedProvider === 'minimax'
|
||||
? MINIMAX_MODEL_IDS[0]
|
||||
: '';
|
||||
|
||||
return {
|
||||
apiKey,
|
||||
|
|
@ -137,17 +167,12 @@ export async function resolveLLMConfig(overrides?: Partial<LLMConfig>): Promise<
|
|||
overrides?.baseUrl ||
|
||||
process.env.GITNEXUS_LLM_BASE_URL ||
|
||||
(reuseSavedHttpConfig ? savedConfig.baseUrl : undefined) ||
|
||||
(savedProvider === 'minimax'
|
||||
? MINIMAX_OPENAI_BASE_URLS.global_en
|
||||
: 'https://openrouter.ai/api/v1'),
|
||||
defaultBaseUrl,
|
||||
model:
|
||||
overrides?.model ||
|
||||
(localProvider ? undefined : process.env.GITNEXUS_MODEL) ||
|
||||
savedLocalModel ||
|
||||
(localProvider
|
||||
? ''
|
||||
: (reuseSavedHttpConfig ? savedConfig.model : undefined) ||
|
||||
(savedProvider === 'minimax' ? MINIMAX_MODEL_IDS[0] : '')),
|
||||
(localProvider ? '' : (reuseSavedHttpConfig ? savedConfig.model : undefined) || defaultModel),
|
||||
maxTokens: overrides?.maxTokens ?? 16_384,
|
||||
temperature: overrides?.temperature ?? 0,
|
||||
provider: savedProvider,
|
||||
|
|
|
|||
|
|
@ -1822,6 +1822,7 @@ export interface CLIConfig {
|
|||
provider?:
|
||||
| 'openai'
|
||||
| 'openrouter'
|
||||
| 'atlascloud'
|
||||
| 'azure'
|
||||
| 'custom'
|
||||
| 'cursor'
|
||||
|
|
|
|||
|
|
@ -168,6 +168,13 @@ describe('CLI help surface', () => {
|
|||
expect(result.stdout).toContain('-c, --coding-agent <agents>');
|
||||
});
|
||||
|
||||
it('wiki help lists the Atlas Cloud provider preset', () => {
|
||||
const result = runHelp('wiki');
|
||||
|
||||
expect(result.status).toBe(0);
|
||||
expect(result.stdout).toContain('atlascloud');
|
||||
});
|
||||
|
||||
it('localizes every registered CLI command and option description in zh-CN help', () => {
|
||||
const zhHelpOutput = allHelpCommands
|
||||
.map((args) => {
|
||||
|
|
|
|||
|
|
@ -138,9 +138,22 @@ describe('detectLocalCLI', () => {
|
|||
|
||||
describe('resolveLLMConfig', () => {
|
||||
let tmpDir: string;
|
||||
const envKeys = [
|
||||
'ATLASCLOUD_API_KEY',
|
||||
'GITNEXUS_API_KEY',
|
||||
'OPENAI_API_KEY',
|
||||
'GITNEXUS_LLM_BASE_URL',
|
||||
'GITNEXUS_MODEL',
|
||||
] as const;
|
||||
let originalEnv: Record<(typeof envKeys)[number], string | undefined>;
|
||||
|
||||
beforeEach(async () => {
|
||||
vi.resetModules();
|
||||
originalEnv = Object.fromEntries(envKeys.map((key) => [key, process.env[key]])) as Record<
|
||||
(typeof envKeys)[number],
|
||||
string | undefined
|
||||
>;
|
||||
for (const key of envKeys) delete process.env[key];
|
||||
tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'wiki-test-config-'));
|
||||
// Create empty config so loadCLIConfig returns {}
|
||||
const configDir = path.join(tmpDir, '.gitnexus');
|
||||
|
|
@ -151,6 +164,11 @@ describe('resolveLLMConfig', () => {
|
|||
afterEach(async () => {
|
||||
vi.restoreAllMocks();
|
||||
vi.unstubAllEnvs();
|
||||
for (const key of envKeys) {
|
||||
const value = originalEnv[key];
|
||||
if (value === undefined) delete process.env[key];
|
||||
else process.env[key] = value;
|
||||
}
|
||||
await fs.rm(tmpDir, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
|
|
@ -343,6 +361,27 @@ describe('resolveLLMConfig', () => {
|
|||
expect(config.baseUrl).toBe('https://legacy.example/v1');
|
||||
});
|
||||
|
||||
it('uses Atlas Cloud defaults and its provider-specific API key', async () => {
|
||||
process.env.ATLASCLOUD_API_KEY = 'atlas-key';
|
||||
process.env.OPENAI_API_KEY = 'openai-key';
|
||||
vi.doMock('../../src/storage/repo-manager.js', () => ({
|
||||
loadCLIConfig: vi.fn().mockResolvedValue({
|
||||
provider: 'openai',
|
||||
apiKey: 'saved-openai-key',
|
||||
baseUrl: 'https://api.openai.com/v1',
|
||||
model: 'gpt-4o-mini',
|
||||
}),
|
||||
}));
|
||||
|
||||
const { resolveLLMConfig } = await import('../../src/core/wiki/llm-client.js');
|
||||
const config = await resolveLLMConfig({ provider: 'atlascloud' });
|
||||
|
||||
expect(config.provider).toBe('atlascloud');
|
||||
expect(config.apiKey).toBe('atlas-key');
|
||||
expect(config.baseUrl).toBe('https://api.atlascloud.ai/v1');
|
||||
expect(config.model).toBe('deepseek-ai/deepseek-v4-pro');
|
||||
});
|
||||
|
||||
it('CLI overrides take priority over saved config', async () => {
|
||||
vi.doMock('../../src/storage/repo-manager.js', () => ({
|
||||
loadCLIConfig: vi.fn().mockResolvedValue({
|
||||
|
|
@ -842,6 +881,7 @@ describe('wikiCommand --timeout mapping', () => {
|
|||
|
||||
async function loadWikiCommandHarness() {
|
||||
let capturedConfig: Record<string, unknown> | undefined;
|
||||
const saveCLIConfig = vi.fn();
|
||||
const resolveLLMConfig = vi.fn().mockImplementation((overrides = {}) =>
|
||||
Promise.resolve({
|
||||
apiKey: 'sk-test',
|
||||
|
|
@ -877,7 +917,7 @@ describe('wikiCommand --timeout mapping', () => {
|
|||
model: 'gpt-4o',
|
||||
provider: 'openai',
|
||||
}),
|
||||
saveCLIConfig: vi.fn(),
|
||||
saveCLIConfig,
|
||||
}));
|
||||
vi.doMock('../../src/core/wiki/llm-client.js', async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import('../../src/core/wiki/llm-client.js')>();
|
||||
|
|
@ -911,9 +951,54 @@ describe('wikiCommand --timeout mapping', () => {
|
|||
consoleSpy,
|
||||
getCapturedConfig: () => capturedConfig,
|
||||
resolveLLMConfig,
|
||||
saveCLIConfig,
|
||||
};
|
||||
}
|
||||
|
||||
it('switches to Atlas Cloud without overwriting a saved key from another provider', async () => {
|
||||
const originalAtlasKey = process.env.ATLASCLOUD_API_KEY;
|
||||
const originalGitNexusKey = process.env.GITNEXUS_API_KEY;
|
||||
delete process.env.ATLASCLOUD_API_KEY;
|
||||
delete process.env.GITNEXUS_API_KEY;
|
||||
const harness = await loadWikiCommandHarness();
|
||||
|
||||
try {
|
||||
await harness.wikiCommand('/tmp/repo', { provider: 'atlascloud' });
|
||||
|
||||
expect(harness.saveCLIConfig).toHaveBeenCalledWith({
|
||||
apiKey: undefined,
|
||||
baseUrl: 'https://api.atlascloud.ai/v1',
|
||||
model: 'deepseek-ai/deepseek-v4-pro',
|
||||
provider: 'atlascloud',
|
||||
});
|
||||
expect(harness.getCapturedConfig()?.apiKey).toBe('');
|
||||
} finally {
|
||||
if (originalAtlasKey === undefined) delete process.env.ATLASCLOUD_API_KEY;
|
||||
else process.env.ATLASCLOUD_API_KEY = originalAtlasKey;
|
||||
if (originalGitNexusKey === undefined) delete process.env.GITNEXUS_API_KEY;
|
||||
else process.env.GITNEXUS_API_KEY = originalGitNexusKey;
|
||||
}
|
||||
});
|
||||
|
||||
it('preserves the Atlas Cloud fallback key when GITNEXUS_API_KEY is set', async () => {
|
||||
const originalAtlasKey = process.env.ATLASCLOUD_API_KEY;
|
||||
const originalGitNexusKey = process.env.GITNEXUS_API_KEY;
|
||||
delete process.env.ATLASCLOUD_API_KEY;
|
||||
process.env.GITNEXUS_API_KEY = 'gitnexus-test-key';
|
||||
const harness = await loadWikiCommandHarness();
|
||||
|
||||
try {
|
||||
await harness.wikiCommand('/tmp/repo', { provider: 'atlascloud' });
|
||||
|
||||
expect(harness.getCapturedConfig()?.apiKey).toBeUndefined();
|
||||
} finally {
|
||||
if (originalAtlasKey === undefined) delete process.env.ATLASCLOUD_API_KEY;
|
||||
else process.env.ATLASCLOUD_API_KEY = originalAtlasKey;
|
||||
if (originalGitNexusKey === undefined) delete process.env.GITNEXUS_API_KEY;
|
||||
else process.env.GITNEXUS_API_KEY = originalGitNexusKey;
|
||||
}
|
||||
});
|
||||
|
||||
it('maps --timeout seconds to requestTimeoutMs before constructing WikiGenerator', async () => {
|
||||
const harness = await loadWikiCommandHarness();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue