wiggum-cli 0.11.13 → 0.11.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +6 -1
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +9 -17
- package/dist/commands/config.js.map +1 -1
- package/dist/templates/root/.gitignore.tmpl +1 -0
- package/dist/tui/hooks/useInit.js +1 -1
- package/dist/tui/hooks/useInit.js.map +1 -1
- package/dist/tui/screens/InitScreen.d.ts.map +1 -1
- package/dist/tui/screens/InitScreen.js +5 -26
- package/dist/tui/screens/InitScreen.js.map +1 -1
- package/dist/utils/env.d.ts +16 -1
- package/dist/utils/env.d.ts.map +1 -1
- package/dist/utils/env.js +55 -4
- package/dist/utils/env.js.map +1 -1
- package/package.json +1 -1
- package/src/commands/config.test.ts +225 -0
- package/src/commands/config.ts +9 -18
- package/src/templates/root/.gitignore.tmpl +1 -0
- package/src/tui/hooks/useInit.ts +1 -1
- package/src/tui/screens/InitScreen.tsx +5 -27
- package/src/utils/env.test.ts +220 -20
- package/src/utils/env.ts +60 -4
|
@@ -27,7 +27,12 @@
|
|
|
27
27
|
"Bash(npm install:*)",
|
|
28
28
|
"Bash(git init:*)",
|
|
29
29
|
"Bash(git add:*)",
|
|
30
|
-
"Bash(git commit -m \"$\\(cat <<''EOF''\nchore: scaffold Astro project with Tailwind, Cloudflare, and sitemap\n\nInitialized wiggum-website with Astro minimal template, added Tailwind CSS v4,\nCloudflare adapter, sitemap integration, and self-hosted font packages\n\\(IBM Plex Mono, Instrument Serif\\).\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>\nEOF\n\\)\")"
|
|
30
|
+
"Bash(git commit -m \"$\\(cat <<''EOF''\nchore: scaffold Astro project with Tailwind, Cloudflare, and sitemap\n\nInitialized wiggum-website with Astro minimal template, added Tailwind CSS v4,\nCloudflare adapter, sitemap integration, and self-hosted font packages\n\\(IBM Plex Mono, Instrument Serif\\).\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>\nEOF\n\\)\")",
|
|
31
|
+
"mcp__plugin_playwright_playwright__browser_navigate",
|
|
32
|
+
"mcp__plugin_playwright_playwright__browser_resize",
|
|
33
|
+
"mcp__plugin_playwright_playwright__browser_take_screenshot",
|
|
34
|
+
"Bash(curl:*)",
|
|
35
|
+
"mcp__plugin_playwright_playwright__browser_close"
|
|
31
36
|
]
|
|
32
37
|
}
|
|
33
38
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAkF7D;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,MAAM,EAAE,EACd,KAAK,EAAE,YAAY,GAClB,OAAO,CAAC,YAAY,CAAC,CA+DvB"}
|
package/dist/commands/config.js
CHANGED
|
@@ -8,6 +8,7 @@ import pc from 'picocolors';
|
|
|
8
8
|
import { logger } from '../utils/logger.js';
|
|
9
9
|
import { simpson } from '../utils/colors.js';
|
|
10
10
|
import { getAvailableProvider, AVAILABLE_MODELS } from '../ai/providers.js';
|
|
11
|
+
import { writeKeysToEnvFile } from '../utils/env.js';
|
|
11
12
|
/**
|
|
12
13
|
* Supported services for API key configuration
|
|
13
14
|
*/
|
|
@@ -33,25 +34,16 @@ function isServiceConfigured(service) {
|
|
|
33
34
|
return !!process.env[envVar];
|
|
34
35
|
}
|
|
35
36
|
/**
|
|
36
|
-
* Save an API key to .env.local file
|
|
37
|
+
* Save an API key to .ralph/.env.local file
|
|
37
38
|
*/
|
|
38
39
|
function saveKeyToEnvLocal(projectRoot, envVar, value) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
envContent = fs.readFileSync(envLocalPath, 'utf-8');
|
|
40
|
+
// Check that .ralph/ exists (project is initialized)
|
|
41
|
+
const ralphDir = path.join(projectRoot, '.ralph');
|
|
42
|
+
if (!fs.existsSync(ralphDir) || !fs.statSync(ralphDir).isDirectory()) {
|
|
43
|
+
throw new Error('This project is not initialized. Run \'ralph init\' to set up .ralph/ before using \'ralph config set\'.');
|
|
44
44
|
}
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
// Replace existing key
|
|
48
|
-
envContent = envContent.replace(keyRegex, `${envVar}=${value}`);
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
// Append new key
|
|
52
|
-
envContent = envContent.trimEnd() + (envContent ? '\n' : '') + `${envVar}=${value}\n`;
|
|
53
|
-
}
|
|
54
|
-
fs.writeFileSync(envLocalPath, envContent);
|
|
45
|
+
const envLocalPath = path.join(ralphDir, '.env.local');
|
|
46
|
+
writeKeysToEnvFile(envLocalPath, { [envVar]: value });
|
|
55
47
|
}
|
|
56
48
|
/**
|
|
57
49
|
* Display current configuration status
|
|
@@ -133,7 +125,7 @@ export async function handleConfigCommand(args, state) {
|
|
|
133
125
|
saveKeyToEnvLocal(state.projectRoot, envVar, apiKey);
|
|
134
126
|
// Also set in current process environment
|
|
135
127
|
process.env[envVar] = apiKey;
|
|
136
|
-
logger.success(`${envVar} saved to .env.local`);
|
|
128
|
+
logger.success(`${envVar} saved to .ralph/.env.local`);
|
|
137
129
|
console.log(pc.dim('Restart Wiggum to apply changes to tool availability.'));
|
|
138
130
|
console.log('');
|
|
139
131
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useInit.js","sourceRoot":"","sources":["../../../src/tui/hooks/useInit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAiCtD;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAuC;IACpE,QAAQ,EAAE;QACR,MAAM,EAAE,CAAC;QACT,IAAI,EAAE,UAAU;QAChB,WAAW,EAAE,6BAA6B;KAC3C;IACD,iBAAiB,EAAE;QACjB,MAAM,EAAE,CAAC;QACT,IAAI,EAAE,UAAU;QAChB,WAAW,EAAE,oBAAoB;KAClC;IACD,WAAW,EAAE;QACX,MAAM,EAAE,CAAC;QACT,IAAI,EAAE,SAAS;QACf,WAAW,EAAE,eAAe;KAC7B;IACD,UAAU,EAAE;QACV,MAAM,EAAE,CAAC;QACT,IAAI,EAAE,UAAU;QAChB,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"useInit.js","sourceRoot":"","sources":["../../../src/tui/hooks/useInit.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InitScreen.d.ts","sourceRoot":"","sources":["../../../src/tui/screens/InitScreen.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAyC,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"InitScreen.d.ts","sourceRoot":"","sources":["../../../src/tui/screens/InitScreen.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAyC,MAAM,OAAO,CAAC;AA8B9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAGhE;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,6BAA6B;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,4BAA4B;IAC5B,YAAY,EAAE,YAAY,CAAC;IAC3B,kFAAkF;IAClF,UAAU,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,cAAc,CAAC,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACxE,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAuBD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,EACzB,WAAW,EACX,YAAY,EACZ,UAAU,EACV,QAAQ,GACT,EAAE,eAAe,GAAG,KAAK,CAAC,YAAY,CAmetC"}
|
|
@@ -25,7 +25,7 @@ import { getApiKeyEnvVar, getAvailableProvider, AVAILABLE_MODELS, } from '../../
|
|
|
25
25
|
import { Generator } from '../../generator/index.js';
|
|
26
26
|
import { loadConfigWithDefaults } from '../../utils/config.js';
|
|
27
27
|
import { initTracing, flushTracing, traced } from '../../utils/tracing.js';
|
|
28
|
-
import
|
|
28
|
+
import { writeKeysToEnvFile } from '../../utils/env.js';
|
|
29
29
|
import path from 'node:path';
|
|
30
30
|
import { updateSessionState } from '../../repl/session-state.js';
|
|
31
31
|
/**
|
|
@@ -46,28 +46,6 @@ function getModelOptions(provider) {
|
|
|
46
46
|
hint: m.hint,
|
|
47
47
|
}));
|
|
48
48
|
}
|
|
49
|
-
/**
|
|
50
|
-
* Save API keys to .env.local file
|
|
51
|
-
*/
|
|
52
|
-
function saveKeysToEnvLocal(projectRoot, keys) {
|
|
53
|
-
const envLocalPath = path.join(projectRoot, '.env.local');
|
|
54
|
-
let envContent = '';
|
|
55
|
-
if (fs.existsSync(envLocalPath)) {
|
|
56
|
-
envContent = fs.readFileSync(envLocalPath, 'utf-8');
|
|
57
|
-
}
|
|
58
|
-
for (const [envVar, value] of Object.entries(keys)) {
|
|
59
|
-
if (!value)
|
|
60
|
-
continue;
|
|
61
|
-
const keyRegex = new RegExp(`^${envVar}=.*$`, 'm');
|
|
62
|
-
if (keyRegex.test(envContent)) {
|
|
63
|
-
envContent = envContent.replace(keyRegex, `${envVar}=${value}`);
|
|
64
|
-
}
|
|
65
|
-
else {
|
|
66
|
-
envContent = envContent.trimEnd() + (envContent ? '\n' : '') + `${envVar}=${value}\n`;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
fs.writeFileSync(envLocalPath, envContent);
|
|
70
|
-
}
|
|
71
49
|
/**
|
|
72
50
|
* InitScreen component
|
|
73
51
|
*
|
|
@@ -202,10 +180,11 @@ export function InitScreen({ projectRoot, sessionState, onComplete, onCancel, })
|
|
|
202
180
|
const generatedFiles = generationResult.writeSummary.results
|
|
203
181
|
.filter((f) => f.action === 'created' || f.action === 'backed_up' || f.action === 'overwritten')
|
|
204
182
|
.map((f) => path.relative(projectRoot, f.path));
|
|
205
|
-
// Save API key to .env.local if requested
|
|
183
|
+
// Save API key to .ralph/.env.local if requested
|
|
206
184
|
if (state.apiKeyEnteredThisSession && state.saveKeyToEnv && state.provider && apiKeyRef.current) {
|
|
207
185
|
const envVar = getApiKeyEnvVar(state.provider);
|
|
208
|
-
|
|
186
|
+
const envLocalPath = path.join(projectRoot, '.ralph', '.env.local');
|
|
187
|
+
writeKeysToEnvFile(envLocalPath, { [envVar]: apiKeyRef.current });
|
|
209
188
|
}
|
|
210
189
|
setGenerationComplete(generatedFiles);
|
|
211
190
|
// Load config and update session state
|
|
@@ -288,7 +267,7 @@ export function InitScreen({ projectRoot, sessionState, onComplete, onCancel, })
|
|
|
288
267
|
case 'key-input':
|
|
289
268
|
return (_jsx(PasswordInput, { message: `Enter your ${state.provider ? getApiKeyEnvVar(state.provider) : 'API key'}:`, onSubmit: handleApiKeySubmit, onCancel: onCancel }));
|
|
290
269
|
case 'key-save':
|
|
291
|
-
return (_jsx(Confirm, { message: "Save API key to .env.local?", onConfirm: handleSaveKeyConfirm, onCancel: onCancel, initialValue: true }));
|
|
270
|
+
return (_jsx(Confirm, { message: "Save API key to .ralph/.env.local?", onConfirm: handleSaveKeyConfirm, onCancel: onCancel, initialValue: true }));
|
|
292
271
|
case 'model-select':
|
|
293
272
|
if (!state.provider)
|
|
294
273
|
return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InitScreen.js","sourceRoot":"","sources":["../../../src/tui/screens/InitScreen.tsx"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"InitScreen.js","sourceRoot":"","sources":["../../../src/tui/screens/InitScreen.tsx"],"names":[],"mappings":"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"}
|
package/dist/utils/env.d.ts
CHANGED
|
@@ -11,12 +11,27 @@
|
|
|
11
11
|
* - Strips matching surrounding quotes (single or double) from values.
|
|
12
12
|
*/
|
|
13
13
|
export declare function parseEnvContent(content: string): Record<string, string>;
|
|
14
|
+
/**
|
|
15
|
+
* Write API keys to an env file, preserving existing content.
|
|
16
|
+
*
|
|
17
|
+
* - Merges keys into existing file content (preserves other keys).
|
|
18
|
+
* - Replaces existing key values if the key already exists.
|
|
19
|
+
* - Creates parent directories if they don't exist.
|
|
20
|
+
* - Creates the file if it doesn't exist.
|
|
21
|
+
* - Skips empty values (keys with empty strings are ignored).
|
|
22
|
+
*
|
|
23
|
+
* @param filePath - Absolute path to the .env.local file
|
|
24
|
+
* @param keys - Record of environment variable names to values
|
|
25
|
+
*/
|
|
26
|
+
export declare function writeKeysToEnvFile(filePath: string, keys: Record<string, string>): void;
|
|
14
27
|
/**
|
|
15
28
|
* Load known AI provider API keys from .ralph/.env.local into process.env.
|
|
16
29
|
*
|
|
30
|
+
* - Prefers .ralph/.env.local as the canonical source (if it exists).
|
|
31
|
+
* - Falls back to root .env.local if .ralph/.env.local does not exist (backward compatibility).
|
|
17
32
|
* - Only keys in KNOWN_API_KEYS are loaded; all others are ignored.
|
|
18
33
|
* - File values override existing process.env values (file takes precedence).
|
|
19
|
-
* - If
|
|
34
|
+
* - If neither file exists or cannot be read, this is a silent no-op.
|
|
20
35
|
* - Malformed lines are skipped without aborting.
|
|
21
36
|
*/
|
|
22
37
|
export declare function loadApiKeysFromEnvLocal(): void;
|
package/dist/utils/env.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/utils/env.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CA2BvE;AAED
|
|
1
|
+
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/utils/env.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CA2BvE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CA8BvF;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,IAAI,IAAI,CA0B9C"}
|
package/dist/utils/env.js
CHANGED
|
@@ -39,18 +39,69 @@ export function parseEnvContent(content) {
|
|
|
39
39
|
}
|
|
40
40
|
return result;
|
|
41
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Write API keys to an env file, preserving existing content.
|
|
44
|
+
*
|
|
45
|
+
* - Merges keys into existing file content (preserves other keys).
|
|
46
|
+
* - Replaces existing key values if the key already exists.
|
|
47
|
+
* - Creates parent directories if they don't exist.
|
|
48
|
+
* - Creates the file if it doesn't exist.
|
|
49
|
+
* - Skips empty values (keys with empty strings are ignored).
|
|
50
|
+
*
|
|
51
|
+
* @param filePath - Absolute path to the .env.local file
|
|
52
|
+
* @param keys - Record of environment variable names to values
|
|
53
|
+
*/
|
|
54
|
+
export function writeKeysToEnvFile(filePath, keys) {
|
|
55
|
+
// Ensure parent directory exists
|
|
56
|
+
const dir = path.dirname(filePath);
|
|
57
|
+
if (!fs.existsSync(dir)) {
|
|
58
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
59
|
+
}
|
|
60
|
+
// Read existing content if file exists
|
|
61
|
+
let envContent = '';
|
|
62
|
+
if (fs.existsSync(filePath)) {
|
|
63
|
+
envContent = fs.readFileSync(filePath, 'utf-8');
|
|
64
|
+
}
|
|
65
|
+
// Merge keys into content
|
|
66
|
+
const escapeRegex = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
67
|
+
for (const [envVar, value] of Object.entries(keys)) {
|
|
68
|
+
if (!value)
|
|
69
|
+
continue; // Skip empty values
|
|
70
|
+
const keyRegex = new RegExp(`^${escapeRegex(envVar)}=.*$`, 'm');
|
|
71
|
+
if (keyRegex.test(envContent)) {
|
|
72
|
+
// Replace existing key
|
|
73
|
+
envContent = envContent.replace(keyRegex, `${envVar}=${value}`);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
// Append new key
|
|
77
|
+
envContent = envContent.trimEnd() + (envContent ? '\n' : '') + `${envVar}=${value}\n`;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
fs.writeFileSync(filePath, envContent);
|
|
81
|
+
}
|
|
42
82
|
/**
|
|
43
83
|
* Load known AI provider API keys from .ralph/.env.local into process.env.
|
|
44
84
|
*
|
|
85
|
+
* - Prefers .ralph/.env.local as the canonical source (if it exists).
|
|
86
|
+
* - Falls back to root .env.local if .ralph/.env.local does not exist (backward compatibility).
|
|
45
87
|
* - Only keys in KNOWN_API_KEYS are loaded; all others are ignored.
|
|
46
88
|
* - File values override existing process.env values (file takes precedence).
|
|
47
|
-
* - If
|
|
89
|
+
* - If neither file exists or cannot be read, this is a silent no-op.
|
|
48
90
|
* - Malformed lines are skipped without aborting.
|
|
49
91
|
*/
|
|
50
92
|
export function loadApiKeysFromEnvLocal() {
|
|
51
93
|
try {
|
|
52
|
-
const
|
|
53
|
-
|
|
94
|
+
const ralphEnvPath = path.join(process.cwd(), '.ralph', '.env.local');
|
|
95
|
+
const rootEnvPath = path.join(process.cwd(), '.env.local');
|
|
96
|
+
// Prefer .ralph/.env.local, fall back to root .env.local
|
|
97
|
+
let envPath = null;
|
|
98
|
+
if (fs.existsSync(ralphEnvPath)) {
|
|
99
|
+
envPath = ralphEnvPath;
|
|
100
|
+
}
|
|
101
|
+
else if (fs.existsSync(rootEnvPath)) {
|
|
102
|
+
envPath = rootEnvPath;
|
|
103
|
+
}
|
|
104
|
+
if (!envPath)
|
|
54
105
|
return;
|
|
55
106
|
const content = fs.readFileSync(envPath, 'utf8');
|
|
56
107
|
const parsed = parseEnvContent(content);
|
|
@@ -61,7 +112,7 @@ export function loadApiKeysFromEnvLocal() {
|
|
|
61
112
|
}
|
|
62
113
|
}
|
|
63
114
|
catch (err) {
|
|
64
|
-
logger.debug(`Failed to load
|
|
115
|
+
logger.debug(`Failed to load env file: ${err instanceof Error ? err.message : String(err)}`);
|
|
65
116
|
}
|
|
66
117
|
}
|
|
67
118
|
//# sourceMappingURL=env.js.map
|
package/dist/utils/env.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/utils/env.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAAC,OAAe;IAC7C,MAAM,MAAM,GAA2B,EAAE,CAAC;IAE1C,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAE5C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,GAAG,KAAK,CAAC,CAAC;YAAE,SAAS;QAEzB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QACtC,IAAI,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAEvC,oCAAoC;QACpC,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;YACtB,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACvB,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACrC,IAAI,CAAC,KAAK,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;gBACvE,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC;QAED,IAAI,CAAC,GAAG;YAAE,SAAS;QACnB,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACtB,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/utils/env.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAAC,OAAe;IAC7C,MAAM,MAAM,GAA2B,EAAE,CAAC;IAE1C,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAE5C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,GAAG,KAAK,CAAC,CAAC;YAAE,SAAS;QAEzB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QACtC,IAAI,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAEvC,oCAAoC;QACpC,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;YACtB,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACvB,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACrC,IAAI,CAAC,KAAK,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;gBACvE,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC;QAED,IAAI,CAAC,GAAG;YAAE,SAAS;QACnB,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACtB,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAAgB,EAAE,IAA4B;IAC/E,iCAAiC;IACjC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,CAAC;IAED,uCAAuC;IACvC,IAAI,UAAU,GAAG,EAAE,CAAC;IACpB,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,UAAU,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAClD,CAAC;IAED,0BAA0B;IAC1B,MAAM,WAAW,GAAG,CAAC,KAAa,EAAU,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;IAE5F,KAAK,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACnD,IAAI,CAAC,KAAK;YAAE,SAAS,CAAC,oBAAoB;QAE1C,MAAM,QAAQ,GAAG,IAAI,MAAM,CAAC,IAAI,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAChE,IAAI,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;YAC9B,uBAAuB;YACvB,UAAU,GAAG,UAAU,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,MAAM,IAAI,KAAK,EAAE,CAAC,CAAC;QAClE,CAAC;aAAM,CAAC;YACN,iBAAiB;YACjB,UAAU,GAAG,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,GAAG,MAAM,IAAI,KAAK,IAAI,CAAC;QACxF,CAAC;IACH,CAAC;IAED,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;AACzC,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,uBAAuB;IACrC,IAAI,CAAC;QACH,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;QACtE,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,YAAY,CAAC,CAAC;QAE3D,yDAAyD;QACzD,IAAI,OAAO,GAAkB,IAAI,CAAC;QAClC,IAAI,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YAChC,OAAO,GAAG,YAAY,CAAC;QACzB,CAAC;aAAM,IAAI,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YACtC,OAAO,GAAG,WAAW,CAAC;QACxB,CAAC;QAED,IAAI,CAAC,OAAO;YAAE,OAAO;QAErB,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;QAExC,KAAK,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;YACjC,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,SAAS,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC;gBACpD,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;YACjC,CAAC;QACH,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,KAAK,CAAC,4BAA4B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC/F,CAAC;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { handleConfigCommand } from './config.js';
|
|
5
|
+
import type { SessionState } from '../repl/session-state.js';
|
|
6
|
+
|
|
7
|
+
// Mock logger to suppress console output during tests
|
|
8
|
+
vi.mock('../utils/logger.js', () => ({
|
|
9
|
+
logger: {
|
|
10
|
+
error: vi.fn(),
|
|
11
|
+
success: vi.fn(),
|
|
12
|
+
},
|
|
13
|
+
}));
|
|
14
|
+
|
|
15
|
+
// Mock colors to avoid picocolors output during tests
|
|
16
|
+
vi.mock('../utils/colors.js', () => ({
|
|
17
|
+
simpson: {
|
|
18
|
+
yellow: (s: string) => s,
|
|
19
|
+
},
|
|
20
|
+
}));
|
|
21
|
+
|
|
22
|
+
describe('handleConfigCommand - init guard', () => {
|
|
23
|
+
const mockState: SessionState = {
|
|
24
|
+
projectRoot: '/fake/project',
|
|
25
|
+
provider: 'openai',
|
|
26
|
+
model: 'gpt-4',
|
|
27
|
+
conversationHistory: [],
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
beforeEach(() => {
|
|
31
|
+
vi.restoreAllMocks();
|
|
32
|
+
// Clear process.env
|
|
33
|
+
delete process.env.TAVILY_API_KEY;
|
|
34
|
+
delete process.env.CONTEXT7_API_KEY;
|
|
35
|
+
delete process.env.BRAINTRUST_API_KEY;
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('throws error when .ralph/ does not exist', async () => {
|
|
39
|
+
const ralphDir = path.join(mockState.projectRoot, '.ralph');
|
|
40
|
+
|
|
41
|
+
vi.spyOn(fs, 'existsSync').mockImplementation((p) => {
|
|
42
|
+
// .ralph/ directory does not exist
|
|
43
|
+
return p !== ralphDir;
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const writeSpy = vi.spyOn(fs, 'writeFileSync');
|
|
47
|
+
const mkdirSpy = vi.spyOn(fs, 'mkdirSync');
|
|
48
|
+
|
|
49
|
+
const args = ['set', 'tavily', 'tvly-test-key-1234567890'];
|
|
50
|
+
|
|
51
|
+
await handleConfigCommand(args, mockState);
|
|
52
|
+
|
|
53
|
+
// Should not create .ralph/ directory
|
|
54
|
+
expect(mkdirSpy).not.toHaveBeenCalled();
|
|
55
|
+
|
|
56
|
+
// Should not write to .env.local
|
|
57
|
+
expect(writeSpy).not.toHaveBeenCalled();
|
|
58
|
+
|
|
59
|
+
// Should not set environment variable
|
|
60
|
+
expect(process.env.TAVILY_API_KEY).toBeUndefined();
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('writes to .ralph/.env.local when .ralph/ exists', async () => {
|
|
64
|
+
const ralphDir = path.join(mockState.projectRoot, '.ralph');
|
|
65
|
+
const envLocalPath = path.join(ralphDir, '.env.local');
|
|
66
|
+
|
|
67
|
+
vi.spyOn(fs, 'existsSync').mockImplementation((p) => {
|
|
68
|
+
// .ralph/ directory exists
|
|
69
|
+
if (p === ralphDir) return true;
|
|
70
|
+
// .env.local does not exist yet
|
|
71
|
+
if (p === envLocalPath) return false;
|
|
72
|
+
return false;
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
vi.spyOn(fs, 'statSync').mockReturnValue({
|
|
76
|
+
isDirectory: () => true,
|
|
77
|
+
} as any);
|
|
78
|
+
|
|
79
|
+
vi.spyOn(fs, 'readFileSync').mockReturnValue('');
|
|
80
|
+
vi.spyOn(fs, 'mkdirSync').mockReturnValue(undefined);
|
|
81
|
+
const writeSpy = vi.spyOn(fs, 'writeFileSync').mockReturnValue(undefined);
|
|
82
|
+
|
|
83
|
+
const args = ['set', 'tavily', 'tvly-test-key-1234567890'];
|
|
84
|
+
|
|
85
|
+
await handleConfigCommand(args, mockState);
|
|
86
|
+
|
|
87
|
+
// Should write to .ralph/.env.local
|
|
88
|
+
expect(writeSpy).toHaveBeenCalledWith(
|
|
89
|
+
envLocalPath,
|
|
90
|
+
'TAVILY_API_KEY=tvly-test-key-1234567890\n'
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
// Should set environment variable
|
|
94
|
+
expect(process.env.TAVILY_API_KEY).toBe('tvly-test-key-1234567890');
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it('merges new key into existing .ralph/.env.local', async () => {
|
|
98
|
+
const ralphDir = path.join(mockState.projectRoot, '.ralph');
|
|
99
|
+
const envLocalPath = path.join(ralphDir, '.env.local');
|
|
100
|
+
const existingContent = 'CONTEXT7_API_KEY=c7-existing-123\n';
|
|
101
|
+
|
|
102
|
+
vi.spyOn(fs, 'existsSync').mockImplementation((p) => {
|
|
103
|
+
// Both .ralph/ and .env.local exist
|
|
104
|
+
if (p === ralphDir) return true;
|
|
105
|
+
if (p === envLocalPath) return true;
|
|
106
|
+
return false;
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
vi.spyOn(fs, 'statSync').mockReturnValue({
|
|
110
|
+
isDirectory: () => true,
|
|
111
|
+
} as any);
|
|
112
|
+
|
|
113
|
+
vi.spyOn(fs, 'readFileSync').mockReturnValue(existingContent);
|
|
114
|
+
const writeSpy = vi.spyOn(fs, 'writeFileSync').mockReturnValue(undefined);
|
|
115
|
+
|
|
116
|
+
const args = ['set', 'tavily', 'tvly-test-key-1234567890'];
|
|
117
|
+
|
|
118
|
+
await handleConfigCommand(args, mockState);
|
|
119
|
+
|
|
120
|
+
const writtenContent = (writeSpy as any).mock.calls[0][1];
|
|
121
|
+
|
|
122
|
+
// Should preserve existing key
|
|
123
|
+
expect(writtenContent).toContain('CONTEXT7_API_KEY=c7-existing-123');
|
|
124
|
+
|
|
125
|
+
// Should add new key
|
|
126
|
+
expect(writtenContent).toContain('TAVILY_API_KEY=tvly-test-key-1234567890');
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it('replaces existing key value in .ralph/.env.local', async () => {
|
|
130
|
+
const ralphDir = path.join(mockState.projectRoot, '.ralph');
|
|
131
|
+
const envLocalPath = path.join(ralphDir, '.env.local');
|
|
132
|
+
const existingContent = 'TAVILY_API_KEY=old-key-value\n';
|
|
133
|
+
|
|
134
|
+
vi.spyOn(fs, 'existsSync').mockImplementation((p) => {
|
|
135
|
+
if (p === ralphDir) return true;
|
|
136
|
+
if (p === envLocalPath) return true;
|
|
137
|
+
return false;
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
vi.spyOn(fs, 'statSync').mockReturnValue({
|
|
141
|
+
isDirectory: () => true,
|
|
142
|
+
} as any);
|
|
143
|
+
|
|
144
|
+
vi.spyOn(fs, 'readFileSync').mockReturnValue(existingContent);
|
|
145
|
+
const writeSpy = vi.spyOn(fs, 'writeFileSync').mockReturnValue(undefined);
|
|
146
|
+
|
|
147
|
+
const args = ['set', 'tavily', 'tvly-new-key-9876543210'];
|
|
148
|
+
|
|
149
|
+
await handleConfigCommand(args, mockState);
|
|
150
|
+
|
|
151
|
+
const writtenContent = (writeSpy as any).mock.calls[0][1];
|
|
152
|
+
|
|
153
|
+
// Should replace old value
|
|
154
|
+
expect(writtenContent).not.toContain('old-key-value');
|
|
155
|
+
expect(writtenContent).toContain('TAVILY_API_KEY=tvly-new-key-9876543210');
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
it('validates API key length', async () => {
|
|
159
|
+
const ralphDir = path.join(mockState.projectRoot, '.ralph');
|
|
160
|
+
|
|
161
|
+
vi.spyOn(fs, 'existsSync').mockReturnValue(true);
|
|
162
|
+
vi.spyOn(fs, 'statSync').mockReturnValue({
|
|
163
|
+
isDirectory: () => true,
|
|
164
|
+
} as any);
|
|
165
|
+
|
|
166
|
+
const writeSpy = vi.spyOn(fs, 'writeFileSync');
|
|
167
|
+
|
|
168
|
+
// Key too short (< 10 chars)
|
|
169
|
+
const args = ['set', 'tavily', 'short'];
|
|
170
|
+
|
|
171
|
+
await handleConfigCommand(args, mockState);
|
|
172
|
+
|
|
173
|
+
// Should not write
|
|
174
|
+
expect(writeSpy).not.toHaveBeenCalled();
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
it('rejects unknown service names', async () => {
|
|
178
|
+
const ralphDir = path.join(mockState.projectRoot, '.ralph');
|
|
179
|
+
|
|
180
|
+
vi.spyOn(fs, 'existsSync').mockReturnValue(true);
|
|
181
|
+
vi.spyOn(fs, 'statSync').mockReturnValue({
|
|
182
|
+
isDirectory: () => true,
|
|
183
|
+
} as any);
|
|
184
|
+
|
|
185
|
+
const writeSpy = vi.spyOn(fs, 'writeFileSync');
|
|
186
|
+
|
|
187
|
+
const args = ['set', 'unknown-service', 'some-key-1234567890'];
|
|
188
|
+
|
|
189
|
+
await handleConfigCommand(args, mockState);
|
|
190
|
+
|
|
191
|
+
// Should not write
|
|
192
|
+
expect(writeSpy).not.toHaveBeenCalled();
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
it('handles all supported services', async () => {
|
|
196
|
+
const ralphDir = path.join(mockState.projectRoot, '.ralph');
|
|
197
|
+
const envLocalPath = path.join(ralphDir, '.env.local');
|
|
198
|
+
|
|
199
|
+
vi.spyOn(fs, 'existsSync').mockImplementation((p) => {
|
|
200
|
+
if (p === ralphDir) return true;
|
|
201
|
+
if (p === envLocalPath) return false;
|
|
202
|
+
return false;
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
vi.spyOn(fs, 'statSync').mockReturnValue({
|
|
206
|
+
isDirectory: () => true,
|
|
207
|
+
} as any);
|
|
208
|
+
|
|
209
|
+
vi.spyOn(fs, 'readFileSync').mockReturnValue('');
|
|
210
|
+
vi.spyOn(fs, 'mkdirSync').mockReturnValue(undefined);
|
|
211
|
+
const writeSpy = vi.spyOn(fs, 'writeFileSync').mockReturnValue(undefined);
|
|
212
|
+
|
|
213
|
+
// Test tavily
|
|
214
|
+
await handleConfigCommand(['set', 'tavily', 'tvly-key-1234567890'], mockState);
|
|
215
|
+
expect(writeSpy).toHaveBeenLastCalledWith(envLocalPath, 'TAVILY_API_KEY=tvly-key-1234567890\n');
|
|
216
|
+
|
|
217
|
+
// Test context7
|
|
218
|
+
await handleConfigCommand(['set', 'context7', 'c7-key-1234567890'], mockState);
|
|
219
|
+
expect(writeSpy).toHaveBeenLastCalledWith(envLocalPath, 'CONTEXT7_API_KEY=c7-key-1234567890\n');
|
|
220
|
+
|
|
221
|
+
// Test braintrust
|
|
222
|
+
await handleConfigCommand(['set', 'braintrust', 'bt-key-1234567890'], mockState);
|
|
223
|
+
expect(writeSpy).toHaveBeenLastCalledWith(envLocalPath, 'BRAINTRUST_API_KEY=bt-key-1234567890\n');
|
|
224
|
+
});
|
|
225
|
+
});
|
package/src/commands/config.ts
CHANGED
|
@@ -10,6 +10,7 @@ import { logger } from '../utils/logger.js';
|
|
|
10
10
|
import { simpson } from '../utils/colors.js';
|
|
11
11
|
import type { SessionState } from '../repl/session-state.js';
|
|
12
12
|
import { getAvailableProvider, AVAILABLE_MODELS } from '../ai/providers.js';
|
|
13
|
+
import { writeKeysToEnvFile } from '../utils/env.js';
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* Supported services for API key configuration
|
|
@@ -40,27 +41,17 @@ function isServiceConfigured(service: ConfigurableService): boolean {
|
|
|
40
41
|
}
|
|
41
42
|
|
|
42
43
|
/**
|
|
43
|
-
* Save an API key to .env.local file
|
|
44
|
+
* Save an API key to .ralph/.env.local file
|
|
44
45
|
*/
|
|
45
46
|
function saveKeyToEnvLocal(projectRoot: string, envVar: string, value: string): void {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if (fs.existsSync(envLocalPath)) {
|
|
51
|
-
envContent = fs.readFileSync(envLocalPath, 'utf-8');
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const keyRegex = new RegExp(`^${envVar}=.*$`, 'm');
|
|
55
|
-
if (keyRegex.test(envContent)) {
|
|
56
|
-
// Replace existing key
|
|
57
|
-
envContent = envContent.replace(keyRegex, `${envVar}=${value}`);
|
|
58
|
-
} else {
|
|
59
|
-
// Append new key
|
|
60
|
-
envContent = envContent.trimEnd() + (envContent ? '\n' : '') + `${envVar}=${value}\n`;
|
|
47
|
+
// Check that .ralph/ exists (project is initialized)
|
|
48
|
+
const ralphDir = path.join(projectRoot, '.ralph');
|
|
49
|
+
if (!fs.existsSync(ralphDir) || !fs.statSync(ralphDir).isDirectory()) {
|
|
50
|
+
throw new Error('This project is not initialized. Run \'ralph init\' to set up .ralph/ before using \'ralph config set\'.');
|
|
61
51
|
}
|
|
62
52
|
|
|
63
|
-
|
|
53
|
+
const envLocalPath = path.join(ralphDir, '.env.local');
|
|
54
|
+
writeKeysToEnvFile(envLocalPath, { [envVar]: value });
|
|
64
55
|
}
|
|
65
56
|
|
|
66
57
|
/**
|
|
@@ -160,7 +151,7 @@ export async function handleConfigCommand(
|
|
|
160
151
|
// Also set in current process environment
|
|
161
152
|
process.env[envVar] = apiKey;
|
|
162
153
|
|
|
163
|
-
logger.success(`${envVar} saved to .env.local`);
|
|
154
|
+
logger.success(`${envVar} saved to .ralph/.env.local`);
|
|
164
155
|
console.log(pc.dim('Restart Wiggum to apply changes to tool availability.'));
|
|
165
156
|
console.log('');
|
|
166
157
|
} catch (error) {
|
package/src/tui/hooks/useInit.ts
CHANGED
|
@@ -68,7 +68,7 @@ export const INIT_PHASE_CONFIGS: Record<InitPhase, InitPhaseConfig> = {
|
|
|
68
68
|
'key-save': {
|
|
69
69
|
number: 2,
|
|
70
70
|
name: 'Save Key',
|
|
71
|
-
description: 'Save API key to .env.local',
|
|
71
|
+
description: 'Save API key to .ralph/.env.local',
|
|
72
72
|
},
|
|
73
73
|
'model-select': {
|
|
74
74
|
number: 3,
|
|
@@ -36,6 +36,7 @@ import {
|
|
|
36
36
|
import { Generator } from '../../generator/index.js';
|
|
37
37
|
import { loadConfigWithDefaults } from '../../utils/config.js';
|
|
38
38
|
import { initTracing, flushTracing, traced } from '../../utils/tracing.js';
|
|
39
|
+
import { writeKeysToEnvFile } from '../../utils/env.js';
|
|
39
40
|
import fs from 'node:fs';
|
|
40
41
|
import path from 'node:path';
|
|
41
42
|
import type { SessionState } from '../../repl/session-state.js';
|
|
@@ -75,30 +76,6 @@ function getModelOptions(provider: AIProvider): SelectOption<string>[] {
|
|
|
75
76
|
}));
|
|
76
77
|
}
|
|
77
78
|
|
|
78
|
-
/**
|
|
79
|
-
* Save API keys to .env.local file
|
|
80
|
-
*/
|
|
81
|
-
function saveKeysToEnvLocal(projectRoot: string, keys: Record<string, string>): void {
|
|
82
|
-
const envLocalPath = path.join(projectRoot, '.env.local');
|
|
83
|
-
let envContent = '';
|
|
84
|
-
|
|
85
|
-
if (fs.existsSync(envLocalPath)) {
|
|
86
|
-
envContent = fs.readFileSync(envLocalPath, 'utf-8');
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
for (const [envVar, value] of Object.entries(keys)) {
|
|
90
|
-
if (!value) continue;
|
|
91
|
-
|
|
92
|
-
const keyRegex = new RegExp(`^${envVar}=.*$`, 'm');
|
|
93
|
-
if (keyRegex.test(envContent)) {
|
|
94
|
-
envContent = envContent.replace(keyRegex, `${envVar}=${value}`);
|
|
95
|
-
} else {
|
|
96
|
-
envContent = envContent.trimEnd() + (envContent ? '\n' : '') + `${envVar}=${value}\n`;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
fs.writeFileSync(envLocalPath, envContent);
|
|
101
|
-
}
|
|
102
79
|
|
|
103
80
|
/**
|
|
104
81
|
* InitScreen component
|
|
@@ -273,10 +250,11 @@ export function InitScreen({
|
|
|
273
250
|
)
|
|
274
251
|
.map((f: { path: string }) => path.relative(projectRoot, f.path));
|
|
275
252
|
|
|
276
|
-
// Save API key to .env.local if requested
|
|
253
|
+
// Save API key to .ralph/.env.local if requested
|
|
277
254
|
if (state.apiKeyEnteredThisSession && state.saveKeyToEnv && state.provider && apiKeyRef.current) {
|
|
278
255
|
const envVar = getApiKeyEnvVar(state.provider);
|
|
279
|
-
|
|
256
|
+
const envLocalPath = path.join(projectRoot, '.ralph', '.env.local');
|
|
257
|
+
writeKeysToEnvFile(envLocalPath, { [envVar]: apiKeyRef.current });
|
|
280
258
|
}
|
|
281
259
|
|
|
282
260
|
setGenerationComplete(generatedFiles);
|
|
@@ -415,7 +393,7 @@ export function InitScreen({
|
|
|
415
393
|
case 'key-save':
|
|
416
394
|
return (
|
|
417
395
|
<Confirm
|
|
418
|
-
message="Save API key to .env.local?"
|
|
396
|
+
message="Save API key to .ralph/.env.local?"
|
|
419
397
|
onConfirm={handleSaveKeyConfirm}
|
|
420
398
|
onCancel={onCancel}
|
|
421
399
|
initialValue={true}
|
package/src/utils/env.test.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
2
|
import fs from 'fs';
|
|
3
3
|
import path from 'path';
|
|
4
|
-
import { parseEnvContent, loadApiKeysFromEnvLocal } from './env.js';
|
|
4
|
+
import { parseEnvContent, loadApiKeysFromEnvLocal, writeKeysToEnvFile } from './env.js';
|
|
5
5
|
|
|
6
6
|
describe('parseEnvContent', () => {
|
|
7
7
|
it('returns empty object for empty input', () => {
|
|
@@ -94,7 +94,8 @@ describe('loadApiKeysFromEnvLocal', () => {
|
|
|
94
94
|
});
|
|
95
95
|
|
|
96
96
|
it('sets known provider keys from file into process.env', () => {
|
|
97
|
-
|
|
97
|
+
const ralphPath = path.join(process.cwd(), '.ralph', '.env.local');
|
|
98
|
+
vi.spyOn(fs, 'existsSync').mockImplementation((p) => p === ralphPath);
|
|
98
99
|
vi.spyOn(fs, 'readFileSync').mockReturnValue(
|
|
99
100
|
'OPENAI_API_KEY=sk-test-123\nANTHROPIC_API_KEY=sk-ant-456\n'
|
|
100
101
|
);
|
|
@@ -106,8 +107,9 @@ describe('loadApiKeysFromEnvLocal', () => {
|
|
|
106
107
|
});
|
|
107
108
|
|
|
108
109
|
it('overrides existing process.env values (file takes precedence)', () => {
|
|
110
|
+
const ralphPath = path.join(process.cwd(), '.ralph', '.env.local');
|
|
109
111
|
process.env.OPENAI_API_KEY = 'from-shell';
|
|
110
|
-
vi.spyOn(fs, 'existsSync').
|
|
112
|
+
vi.spyOn(fs, 'existsSync').mockImplementation((p) => p === ralphPath);
|
|
111
113
|
vi.spyOn(fs, 'readFileSync').mockReturnValue('OPENAI_API_KEY=from-file\n');
|
|
112
114
|
|
|
113
115
|
loadApiKeysFromEnvLocal();
|
|
@@ -116,7 +118,8 @@ describe('loadApiKeysFromEnvLocal', () => {
|
|
|
116
118
|
});
|
|
117
119
|
|
|
118
120
|
it('ignores unknown keys not in KNOWN_API_KEYS', () => {
|
|
119
|
-
|
|
121
|
+
const ralphPath = path.join(process.cwd(), '.ralph', '.env.local');
|
|
122
|
+
vi.spyOn(fs, 'existsSync').mockImplementation((p) => p === ralphPath);
|
|
120
123
|
vi.spyOn(fs, 'readFileSync').mockReturnValue(
|
|
121
124
|
'OPENAI_API_KEY=sk-test\nSOME_OTHER_KEY=should-not-load\n'
|
|
122
125
|
);
|
|
@@ -127,18 +130,10 @@ describe('loadApiKeysFromEnvLocal', () => {
|
|
|
127
130
|
expect(process.env.SOME_OTHER_KEY).toBeUndefined();
|
|
128
131
|
});
|
|
129
132
|
|
|
130
|
-
it('is a no-op when file does not exist', () => {
|
|
131
|
-
vi.spyOn(fs, 'existsSync').mockReturnValue(false);
|
|
132
|
-
const readSpy = vi.spyOn(fs, 'readFileSync');
|
|
133
|
-
|
|
134
|
-
loadApiKeysFromEnvLocal();
|
|
135
|
-
|
|
136
|
-
expect(readSpy).not.toHaveBeenCalled();
|
|
137
|
-
expect(process.env.OPENAI_API_KEY).toBeUndefined();
|
|
138
|
-
});
|
|
139
133
|
|
|
140
134
|
it('does not throw when file read fails', () => {
|
|
141
|
-
|
|
135
|
+
const ralphPath = path.join(process.cwd(), '.ralph', '.env.local');
|
|
136
|
+
vi.spyOn(fs, 'existsSync').mockImplementation((p) => p === ralphPath);
|
|
142
137
|
vi.spyOn(fs, 'readFileSync').mockImplementation(() => {
|
|
143
138
|
throw new Error('EACCES: permission denied');
|
|
144
139
|
});
|
|
@@ -147,7 +142,8 @@ describe('loadApiKeysFromEnvLocal', () => {
|
|
|
147
142
|
});
|
|
148
143
|
|
|
149
144
|
it('loads optional service keys (TAVILY, CONTEXT7)', () => {
|
|
150
|
-
|
|
145
|
+
const ralphPath = path.join(process.cwd(), '.ralph', '.env.local');
|
|
146
|
+
vi.spyOn(fs, 'existsSync').mockImplementation((p) => p === ralphPath);
|
|
151
147
|
vi.spyOn(fs, 'readFileSync').mockReturnValue(
|
|
152
148
|
'TAVILY_API_KEY=tvly-xxx\nCONTEXT7_API_KEY=c7-yyy\n'
|
|
153
149
|
);
|
|
@@ -158,18 +154,78 @@ describe('loadApiKeysFromEnvLocal', () => {
|
|
|
158
154
|
expect(process.env.CONTEXT7_API_KEY).toBe('c7-yyy');
|
|
159
155
|
});
|
|
160
156
|
|
|
157
|
+
it('prefers .ralph/.env.local over root .env.local when both exist', () => {
|
|
158
|
+
const ralphPath = path.join(process.cwd(), '.ralph', '.env.local');
|
|
159
|
+
const rootPath = path.join(process.cwd(), '.env.local');
|
|
160
|
+
|
|
161
|
+
vi.spyOn(fs, 'existsSync').mockImplementation((p) => {
|
|
162
|
+
// Both files exist
|
|
163
|
+
return p === ralphPath || p === rootPath;
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
vi.spyOn(fs, 'readFileSync').mockImplementation((p) => {
|
|
167
|
+
if (p === ralphPath) {
|
|
168
|
+
return 'OPENAI_API_KEY=from-ralph\n';
|
|
169
|
+
}
|
|
170
|
+
if (p === rootPath) {
|
|
171
|
+
return 'OPENAI_API_KEY=from-root\n';
|
|
172
|
+
}
|
|
173
|
+
return '';
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
loadApiKeysFromEnvLocal();
|
|
177
|
+
|
|
178
|
+
// Should load from .ralph/.env.local, not root
|
|
179
|
+
expect(process.env.OPENAI_API_KEY).toBe('from-ralph');
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
it('falls back to root .env.local when .ralph/.env.local does not exist', () => {
|
|
183
|
+
const ralphPath = path.join(process.cwd(), '.ralph', '.env.local');
|
|
184
|
+
const rootPath = path.join(process.cwd(), '.env.local');
|
|
185
|
+
|
|
186
|
+
vi.spyOn(fs, 'existsSync').mockImplementation((p) => {
|
|
187
|
+
// Only root exists
|
|
188
|
+
return p === rootPath;
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
vi.spyOn(fs, 'readFileSync').mockImplementation((p) => {
|
|
192
|
+
if (p === rootPath) {
|
|
193
|
+
return 'OPENAI_API_KEY=from-root\n';
|
|
194
|
+
}
|
|
195
|
+
return '';
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
loadApiKeysFromEnvLocal();
|
|
199
|
+
|
|
200
|
+
// Should load from root .env.local as fallback
|
|
201
|
+
expect(process.env.OPENAI_API_KEY).toBe('from-root');
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
it('is a no-op when neither .ralph/.env.local nor root .env.local exist', () => {
|
|
205
|
+
vi.spyOn(fs, 'existsSync').mockReturnValue(false);
|
|
206
|
+
const readSpy = vi.spyOn(fs, 'readFileSync');
|
|
207
|
+
|
|
208
|
+
loadApiKeysFromEnvLocal();
|
|
209
|
+
|
|
210
|
+
expect(readSpy).not.toHaveBeenCalled();
|
|
211
|
+
expect(process.env.OPENAI_API_KEY).toBeUndefined();
|
|
212
|
+
});
|
|
213
|
+
|
|
161
214
|
it('resolves path relative to process.cwd()', () => {
|
|
162
215
|
vi.spyOn(fs, 'existsSync').mockReturnValue(false);
|
|
163
216
|
const existsSpy = vi.spyOn(fs, 'existsSync');
|
|
164
217
|
|
|
165
218
|
loadApiKeysFromEnvLocal();
|
|
166
219
|
|
|
167
|
-
const
|
|
168
|
-
|
|
220
|
+
const ralphPath = path.join(process.cwd(), '.ralph', '.env.local');
|
|
221
|
+
const rootPath = path.join(process.cwd(), '.env.local');
|
|
222
|
+
expect(existsSpy).toHaveBeenCalledWith(ralphPath);
|
|
223
|
+
expect(existsSpy).toHaveBeenCalledWith(rootPath);
|
|
169
224
|
});
|
|
170
225
|
|
|
171
226
|
it('loads BRAINTRUST_API_KEY as a known key', () => {
|
|
172
|
-
|
|
227
|
+
const ralphPath = path.join(process.cwd(), '.ralph', '.env.local');
|
|
228
|
+
vi.spyOn(fs, 'existsSync').mockImplementation((p) => p === ralphPath);
|
|
173
229
|
vi.spyOn(fs, 'readFileSync').mockReturnValue(
|
|
174
230
|
'BRAINTRUST_API_KEY=bt-xxx\n'
|
|
175
231
|
);
|
|
@@ -180,8 +236,9 @@ describe('loadApiKeysFromEnvLocal', () => {
|
|
|
180
236
|
});
|
|
181
237
|
|
|
182
238
|
it('does not override existing env with empty value from file', () => {
|
|
239
|
+
const ralphPath = path.join(process.cwd(), '.ralph', '.env.local');
|
|
183
240
|
process.env.OPENAI_API_KEY = 'from-shell';
|
|
184
|
-
vi.spyOn(fs, 'existsSync').
|
|
241
|
+
vi.spyOn(fs, 'existsSync').mockImplementation((p) => p === ralphPath);
|
|
185
242
|
vi.spyOn(fs, 'readFileSync').mockReturnValue('OPENAI_API_KEY=\n');
|
|
186
243
|
|
|
187
244
|
loadApiKeysFromEnvLocal();
|
|
@@ -190,7 +247,8 @@ describe('loadApiKeysFromEnvLocal', () => {
|
|
|
190
247
|
});
|
|
191
248
|
|
|
192
249
|
it('strips quotes from values before setting env', () => {
|
|
193
|
-
|
|
250
|
+
const ralphPath = path.join(process.cwd(), '.ralph', '.env.local');
|
|
251
|
+
vi.spyOn(fs, 'existsSync').mockImplementation((p) => p === ralphPath);
|
|
194
252
|
vi.spyOn(fs, 'readFileSync').mockReturnValue(
|
|
195
253
|
'OPENAI_API_KEY="sk-quoted-123"\n'
|
|
196
254
|
);
|
|
@@ -200,3 +258,145 @@ describe('loadApiKeysFromEnvLocal', () => {
|
|
|
200
258
|
expect(process.env.OPENAI_API_KEY).toBe('sk-quoted-123');
|
|
201
259
|
});
|
|
202
260
|
});
|
|
261
|
+
|
|
262
|
+
describe('writeKeysToEnvFile', () => {
|
|
263
|
+
beforeEach(() => {
|
|
264
|
+
vi.restoreAllMocks();
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
it('creates file when it does not exist', () => {
|
|
268
|
+
const filePath = '/fake/path/.env.local';
|
|
269
|
+
const keys = { OPENAI_API_KEY: 'sk-test-123' };
|
|
270
|
+
|
|
271
|
+
vi.spyOn(fs, 'existsSync').mockReturnValue(false);
|
|
272
|
+
vi.spyOn(fs, 'mkdirSync').mockReturnValue(undefined);
|
|
273
|
+
vi.spyOn(fs, 'writeFileSync').mockReturnValue(undefined);
|
|
274
|
+
|
|
275
|
+
writeKeysToEnvFile(filePath, keys);
|
|
276
|
+
|
|
277
|
+
expect(fs.writeFileSync).toHaveBeenCalledWith(
|
|
278
|
+
filePath,
|
|
279
|
+
'OPENAI_API_KEY=sk-test-123\n'
|
|
280
|
+
);
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
it('merges keys into existing file content (preserves other keys)', () => {
|
|
284
|
+
const filePath = '/fake/path/.env.local';
|
|
285
|
+
const keys = { ANTHROPIC_API_KEY: 'sk-ant-456' };
|
|
286
|
+
const existingContent = 'OPENAI_API_KEY=sk-test-123\nOTHER_KEY=value\n';
|
|
287
|
+
|
|
288
|
+
vi.spyOn(fs, 'existsSync').mockReturnValue(true);
|
|
289
|
+
vi.spyOn(fs, 'readFileSync').mockReturnValue(existingContent);
|
|
290
|
+
vi.spyOn(fs, 'writeFileSync').mockReturnValue(undefined);
|
|
291
|
+
|
|
292
|
+
writeKeysToEnvFile(filePath, keys);
|
|
293
|
+
|
|
294
|
+
const writtenContent = (fs.writeFileSync as any).mock.calls[0][1];
|
|
295
|
+
expect(writtenContent).toContain('OPENAI_API_KEY=sk-test-123');
|
|
296
|
+
expect(writtenContent).toContain('OTHER_KEY=value');
|
|
297
|
+
expect(writtenContent).toContain('ANTHROPIC_API_KEY=sk-ant-456');
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
it('replaces existing key value', () => {
|
|
301
|
+
const filePath = '/fake/path/.env.local';
|
|
302
|
+
const keys = { OPENAI_API_KEY: 'sk-new-value' };
|
|
303
|
+
const existingContent = 'OPENAI_API_KEY=sk-old-value\nOTHER_KEY=value\n';
|
|
304
|
+
|
|
305
|
+
vi.spyOn(fs, 'existsSync').mockReturnValue(true);
|
|
306
|
+
vi.spyOn(fs, 'readFileSync').mockReturnValue(existingContent);
|
|
307
|
+
vi.spyOn(fs, 'writeFileSync').mockReturnValue(undefined);
|
|
308
|
+
|
|
309
|
+
writeKeysToEnvFile(filePath, keys);
|
|
310
|
+
|
|
311
|
+
const writtenContent = (fs.writeFileSync as any).mock.calls[0][1];
|
|
312
|
+
expect(writtenContent).toContain('OPENAI_API_KEY=sk-new-value');
|
|
313
|
+
expect(writtenContent).not.toContain('sk-old-value');
|
|
314
|
+
expect(writtenContent).toContain('OTHER_KEY=value');
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
it('handles empty keys object (no-op)', () => {
|
|
318
|
+
const filePath = '/fake/path/.env.local';
|
|
319
|
+
const keys = {};
|
|
320
|
+
const existingContent = 'OPENAI_API_KEY=sk-test-123\n';
|
|
321
|
+
|
|
322
|
+
vi.spyOn(fs, 'existsSync').mockReturnValue(true);
|
|
323
|
+
vi.spyOn(fs, 'readFileSync').mockReturnValue(existingContent);
|
|
324
|
+
vi.spyOn(fs, 'writeFileSync').mockReturnValue(undefined);
|
|
325
|
+
|
|
326
|
+
writeKeysToEnvFile(filePath, keys);
|
|
327
|
+
|
|
328
|
+
expect(fs.writeFileSync).toHaveBeenCalledWith(
|
|
329
|
+
filePath,
|
|
330
|
+
existingContent
|
|
331
|
+
);
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
it('skips keys with empty string values', () => {
|
|
335
|
+
const filePath = '/fake/path/.env.local';
|
|
336
|
+
const keys = { OPENAI_API_KEY: '', ANTHROPIC_API_KEY: 'sk-ant-456' };
|
|
337
|
+
|
|
338
|
+
vi.spyOn(fs, 'existsSync').mockReturnValue(false);
|
|
339
|
+
vi.spyOn(fs, 'mkdirSync').mockReturnValue(undefined);
|
|
340
|
+
vi.spyOn(fs, 'writeFileSync').mockReturnValue(undefined);
|
|
341
|
+
|
|
342
|
+
writeKeysToEnvFile(filePath, keys);
|
|
343
|
+
|
|
344
|
+
const writtenContent = (fs.writeFileSync as any).mock.calls[0][1];
|
|
345
|
+
expect(writtenContent).not.toContain('OPENAI_API_KEY');
|
|
346
|
+
expect(writtenContent).toContain('ANTHROPIC_API_KEY=sk-ant-456');
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
it('creates parent directory if it does not exist', () => {
|
|
350
|
+
const filePath = '/fake/path/to/.env.local';
|
|
351
|
+
const keys = { OPENAI_API_KEY: 'sk-test-123' };
|
|
352
|
+
|
|
353
|
+
vi.spyOn(fs, 'existsSync').mockImplementation((p) => {
|
|
354
|
+
if (p === '/fake/path/to') return false;
|
|
355
|
+
return false;
|
|
356
|
+
});
|
|
357
|
+
vi.spyOn(fs, 'mkdirSync').mockReturnValue(undefined);
|
|
358
|
+
vi.spyOn(fs, 'writeFileSync').mockReturnValue(undefined);
|
|
359
|
+
|
|
360
|
+
writeKeysToEnvFile(filePath, keys);
|
|
361
|
+
|
|
362
|
+
expect(fs.mkdirSync).toHaveBeenCalledWith('/fake/path/to', { recursive: true });
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
it('handles multiple keys at once', () => {
|
|
366
|
+
const filePath = '/fake/path/.env.local';
|
|
367
|
+
const keys = {
|
|
368
|
+
OPENAI_API_KEY: 'sk-test-123',
|
|
369
|
+
ANTHROPIC_API_KEY: 'sk-ant-456',
|
|
370
|
+
TAVILY_API_KEY: 'tvly-789',
|
|
371
|
+
};
|
|
372
|
+
|
|
373
|
+
vi.spyOn(fs, 'existsSync').mockReturnValue(false);
|
|
374
|
+
vi.spyOn(fs, 'mkdirSync').mockReturnValue(undefined);
|
|
375
|
+
vi.spyOn(fs, 'writeFileSync').mockReturnValue(undefined);
|
|
376
|
+
|
|
377
|
+
writeKeysToEnvFile(filePath, keys);
|
|
378
|
+
|
|
379
|
+
const writtenContent = (fs.writeFileSync as any).mock.calls[0][1];
|
|
380
|
+
expect(writtenContent).toContain('OPENAI_API_KEY=sk-test-123');
|
|
381
|
+
expect(writtenContent).toContain('ANTHROPIC_API_KEY=sk-ant-456');
|
|
382
|
+
expect(writtenContent).toContain('TAVILY_API_KEY=tvly-789');
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
it('preserves formatting when replacing keys', () => {
|
|
386
|
+
const filePath = '/fake/path/.env.local';
|
|
387
|
+
const keys = { OPENAI_API_KEY: 'sk-new-value' };
|
|
388
|
+
const existingContent = '# Comment\nOPENAI_API_KEY=sk-old-value\n# Another comment\nOTHER_KEY=value\n';
|
|
389
|
+
|
|
390
|
+
vi.spyOn(fs, 'existsSync').mockReturnValue(true);
|
|
391
|
+
vi.spyOn(fs, 'readFileSync').mockReturnValue(existingContent);
|
|
392
|
+
vi.spyOn(fs, 'writeFileSync').mockReturnValue(undefined);
|
|
393
|
+
|
|
394
|
+
writeKeysToEnvFile(filePath, keys);
|
|
395
|
+
|
|
396
|
+
const writtenContent = (fs.writeFileSync as any).mock.calls[0][1];
|
|
397
|
+
expect(writtenContent).toContain('# Comment');
|
|
398
|
+
expect(writtenContent).toContain('# Another comment');
|
|
399
|
+
expect(writtenContent).toContain('OPENAI_API_KEY=sk-new-value');
|
|
400
|
+
expect(writtenContent).toContain('OTHER_KEY=value');
|
|
401
|
+
});
|
|
402
|
+
});
|
package/src/utils/env.ts
CHANGED
|
@@ -45,18 +45,74 @@ export function parseEnvContent(content: string): Record<string, string> {
|
|
|
45
45
|
return result;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
/**
|
|
49
|
+
* Write API keys to an env file, preserving existing content.
|
|
50
|
+
*
|
|
51
|
+
* - Merges keys into existing file content (preserves other keys).
|
|
52
|
+
* - Replaces existing key values if the key already exists.
|
|
53
|
+
* - Creates parent directories if they don't exist.
|
|
54
|
+
* - Creates the file if it doesn't exist.
|
|
55
|
+
* - Skips empty values (keys with empty strings are ignored).
|
|
56
|
+
*
|
|
57
|
+
* @param filePath - Absolute path to the .env.local file
|
|
58
|
+
* @param keys - Record of environment variable names to values
|
|
59
|
+
*/
|
|
60
|
+
export function writeKeysToEnvFile(filePath: string, keys: Record<string, string>): void {
|
|
61
|
+
// Ensure parent directory exists
|
|
62
|
+
const dir = path.dirname(filePath);
|
|
63
|
+
if (!fs.existsSync(dir)) {
|
|
64
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Read existing content if file exists
|
|
68
|
+
let envContent = '';
|
|
69
|
+
if (fs.existsSync(filePath)) {
|
|
70
|
+
envContent = fs.readFileSync(filePath, 'utf-8');
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Merge keys into content
|
|
74
|
+
const escapeRegex = (value: string): string => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
75
|
+
|
|
76
|
+
for (const [envVar, value] of Object.entries(keys)) {
|
|
77
|
+
if (!value) continue; // Skip empty values
|
|
78
|
+
|
|
79
|
+
const keyRegex = new RegExp(`^${escapeRegex(envVar)}=.*$`, 'm');
|
|
80
|
+
if (keyRegex.test(envContent)) {
|
|
81
|
+
// Replace existing key
|
|
82
|
+
envContent = envContent.replace(keyRegex, `${envVar}=${value}`);
|
|
83
|
+
} else {
|
|
84
|
+
// Append new key
|
|
85
|
+
envContent = envContent.trimEnd() + (envContent ? '\n' : '') + `${envVar}=${value}\n`;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
fs.writeFileSync(filePath, envContent);
|
|
90
|
+
}
|
|
91
|
+
|
|
48
92
|
/**
|
|
49
93
|
* Load known AI provider API keys from .ralph/.env.local into process.env.
|
|
50
94
|
*
|
|
95
|
+
* - Prefers .ralph/.env.local as the canonical source (if it exists).
|
|
96
|
+
* - Falls back to root .env.local if .ralph/.env.local does not exist (backward compatibility).
|
|
51
97
|
* - Only keys in KNOWN_API_KEYS are loaded; all others are ignored.
|
|
52
98
|
* - File values override existing process.env values (file takes precedence).
|
|
53
|
-
* - If
|
|
99
|
+
* - If neither file exists or cannot be read, this is a silent no-op.
|
|
54
100
|
* - Malformed lines are skipped without aborting.
|
|
55
101
|
*/
|
|
56
102
|
export function loadApiKeysFromEnvLocal(): void {
|
|
57
103
|
try {
|
|
58
|
-
const
|
|
59
|
-
|
|
104
|
+
const ralphEnvPath = path.join(process.cwd(), '.ralph', '.env.local');
|
|
105
|
+
const rootEnvPath = path.join(process.cwd(), '.env.local');
|
|
106
|
+
|
|
107
|
+
// Prefer .ralph/.env.local, fall back to root .env.local
|
|
108
|
+
let envPath: string | null = null;
|
|
109
|
+
if (fs.existsSync(ralphEnvPath)) {
|
|
110
|
+
envPath = ralphEnvPath;
|
|
111
|
+
} else if (fs.existsSync(rootEnvPath)) {
|
|
112
|
+
envPath = rootEnvPath;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (!envPath) return;
|
|
60
116
|
|
|
61
117
|
const content = fs.readFileSync(envPath, 'utf8');
|
|
62
118
|
const parsed = parseEnvContent(content);
|
|
@@ -67,6 +123,6 @@ export function loadApiKeysFromEnvLocal(): void {
|
|
|
67
123
|
}
|
|
68
124
|
}
|
|
69
125
|
} catch (err) {
|
|
70
|
-
logger.debug(`Failed to load
|
|
126
|
+
logger.debug(`Failed to load env file: ${err instanceof Error ? err.message : String(err)}`);
|
|
71
127
|
}
|
|
72
128
|
}
|