@iservu-inc/adf-cli 0.14.0 ā 0.14.1
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 +10 -0
- package/README.md +12 -2
- package/lib/commands/init.js +94 -0
- package/lib/frameworks/interviewer.js +4 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,16 @@ 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.14.1] - 2026-01-12
|
|
9
|
+
|
|
10
|
+
### š Integration - Project Context Synthesis in core CLI
|
|
11
|
+
|
|
12
|
+
**Patch Release:** Integrated the Synthesis Engine and Adaptive Augmentation flow directly into the `adf init` command.
|
|
13
|
+
|
|
14
|
+
#### Fixed/Integrated
|
|
15
|
+
- š§ **Core CLI Integration** - The `adf init` command now automatically detects existing BMAD, OpenSpec, and Spec-Kit frameworks and offers a "Synthesize & Augment" path.
|
|
16
|
+
- š§ **Dependency Fix** - Ensured all new analysis utilities are correctly required in the command entry point.
|
|
17
|
+
|
|
8
18
|
## [0.14.0] - 2026-01-12
|
|
9
19
|
|
|
10
20
|
### š Major Feature - Project Context Synthesis & Adaptive Augmentation
|
package/README.md
CHANGED
|
@@ -501,8 +501,18 @@ When we release updates to the framework:
|
|
|
501
501
|
|
|
502
502
|
See [CHANGELOG.md](./CHANGELOG.md) for detailed version history.
|
|
503
503
|
|
|
504
|
-
**Latest:** v0.
|
|
505
|
-
- **
|
|
504
|
+
**Latest:** v0.14.0 (2026-01-12)
|
|
505
|
+
- **Project Context Synthesis & Extended Tool Support (v0.14.0)** - Minor release
|
|
506
|
+
- ⨠**Adaptive Project Augmentation** - Synthesizes existing .adf, BMAD, OpenSpec, and Spec-Kit project files into unified context.
|
|
507
|
+
- ⨠**AI-Driven Gap Analysis** - Automatically identifies knowledge gaps and generates targeted questionnaire to fill them.
|
|
508
|
+
- ⨠**Extended Tool Support** - Native generators for Kiro, Trae, and Codex CLI.
|
|
509
|
+
- ⨠**Tool Audit Registry** - New `adf tools audit` command to monitor integration features across all 12+ supported tools.
|
|
510
|
+
|
|
511
|
+
**Previous Releases:**
|
|
512
|
+
- **v0.13.0 (2026-01-03)** - OpenCode Multi-Agent Integration
|
|
513
|
+
- Complete OpenCode generator rewrite with multi-provider, multi-agent support.
|
|
514
|
+
- Optimal model assignment and MCP server integration.
|
|
515
|
+
- **v0.12.10 (2025-12-23)** - Critical Bug Fixes (v0.12.10) - Patch release
|
|
506
516
|
- Fixed EISDIR deployment error for directory-based tools
|
|
507
517
|
- Improved rate limit error detection for Gemini models
|
|
508
518
|
- Added free tier model recommendations for Google Gemini
|
package/lib/commands/init.js
CHANGED
|
@@ -7,6 +7,12 @@ const {
|
|
|
7
7
|
detectProjectType,
|
|
8
8
|
getWorkflowRecommendation
|
|
9
9
|
} = require('../utils/project-detector');
|
|
10
|
+
const FrameworkDetector = require('../utils/framework-detector');
|
|
11
|
+
const ContextExtractor = require('../utils/context-extractor');
|
|
12
|
+
const SynthesisEngine = require('../analysis/synthesis-engine');
|
|
13
|
+
const HeuristicGapAnalyzer = require('../analysis/heuristic-gap-analyzer');
|
|
14
|
+
const AIGapAnalyzer = require('../analysis/ai-gap-analyzer');
|
|
15
|
+
const DynamicQuestionGenerator = require('../analysis/dynamic-question-generator');
|
|
10
16
|
const Interviewer = require('../frameworks/interviewer');
|
|
11
17
|
const SessionManager = require('../frameworks/session-manager');
|
|
12
18
|
const { deployToTool } = require('./deploy');
|
|
@@ -24,6 +30,94 @@ async function init(options) {
|
|
|
24
30
|
loadEnvIntoProcess(envPath);
|
|
25
31
|
}
|
|
26
32
|
|
|
33
|
+
// Detect existing frameworks for potential synthesis
|
|
34
|
+
const detectedFrameworks = await FrameworkDetector.detect(cwd);
|
|
35
|
+
const hasOtherFrameworks = detectedFrameworks.filter(f => f !== 'adf').length > 0;
|
|
36
|
+
|
|
37
|
+
if (hasOtherFrameworks) {
|
|
38
|
+
console.log(chalk.cyan('š¦ Existing Development Frameworks Detected:'));
|
|
39
|
+
console.log(chalk.gray(` ${detectedFrameworks.join(', ')}\n`));
|
|
40
|
+
|
|
41
|
+
const { action } = await inquirer.prompt([
|
|
42
|
+
{
|
|
43
|
+
type: 'list',
|
|
44
|
+
name: 'action',
|
|
45
|
+
message: 'How would you like to proceed?',
|
|
46
|
+
choices: [
|
|
47
|
+
{
|
|
48
|
+
name: 'Synthesize & Augment (Seamless Merge - Recommended)',
|
|
49
|
+
value: 'synthesize'
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
name: 'Start Fresh (Ignore existing frameworks)',
|
|
53
|
+
value: 'fresh'
|
|
54
|
+
},
|
|
55
|
+
new inquirer.Separator(),
|
|
56
|
+
{
|
|
57
|
+
name: chalk.gray('ā Exit'),
|
|
58
|
+
value: 'exit'
|
|
59
|
+
}
|
|
60
|
+
]
|
|
61
|
+
}
|
|
62
|
+
]);
|
|
63
|
+
|
|
64
|
+
if (action === 'exit') return;
|
|
65
|
+
|
|
66
|
+
if (action === 'synthesize') {
|
|
67
|
+
const spinner = ora('Synthesizing project context...').start();
|
|
68
|
+
try {
|
|
69
|
+
const context = await ContextExtractor.extract(cwd, detectedFrameworks);
|
|
70
|
+
const sessionPath = await SynthesisEngine.createAugmentedSession(cwd, context, 'balanced');
|
|
71
|
+
spinner.succeed(chalk.green(`ā Project synthesized into new session: ${path.basename(sessionPath)}`));
|
|
72
|
+
|
|
73
|
+
console.log(chalk.yellow('\nš” Starting Adaptive Augmentation Interview to fill knowledge gaps...\n'));
|
|
74
|
+
|
|
75
|
+
// Load AI config for the interviewer
|
|
76
|
+
const aiConfig = await configureAIProvider(cwd);
|
|
77
|
+
const sessionProgress = await fs.readJson(path.join(sessionPath, '_progress.json'));
|
|
78
|
+
|
|
79
|
+
// Perform Knowledge Gap Analysis
|
|
80
|
+
console.log(chalk.cyan('š Analyzing for knowledge gaps...'));
|
|
81
|
+
const hGaps = HeuristicGapAnalyzer.analyze(context, 'balanced');
|
|
82
|
+
|
|
83
|
+
let aiGaps = [];
|
|
84
|
+
if (aiConfig) {
|
|
85
|
+
const AIClient = require('../ai/ai-client');
|
|
86
|
+
const aiClient = new AIClient(aiConfig);
|
|
87
|
+
const aiAnalyzer = new AIGapAnalyzer(aiClient);
|
|
88
|
+
aiGaps = await aiAnalyzer.analyze(context);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const dynamicQuestions = DynamicQuestionGenerator.generate(hGaps, aiGaps);
|
|
92
|
+
|
|
93
|
+
if (dynamicQuestions.length === 0) {
|
|
94
|
+
console.log(chalk.green('ā Context is comprehensive. No additional questions needed.'));
|
|
95
|
+
const interviewer = new Interviewer('balanced', cwd, {
|
|
96
|
+
sessionId: path.basename(sessionPath),
|
|
97
|
+
sessionPath,
|
|
98
|
+
progress: sessionProgress
|
|
99
|
+
}, aiConfig);
|
|
100
|
+
await interviewer.generateOutputs();
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
console.log(chalk.yellow(`\nš” Identified ${dynamicQuestions.length} gaps. Starting targeted interview...\n`));
|
|
105
|
+
|
|
106
|
+
const interviewer = new Interviewer('balanced', cwd, {
|
|
107
|
+
sessionId: path.basename(sessionPath),
|
|
108
|
+
sessionPath,
|
|
109
|
+
progress: sessionProgress
|
|
110
|
+
}, aiConfig, dynamicQuestions);
|
|
111
|
+
|
|
112
|
+
await interviewer.start();
|
|
113
|
+
return;
|
|
114
|
+
} catch (error) {
|
|
115
|
+
spinner.fail(chalk.red(`Synthesis failed: ${error.message}`));
|
|
116
|
+
console.log(chalk.yellow('Falling back to standard initialization...\n'));
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
27
121
|
// Check for resumable sessions FIRST (before asking to overwrite)
|
|
28
122
|
const sessionManager = new SessionManager(cwd);
|
|
29
123
|
const existingSession = await sessionManager.promptToResume();
|
|
@@ -21,10 +21,11 @@ const DynamicPipeline = require('../analysis/dynamic-pipeline');
|
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
23
|
class Interviewer {
|
|
24
|
-
constructor(framework, projectPath, existingSession = null, aiConfig = null) {
|
|
24
|
+
constructor(framework, projectPath, existingSession = null, aiConfig = null, customQuestions = null) {
|
|
25
25
|
this.framework = framework;
|
|
26
26
|
this.projectPath = projectPath;
|
|
27
27
|
this.aiConfig = aiConfig; // Store AI configuration
|
|
28
|
+
this.customQuestions = customQuestions; // Dynamic questions for augmentation
|
|
28
29
|
|
|
29
30
|
if (existingSession) {
|
|
30
31
|
// Resuming existing session
|
|
@@ -293,8 +294,8 @@ class Interviewer {
|
|
|
293
294
|
projectContext = { type: 'unknown', frameworks: [], languages: [], confidence: 0 };
|
|
294
295
|
}
|
|
295
296
|
|
|
296
|
-
// Get questions for framework
|
|
297
|
-
let questions = getQuestionsForFramework(this.framework);
|
|
297
|
+
// Get questions for framework (or use custom ones if provided)
|
|
298
|
+
let questions = this.customQuestions || getQuestionsForFramework(this.framework);
|
|
298
299
|
|
|
299
300
|
// Apply smart filtering if enabled
|
|
300
301
|
let filteringResult = null;
|