@iservu-inc/adf-cli 0.5.5-debug.0 → 0.5.6

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/CHANGELOG.md CHANGED
@@ -5,6 +5,103 @@ All notable changes to `@iservu-inc/adf-cli` will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.5.6] - 2025-10-05
9
+
10
+ ### 🔧 Fixed Invalid .env State Detection
11
+
12
+ **FIX:** Automatically detect and reset invalid configuration where ADF_CURRENT_PROVIDER/ADF_CURRENT_MODEL are set but no API key exists.
13
+
14
+ #### The Problem (Cart Before the Horse)
15
+
16
+ The .env file could end up in an invalid state:
17
+ ```env
18
+ ADF_CURRENT_PROVIDER="openrouter"
19
+ ADF_CURRENT_MODEL="anthropic/claude-sonnet-4-5"
20
+ # But no OPENROUTER_API_KEY present!
21
+ ```
22
+
23
+ This shouldn't be possible - you can't have a "current provider" without an API key for that provider.
24
+
25
+ #### The Fix
26
+
27
+ Now we detect this broken state and automatically reset:
28
+ ```
29
+ ⚠️ Invalid configuration detected:
30
+ ADF_CURRENT_PROVIDER is set to "openrouter" but no API key found
31
+ Resetting provider selection...
32
+ ```
33
+
34
+ The invalid ADF_CURRENT_PROVIDER and ADF_CURRENT_MODEL entries are removed from .env, forcing proper configuration.
35
+
36
+ #### Why This Matters
37
+
38
+ - **Data integrity**: Prevents cart-before-horse situations
39
+ - **Better UX**: Clear feedback about what's wrong
40
+ - **Auto-healing**: Automatically fixes the broken state
41
+ - **Prevents confusion**: Users aren't told they have an active provider when they don't
42
+
43
+ #### How It Can Happen
44
+
45
+ - User manually edited/deleted API key from .env
46
+ - Corrupted .env file
47
+ - Configuration error during setup
48
+
49
+ Now these scenarios are automatically detected and corrected!
50
+
51
+ #### Technical Changes
52
+
53
+ - Modified: `lib/ai/ai-config.js`
54
+ - Added validation after loading .env
55
+ - New `saveEnvFile()` helper function
56
+ - Refactored `saveToEnvFile()` to use `saveEnvFile()`
57
+ - Auto-reset invalid configuration
58
+
59
+ ---
60
+
61
+ ## [0.5.5] - 2025-10-05
62
+
63
+ ### ✅ Fixed AI Provider Configuration Display
64
+
65
+ **FIX:** Restored checkmarks (✓) for configured AI providers alongside the active (★) indicator.
66
+
67
+ #### What Was Broken
68
+
69
+ In the AI provider selection menu, only the "★ Active" indicator was showing. The checkmarks that indicate which providers have configured API keys were missing.
70
+
71
+ **Before (broken):**
72
+ ```
73
+ ? Select AI provider:
74
+ Anthropic Claude
75
+ OpenAI GPT
76
+ Google Gemini
77
+ OpenRouter (Multi-Model) ★ Active
78
+ ```
79
+
80
+ **After (fixed):**
81
+ ```
82
+ ? Select AI provider:
83
+ Anthropic Claude ✓
84
+ OpenAI GPT ✓
85
+ Google Gemini ✓
86
+ OpenRouter (Multi-Model) ✓ ★ Active
87
+ ```
88
+
89
+ #### What We Fixed
90
+
91
+ - Refactored provider name building logic for clarity
92
+ - Added proper spacing between provider name, checkmark, and active indicator
93
+ - Both indicators now show correctly:
94
+ - **✓** = API key configured
95
+ - **★ Active** = Currently selected provider
96
+
97
+ #### Technical Changes
98
+
99
+ - Modified: `lib/ai/ai-config.js` - Cleaner `buildProviderName()` function
100
+ - Better string concatenation with consistent spacing
101
+ - Removed debug logging
102
+
103
+ ---
104
+
8
105
  ## [0.5.4] - 2025-10-05
9
106
 
10
107
  ### ✨ Enhanced Version & Help Display
@@ -136,12 +136,9 @@ async function ensureGitignore(projectPath) {
136
136
  }
137
137
 
138
138
  /**
139
- * Save API key to .env file
139
+ * Save entire env object to .env file
140
140
  */
141
- async function saveToEnvFile(envPath, key, value) {
142
- const env = await loadEnvFile(envPath);
143
- env[key] = value;
144
-
141
+ async function saveEnvFile(envPath, env) {
145
142
  const lines = [
146
143
  '# AI Provider Configuration for adf-cli',
147
144
  '# DO NOT commit this file to version control',
@@ -179,6 +176,15 @@ async function saveToEnvFile(envPath, key, value) {
179
176
  await ensureGitignore(projectPath);
180
177
  }
181
178
 
179
+ /**
180
+ * Save API key to .env file
181
+ */
182
+ async function saveToEnvFile(envPath, key, value) {
183
+ const env = await loadEnvFile(envPath);
184
+ env[key] = value;
185
+ await saveEnvFile(envPath, env);
186
+ }
187
+
182
188
  /**
183
189
  * Load .env file into process.env
184
190
  */
@@ -275,15 +281,33 @@ async function configureAIProvider(projectPath = process.cwd()) {
275
281
  const apiKey = process.env[provider.envVar] || existingEnv[provider.envVar];
276
282
  if (apiKey) {
277
283
  availableProviders.push(provider);
278
- console.log(chalk.gray(`[DEBUG] Found ${provider.id}: ${provider.envVar}=${apiKey ? '***' : 'not found'}`));
279
284
  }
280
285
  }
281
- console.log(chalk.gray(`[DEBUG] availableProviders length: ${availableProviders.length}`));
282
- console.log(chalk.gray(`[DEBUG] availableProviders ids: ${availableProviders.map(p => p.id).join(', ')}`));
283
286
 
284
287
  // Get currently active provider and model
285
- const currentProvider = process.env.ADF_CURRENT_PROVIDER || existingEnv.ADF_CURRENT_PROVIDER;
286
- const currentModel = process.env.ADF_CURRENT_MODEL || existingEnv.ADF_CURRENT_MODEL;
288
+ let currentProvider = process.env.ADF_CURRENT_PROVIDER || existingEnv.ADF_CURRENT_PROVIDER;
289
+ let currentModel = process.env.ADF_CURRENT_MODEL || existingEnv.ADF_CURRENT_MODEL;
290
+
291
+ // Validate: If ADF_CURRENT_PROVIDER is set but its API key is missing, reset it
292
+ if (currentProvider) {
293
+ const currentProviderObj = AI_PROVIDERS[currentProvider.toUpperCase()];
294
+ if (currentProviderObj) {
295
+ const currentProviderHasKey = availableProviders.find(p => p.id === currentProvider);
296
+ if (!currentProviderHasKey) {
297
+ console.log(chalk.yellow(`⚠️ Invalid configuration detected:`));
298
+ console.log(chalk.gray(` ADF_CURRENT_PROVIDER is set to "${currentProvider}" but no API key found`));
299
+ console.log(chalk.gray(` Resetting provider selection...\n`));
300
+
301
+ // Clear invalid values from .env file
302
+ delete existingEnv.ADF_CURRENT_PROVIDER;
303
+ delete existingEnv.ADF_CURRENT_MODEL;
304
+ await saveEnvFile(envPath, existingEnv);
305
+
306
+ currentProvider = null;
307
+ currentModel = null;
308
+ }
309
+ }
310
+ }
287
311
 
288
312
  if (availableProviders.length > 0) {
289
313
  console.log(chalk.green('✓ Detected API keys for:'));
@@ -293,7 +317,7 @@ async function configureAIProvider(projectPath = process.cwd()) {
293
317
  console.log('');
294
318
  }
295
319
 
296
- // Show current active configuration if exists
320
+ // Show current active configuration if exists (and is valid)
297
321
  if (currentProvider && currentModel) {
298
322
  const currentProviderObj = AI_PROVIDERS[currentProvider.toUpperCase()];
299
323
  if (currentProviderObj) {
@@ -301,25 +325,40 @@ async function configureAIProvider(projectPath = process.cwd()) {
301
325
  }
302
326
  }
303
327
 
304
- // Provider selection
328
+ // Provider selection with status indicators
329
+ const buildProviderName = (provider, providerId) => {
330
+ const isConfigured = availableProviders.find(p => p.id === providerId);
331
+ const isActive = currentProvider === providerId;
332
+
333
+ let name = provider.name;
334
+ if (isConfigured) {
335
+ name += chalk.green(' ✓');
336
+ }
337
+ if (isActive) {
338
+ name += chalk.cyan(' ★ Active');
339
+ }
340
+
341
+ return name;
342
+ };
343
+
305
344
  const providerChoices = [
306
345
  {
307
- name: `${AI_PROVIDERS.ANTHROPIC.name} ${availableProviders.find(p => p.id === 'anthropic') ? chalk.green('✓ Configured') : ''} ${currentProvider === 'anthropic' ? chalk.cyan('★ Active') : ''}`,
346
+ name: buildProviderName(AI_PROVIDERS.ANTHROPIC, 'anthropic'),
308
347
  value: 'anthropic',
309
348
  short: 'Anthropic'
310
349
  },
311
350
  {
312
- name: `${AI_PROVIDERS.OPENAI.name} ${availableProviders.find(p => p.id === 'openai') ? chalk.green('✓ Configured') : ''} ${currentProvider === 'openai' ? chalk.cyan('★ Active') : ''}`,
351
+ name: buildProviderName(AI_PROVIDERS.OPENAI, 'openai'),
313
352
  value: 'openai',
314
353
  short: 'OpenAI'
315
354
  },
316
355
  {
317
- name: `${AI_PROVIDERS.GOOGLE.name} ${availableProviders.find(p => p.id === 'google') ? chalk.green('✓ Configured') : ''} ${currentProvider === 'google' ? chalk.cyan('★ Active') : ''}`,
356
+ name: buildProviderName(AI_PROVIDERS.GOOGLE, 'google'),
318
357
  value: 'google',
319
358
  short: 'Google'
320
359
  },
321
360
  {
322
- name: `${AI_PROVIDERS.OPENROUTER.name} ${availableProviders.find(p => p.id === 'openrouter') ? chalk.green('✓ Configured') : ''} ${currentProvider === 'openrouter' ? chalk.cyan('★ Active') : ''}`,
361
+ name: buildProviderName(AI_PROVIDERS.OPENROUTER, 'openrouter'),
323
362
  value: 'openrouter',
324
363
  short: 'OpenRouter'
325
364
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iservu-inc/adf-cli",
3
- "version": "0.5.5-debug.0",
3
+ "version": "0.5.6",
4
4
  "description": "CLI tool for AgentDevFramework - AI-assisted development framework with multi-provider AI support",
5
5
  "main": "index.js",
6
6
  "bin": {