@iservu-inc/adf-cli 0.4.13 ā 0.4.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/CHANGELOG.md +26 -0
- package/lib/frameworks/interviewer.js +67 -14
- package/lib/frameworks/session-manager.js +5 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,32 @@ 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.4.14] - 2025-10-04
|
|
9
|
+
|
|
10
|
+
### š Critical Bug Fixes
|
|
11
|
+
|
|
12
|
+
**Fixed: False .adf Directory Detection (Issue #1)**
|
|
13
|
+
- **Problem:** `adf init` in empty projects incorrectly detected `.adf` directory and asked to overwrite
|
|
14
|
+
- **Root Cause:** `SessionManager.listSessions()` was creating `.adf/sessions/` directory during resume check
|
|
15
|
+
- **Fix:** Modified `listSessions()` to return empty array if directory doesn't exist instead of creating it
|
|
16
|
+
- **Impact:** Clean projects no longer show false "overwrite" prompts
|
|
17
|
+
|
|
18
|
+
**Fixed: Skip AI Config if Already Configured (Issue #2)**
|
|
19
|
+
- **Problem:** Users who configured AI via `adf config` were still prompted during `adf init`
|
|
20
|
+
- **Solution:** Interview now detects existing `.adf/.env` configuration
|
|
21
|
+
- **Behavior:**
|
|
22
|
+
- **If configured:** Shows "ā AI Provider already configured: [Provider Name]" and uses existing config
|
|
23
|
+
- **If not configured:** Shows "š Block 1: AI Configuration" with prompt to configure
|
|
24
|
+
- **Impact:** Better UX - respects user's configuration choices
|
|
25
|
+
|
|
26
|
+
**Technical Details:**
|
|
27
|
+
- `session-manager.js`: Added existence check before creating directory
|
|
28
|
+
- `interviewer.js`: Added AI config detection logic
|
|
29
|
+
- Checks for existing API keys in `.adf/.env`
|
|
30
|
+
- Auto-loads first available provider (Anthropic > OpenAI > Google > OpenRouter)
|
|
31
|
+
- Shows helpful reminder about `adf config` for managing providers
|
|
32
|
+
- All 120 tests passing
|
|
33
|
+
|
|
8
34
|
## [0.4.13] - 2025-10-04
|
|
9
35
|
|
|
10
36
|
### š Bug Fixes & UX Improvements
|
|
@@ -63,24 +63,55 @@ class Interviewer {
|
|
|
63
63
|
|
|
64
64
|
// Configure AI if not already configured (new sessions only)
|
|
65
65
|
if (!this.aiConfig && !this.isResuming) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
// Check if user already configured AI via 'adf config'
|
|
67
|
+
const { getEnvFilePath, loadEnvFile, loadEnvIntoProcess } = require('../ai/ai-config');
|
|
68
|
+
const envPath = getEnvFilePath(this.projectPath);
|
|
69
|
+
|
|
70
|
+
if (await fs.pathExists(envPath)) {
|
|
71
|
+
const envVars = await loadEnvFile(envPath);
|
|
72
|
+
|
|
73
|
+
// Check which provider is configured
|
|
74
|
+
const providerMap = {
|
|
75
|
+
'ANTHROPIC_API_KEY': { id: 'anthropic', name: 'Anthropic Claude', models: ['claude-sonnet-4-5-20250929', 'claude-3-5-sonnet-20241022'] },
|
|
76
|
+
'OPENAI_API_KEY': { id: 'openai', name: 'OpenAI GPT', models: ['gpt-4-turbo', 'gpt-4o', 'gpt-4'] },
|
|
77
|
+
'GOOGLE_API_KEY': { id: 'google', name: 'Google Gemini', models: ['gemini-2.0-flash-exp', 'gemini-1.5-pro'] },
|
|
78
|
+
'OPENROUTER_API_KEY': { id: 'openrouter', name: 'OpenRouter', models: ['anthropic/claude-sonnet-4-5', 'openai/gpt-4-turbo'] }
|
|
79
|
+
};
|
|
69
80
|
|
|
70
|
-
|
|
71
|
-
{
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
81
|
+
let configuredProvider = null;
|
|
82
|
+
for (const [envVar, provider] of Object.entries(providerMap)) {
|
|
83
|
+
if (envVars[envVar] && envVars[envVar].length > 0) {
|
|
84
|
+
configuredProvider = { ...provider, envVar, apiKey: envVars[envVar] };
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
76
87
|
}
|
|
77
|
-
]);
|
|
78
88
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
89
|
+
if (configuredProvider) {
|
|
90
|
+
// User already configured AI via 'adf config' - just show reminder and use it
|
|
91
|
+
console.log(chalk.cyan.bold('ā'.repeat(60)));
|
|
92
|
+
console.log(chalk.green(`\nā AI Provider already configured: ${configuredProvider.name}`));
|
|
93
|
+
console.log(chalk.gray(' (configured via: adf config)\n'));
|
|
94
|
+
console.log(chalk.gray('š” To manage AI providers: adf config\n'));
|
|
95
|
+
|
|
96
|
+
// Load env into process
|
|
97
|
+
loadEnvIntoProcess(envPath);
|
|
98
|
+
|
|
99
|
+
// Create config object for this session
|
|
100
|
+
this.aiConfig = {
|
|
101
|
+
provider: configuredProvider.id,
|
|
102
|
+
providerName: configuredProvider.name,
|
|
103
|
+
model: configuredProvider.models[0], // Use first available model
|
|
104
|
+
apiKey: configuredProvider.apiKey,
|
|
105
|
+
envVar: configuredProvider.envVar,
|
|
106
|
+
envPath
|
|
107
|
+
};
|
|
108
|
+
} else {
|
|
109
|
+
// .env exists but no AI keys - prompt to configure
|
|
110
|
+
await this.promptAIConfiguration();
|
|
111
|
+
}
|
|
82
112
|
} else {
|
|
83
|
-
|
|
113
|
+
// No .env file - prompt to configure
|
|
114
|
+
await this.promptAIConfiguration();
|
|
84
115
|
}
|
|
85
116
|
}
|
|
86
117
|
|
|
@@ -329,6 +360,28 @@ class Interviewer {
|
|
|
329
360
|
return this.sessionPath;
|
|
330
361
|
}
|
|
331
362
|
|
|
363
|
+
async promptAIConfiguration() {
|
|
364
|
+
console.log(chalk.cyan.bold('ā'.repeat(60)));
|
|
365
|
+
console.log(chalk.cyan.bold('\nš Block 1: AI Configuration\n'));
|
|
366
|
+
console.log(chalk.gray('Configure your AI provider for intelligent follow-up questions\n'));
|
|
367
|
+
|
|
368
|
+
const { configureAI } = await inquirer.prompt([
|
|
369
|
+
{
|
|
370
|
+
type: 'confirm',
|
|
371
|
+
name: 'configureAI',
|
|
372
|
+
message: 'Configure AI provider now? (Recommended for best experience)',
|
|
373
|
+
default: true
|
|
374
|
+
}
|
|
375
|
+
]);
|
|
376
|
+
|
|
377
|
+
if (configureAI) {
|
|
378
|
+
const { configureAIProvider } = require('../ai/ai-config');
|
|
379
|
+
this.aiConfig = await configureAIProvider(this.projectPath);
|
|
380
|
+
} else {
|
|
381
|
+
console.log(chalk.yellow('\nš” You can configure AI later with: adf config\n'));
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
332
385
|
getFrameworkName() {
|
|
333
386
|
const names = {
|
|
334
387
|
rapid: 'Product Requirement Prompt (PRP)',
|
|
@@ -15,9 +15,12 @@ class SessionManager {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
async listSessions() {
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
// Don't create directory if it doesn't exist - just return empty array
|
|
19
|
+
if (!await fs.pathExists(this.sessionsDir)) {
|
|
20
|
+
return [];
|
|
21
|
+
}
|
|
20
22
|
|
|
23
|
+
const sessions = await fs.readdir(this.sessionsDir);
|
|
21
24
|
const sessionDetails = [];
|
|
22
25
|
|
|
23
26
|
for (const sessionId of sessions) {
|