Skip to content

Commit 934ab0e

Browse files
committed
Add ability to store API keys in configuration (fixes #134)
1 parent 97704ef commit 934ab0e

File tree

3 files changed

+47
-1
lines changed

3 files changed

+47
-1
lines changed

packages/cli/src/commands/$default.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,12 +107,25 @@ export const command: CommandModule<SharedOptions, DefaultArgs> = {
107107

108108
if (providerSettings) {
109109
const { keyName } = providerSettings;
110-
const apiKey = process.env[keyName];
110+
111+
// First check if the API key is in the config
112+
const configApiKey = userConfig[keyName as keyof typeof userConfig] as string;
113+
// Then fall back to environment variable
114+
const envApiKey = process.env[keyName];
115+
// Use config key if available, otherwise use env key
116+
const apiKey = configApiKey || envApiKey;
111117

112118
if (!apiKey) {
113119
logger.error(getProviderApiKeyError(userModelProvider));
114120
throw new Error(`${userModelProvider} API key not found`);
115121
}
122+
123+
// If we're using a key from config, set it as an environment variable
124+
// This ensures it's available to the provider libraries
125+
if (configApiKey && !envApiKey) {
126+
process.env[keyName] = configApiKey;
127+
logger.debug(`Using ${keyName} from configuration`);
128+
}
116129
}
117130
// No API key check needed for Ollama as it uses a local server
118131

packages/cli/src/commands/config.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ export const command: CommandModule<SharedOptions, ConfigOptions> = {
4545
.example(
4646
'$0 config clear customPrompt',
4747
'Reset customPrompt to default value',
48+
)
49+
.example(
50+
'$0 config set ANTHROPIC_API_KEY <your-key>',
51+
'Store your Anthropic API key in configuration',
4852
) as any; // eslint-disable-line @typescript-eslint/no-explicit-any
4953
},
5054
handler: async (argv: ArgumentsCamelCase<ConfigOptions>) => {
@@ -120,6 +124,30 @@ export const command: CommandModule<SharedOptions, ConfigOptions> = {
120124
return;
121125
}
122126

127+
// Check if this is an API key and add a warning
128+
if (argv.key.includes('API_KEY')) {
129+
logger.warn(
130+
chalk.yellow(
131+
'Warning: Storing API keys in configuration is less secure than using environment variables.'
132+
)
133+
);
134+
logger.warn(
135+
chalk.yellow(
136+
'Your API key will be stored in plaintext in the configuration file.'
137+
)
138+
);
139+
140+
// Ask for confirmation
141+
const isConfirmed = await confirm(
142+
'Do you want to continue storing your API key in the configuration?'
143+
);
144+
145+
if (!isConfirmed) {
146+
logger.info('Operation cancelled.');
147+
return;
148+
}
149+
}
150+
123151
// Parse the value based on current type or infer boolean/number
124152
let parsedValue: string | boolean | number = argv.value;
125153

packages/cli/src/settings/config.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ const defaultConfig = {
2020
customPrompt: '',
2121
profile: false,
2222
tokenCache: true,
23+
// API keys (empty by default)
24+
ANTHROPIC_API_KEY: '',
25+
OPENAI_API_KEY: '',
26+
XAI_API_KEY: '',
27+
MISTRAL_API_KEY: '',
2328
};
2429

2530
export type Config = typeof defaultConfig;

0 commit comments

Comments
 (0)