@iservu-inc/adf-cli 0.13.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/.context/memory/architecture.md +40 -0
- package/.context/memory/glossary.md +19 -0
- package/.project/docs/VERSIONING-GUIDE.md +127 -0
- package/AGENTS.md +53 -0
- package/CHANGELOG.md +57 -0
- package/README.md +12 -2
- package/bin/adf.js +10 -0
- package/conductor/archive/context_synthesis_20260112/metadata.json +8 -0
- package/conductor/archive/context_synthesis_20260112/plan.md +40 -0
- package/conductor/archive/context_synthesis_20260112/spec.md +43 -0
- package/conductor/archive/verify_opencode_20260111/metadata.json +8 -0
- package/conductor/archive/verify_opencode_20260111/plan.md +34 -0
- package/conductor/archive/verify_opencode_20260111/spec.md +25 -0
- package/conductor/code_styleguides/javascript.md +51 -0
- package/conductor/product-guidelines.md +26 -0
- package/conductor/product.md +25 -0
- package/conductor/setup_state.json +1 -0
- package/conductor/tech-stack.md +28 -0
- package/conductor/tracks/bootstrap_agents_20260111/metadata.json +8 -0
- package/conductor/tracks/bootstrap_agents_20260111/plan.md +17 -0
- package/conductor/tracks/bootstrap_agents_20260111/spec.md +27 -0
- package/conductor/tracks.md +9 -0
- package/conductor/workflow.md +333 -0
- package/lib/analysis/ai-gap-analyzer.js +66 -0
- package/lib/analysis/dynamic-question-generator.js +55 -0
- package/lib/analysis/heuristic-gap-analyzer.js +45 -0
- package/lib/analysis/synthesis-engine.js +142 -0
- package/lib/commands/deploy.js +28 -2
- package/lib/commands/init.js +94 -0
- package/lib/commands/tools.js +38 -0
- package/lib/frameworks/interviewer.js +4 -3
- package/lib/generators/codex-cli-generator.js +41 -0
- package/lib/generators/index.js +33 -0
- package/lib/generators/kiro-generator.js +49 -0
- package/lib/generators/opencode-generator.js +332 -313
- package/lib/generators/trae-generator.js +34 -0
- package/lib/templates/scripts/analyze-framework-updates.js +361 -0
- package/lib/templates/scripts/build.js +608 -0
- package/lib/templates/scripts/check-framework-updates.js +118 -0
- package/lib/templates/scripts/config-helpers.js +1 -1
- package/lib/templates/scripts/deploy.js +13 -28
- package/lib/templates/scripts/init.js +110 -220
- package/lib/templates/scripts/postinstall.js +13 -0
- package/lib/templates/scripts/update-frameworks.js +28 -0
- package/lib/templates/scripts/validate-env.js +428 -0
- package/lib/templates/scripts/validate-mcp.js +471 -0
- package/lib/templates/scripts/validate.js +482 -0
- package/lib/templates/shared/agents/analyst.md +1 -1
- package/lib/templates/shared/agents/architect.md +13 -17
- package/lib/templates/shared/agents/dev.md +2 -2
- package/lib/templates/shared/agents/pm.md +1 -1
- package/lib/templates/shared/agents/qa.md +1 -1
- package/lib/templates/shared/agents/sm.md +2 -2
- package/lib/templates/shared/templates/README.md +2 -2
- package/lib/templates/shared/templates/openspec-proposal.md +2 -2
- package/lib/templates/shared/templates/prd-template.md +1 -1
- package/lib/templates/shared/templates/story-template.md +1 -1
- package/lib/utils/context-extractor.js +157 -0
- package/lib/utils/framework-detector.js +54 -0
- package/lib/utils/tool-feature-registry.js +102 -0
- package/package.json +1 -1
- package/tests/ai-gap-analyzer.test.js +38 -0
- package/tests/codex-cli-generator.test.js +29 -0
- package/tests/context-extractor.test.js +70 -0
- package/tests/deploy-integration.test.js +36 -0
- package/tests/deploy.test.js +57 -0
- package/tests/dynamic-question-generator.test.js +29 -0
- package/tests/framework-detector.test.js +55 -0
- package/tests/heuristic-gap-analyzer.test.js +46 -0
- package/tests/kiro-trae-generators.test.js +43 -0
- package/tests/opencode-generator.test.js +113 -0
- package/tests/synthesis-engine.test.js +52 -0
- package/tests/tool-feature-registry.test.js +23 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const uuid = require('uuid');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Synthesis Engine
|
|
7
|
+
* Merges extracted context from multiple frameworks into a unified ADF session.
|
|
8
|
+
* Handles "Session Chain" versioning.
|
|
9
|
+
*/
|
|
10
|
+
class SynthesisEngine {
|
|
11
|
+
/**
|
|
12
|
+
* Merges an array of context objects into a single synthesized context.
|
|
13
|
+
* @param {Object[]} contexts - Array of context objects from ContextExtractor.
|
|
14
|
+
* @returns {Object} Synthesized context.
|
|
15
|
+
*/
|
|
16
|
+
static merge(contexts) {
|
|
17
|
+
const synthesized = {
|
|
18
|
+
name: '',
|
|
19
|
+
version: '',
|
|
20
|
+
overview: '',
|
|
21
|
+
techStack: '',
|
|
22
|
+
architecture: '',
|
|
23
|
+
proposedChanges: ''
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
for (const ctx of contexts) {
|
|
27
|
+
if (ctx.name) synthesized.name = ctx.name;
|
|
28
|
+
if (ctx.version) synthesized.version = ctx.version;
|
|
29
|
+
|
|
30
|
+
if (ctx.overview) {
|
|
31
|
+
synthesized.overview += (synthesized.overview ? '\n\n' : '') + ctx.overview;
|
|
32
|
+
}
|
|
33
|
+
if (ctx.techStack) {
|
|
34
|
+
synthesized.techStack += (synthesized.techStack ? '\n\n' : '') + ctx.techStack;
|
|
35
|
+
}
|
|
36
|
+
if (ctx.architecture) {
|
|
37
|
+
synthesized.architecture += (synthesized.architecture ? '\n\n' : '') + ctx.architecture;
|
|
38
|
+
}
|
|
39
|
+
if (ctx.proposedChanges) {
|
|
40
|
+
synthesized.proposedChanges += (synthesized.proposedChanges ? '\n\n' : '') + ctx.proposedChanges;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return synthesized;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Creates a new augmented session with the synthesized context.
|
|
49
|
+
* @param {string} projectDir - The project directory.
|
|
50
|
+
* @param {Object} synthesizedContext - The output of merge().
|
|
51
|
+
* @param {string} framework - The framework level (rapid, balanced, comprehensive).
|
|
52
|
+
* @returns {Promise<string>} The path to the new session directory.
|
|
53
|
+
*/
|
|
54
|
+
static async createAugmentedSession(projectDir, synthesizedContext, framework = 'balanced') {
|
|
55
|
+
const adfDir = path.join(projectDir, '.adf');
|
|
56
|
+
const sessionsDir = path.join(adfDir, 'sessions');
|
|
57
|
+
await fs.ensureDir(sessionsDir);
|
|
58
|
+
|
|
59
|
+
// Generate Session ID: YYYY-MM-DD_augmentation_vX
|
|
60
|
+
const now = new Date();
|
|
61
|
+
const dateStr = now.toISOString().split('T')[0];
|
|
62
|
+
const baseId = `${dateStr}_augmentation`;
|
|
63
|
+
|
|
64
|
+
let version = 1;
|
|
65
|
+
let sessionId = `${baseId}_v${version}`;
|
|
66
|
+
|
|
67
|
+
while (await fs.pathExists(path.join(sessionsDir, sessionId))) {
|
|
68
|
+
version++;
|
|
69
|
+
sessionId = `${baseId}_v${version}`;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const sessionPath = path.join(sessionsDir, sessionId);
|
|
73
|
+
await fs.ensureDir(sessionPath);
|
|
74
|
+
|
|
75
|
+
// Map synthesized context to question IDs
|
|
76
|
+
const answers = {};
|
|
77
|
+
|
|
78
|
+
if (synthesizedContext.name) {
|
|
79
|
+
answers['prp-1'] = {
|
|
80
|
+
text: synthesizedContext.name,
|
|
81
|
+
quality: { qualityScore: 80, isComprehensive: true },
|
|
82
|
+
timestamp: now.toISOString()
|
|
83
|
+
};
|
|
84
|
+
// Backward compatibility for old tests
|
|
85
|
+
answers['project-name'] = answers['prp-1'];
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (synthesizedContext.overview) {
|
|
89
|
+
answers['prp-3'] = {
|
|
90
|
+
text: synthesizedContext.overview,
|
|
91
|
+
quality: { qualityScore: 80, isComprehensive: true },
|
|
92
|
+
timestamp: now.toISOString()
|
|
93
|
+
};
|
|
94
|
+
// Backward compatibility for old tests
|
|
95
|
+
answers['project-overview'] = answers['prp-3'];
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (synthesizedContext.techStack) {
|
|
99
|
+
answers['prp-8'] = {
|
|
100
|
+
text: synthesizedContext.techStack,
|
|
101
|
+
quality: { qualityScore: 80, isComprehensive: true },
|
|
102
|
+
timestamp: now.toISOString()
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (synthesizedContext.architecture) {
|
|
107
|
+
answers['bal-37'] = {
|
|
108
|
+
text: synthesizedContext.architecture,
|
|
109
|
+
quality: { qualityScore: 80, isComprehensive: true },
|
|
110
|
+
timestamp: now.toISOString()
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (synthesizedContext.proposedChanges) {
|
|
115
|
+
answers['bal-28'] = {
|
|
116
|
+
text: synthesizedContext.proposedChanges,
|
|
117
|
+
quality: { qualityScore: 80, isComprehensive: true },
|
|
118
|
+
timestamp: now.toISOString()
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const progress = {
|
|
123
|
+
sessionId,
|
|
124
|
+
framework,
|
|
125
|
+
status: 'in-progress',
|
|
126
|
+
startedAt: now.toISOString(),
|
|
127
|
+
lastUpdated: now.toISOString(),
|
|
128
|
+
totalBlocks: 0, // Will be set by Interviewer
|
|
129
|
+
completedBlocks: [],
|
|
130
|
+
skippedBlocks: [],
|
|
131
|
+
totalQuestionsAnswered: Object.keys(answers).length,
|
|
132
|
+
answers,
|
|
133
|
+
canResume: true
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
await fs.writeJson(path.join(sessionPath, '_progress.json'), progress, { spaces: 2 });
|
|
137
|
+
|
|
138
|
+
return sessionPath;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
module.exports = SynthesisEngine;
|
package/lib/commands/deploy.js
CHANGED
|
@@ -11,7 +11,10 @@ const {
|
|
|
11
11
|
generateAntigravity,
|
|
12
12
|
generateOpenCode,
|
|
13
13
|
generateGeminiCLI,
|
|
14
|
-
generateDeepAgent
|
|
14
|
+
generateDeepAgent,
|
|
15
|
+
generateKiro,
|
|
16
|
+
generateTrae,
|
|
17
|
+
generateCodexCLI
|
|
15
18
|
} = require('../generators');
|
|
16
19
|
const ContextManager = require('../utils/context-manager');
|
|
17
20
|
|
|
@@ -23,12 +26,15 @@ const TOOLS = {
|
|
|
23
26
|
'vscode-insider': { name: 'VS Code Insider', configFile: '.vscode-insider/settings.json' },
|
|
24
27
|
zed: { name: 'Zed Editor', configFile: '.zed/settings.json' },
|
|
25
28
|
antigravity: { name: 'Google Antigravity', configFile: '.antigravity/agents.yaml' },
|
|
29
|
+
kiro: { name: 'Kiro', configFile: '.kiro/' },
|
|
30
|
+
trae: { name: 'Trae', configFile: '.trae/config.json' },
|
|
26
31
|
|
|
27
32
|
// CLI Tools
|
|
28
33
|
'claude-code': { name: 'Claude Code', configFile: '.framework/agents/' },
|
|
29
34
|
'opencode': { name: 'OpenCode CLI', configFile: '.opencode.json' },
|
|
30
35
|
'gemini-cli': { name: 'Gemini CLI', configFile: 'GEMINI.md' },
|
|
31
36
|
'deepagent': { name: 'DeepAgent (Abacus.ai)', configFile: '.deepagent/agents/' },
|
|
37
|
+
'codex-cli': { name: 'Codex CLI', configFile: '.codex/config.toml' },
|
|
32
38
|
|
|
33
39
|
// Generic
|
|
34
40
|
generic: { name: 'Generic AI Tools', configFile: '.framework/agents/' }
|
|
@@ -202,7 +208,7 @@ async function deployToTool(tool, options = {}) {
|
|
|
202
208
|
generatedFiles = await generateOpenCode(sessionPath, cwd, framework);
|
|
203
209
|
if (!options.silent && !spinner) {
|
|
204
210
|
console.log(chalk.green('✓ Generated OpenCode CLI configurations'));
|
|
205
|
-
console.log(chalk.gray(` -
|
|
211
|
+
console.log(chalk.gray(` - opencode.json (project config, agents, MCP servers)`));
|
|
206
212
|
}
|
|
207
213
|
} else if (tool === 'gemini-cli') {
|
|
208
214
|
generatedFiles = await generateGeminiCLI(sessionPath, cwd, framework);
|
|
@@ -217,6 +223,26 @@ async function deployToTool(tool, options = {}) {
|
|
|
217
223
|
console.log(chalk.gray(` - .deepagent/agents/ (agent markdown files)`));
|
|
218
224
|
console.log(chalk.gray(` - .deepagent/README.md (project overview)`));
|
|
219
225
|
}
|
|
226
|
+
} else if (tool === 'kiro') {
|
|
227
|
+
generatedFiles = await generateKiro(sessionPath, cwd, framework);
|
|
228
|
+
if (!options.silent && !spinner) {
|
|
229
|
+
console.log(chalk.green('✓ Generated Kiro configurations'));
|
|
230
|
+
console.log(chalk.gray(` - .kiro/product.md`));
|
|
231
|
+
console.log(chalk.gray(` - .kiro/technical.md`));
|
|
232
|
+
}
|
|
233
|
+
} else if (tool === 'trae') {
|
|
234
|
+
generatedFiles = await generateTrae(sessionPath, cwd, framework);
|
|
235
|
+
if (!options.silent && !spinner) {
|
|
236
|
+
console.log(chalk.green('✓ Generated Trae configurations'));
|
|
237
|
+
console.log(chalk.gray(` - .trae/config.json`));
|
|
238
|
+
}
|
|
239
|
+
} else if (tool === 'codex-cli') {
|
|
240
|
+
generatedFiles = await generateCodexCLI(sessionPath, cwd, framework);
|
|
241
|
+
if (!options.silent && !spinner) {
|
|
242
|
+
console.log(chalk.green('✓ Generated Codex CLI configurations'));
|
|
243
|
+
console.log(chalk.gray(` - .codex/config.toml`));
|
|
244
|
+
console.log(chalk.gray(` - .codex/instructions.md`));
|
|
245
|
+
}
|
|
220
246
|
}
|
|
221
247
|
} catch (error) {
|
|
222
248
|
console.warn(chalk.yellow(`\n⚠️ Warning: Could not generate ${TOOLS[tool]?.name || tool} configurations: ${error.message}`));
|
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();
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const ToolFeatureRegistry = require('../utils/tool-feature-registry');
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Tools Audit Command
|
|
6
|
+
* Displays a report of supported tools and their features.
|
|
7
|
+
*/
|
|
8
|
+
async function audit() {
|
|
9
|
+
const report = ToolFeatureRegistry.audit();
|
|
10
|
+
|
|
11
|
+
console.log(chalk.cyan.bold('\n🛠️ ADF Tool Support Audit\n'));
|
|
12
|
+
console.log(chalk.gray(`Total Tools: ${report.totalCount}`));
|
|
13
|
+
console.log(chalk.gray(`Timestamp: ${new Date(report.timestamp).toLocaleString()}\n`));
|
|
14
|
+
|
|
15
|
+
console.log(chalk.white.bold('ID'.padEnd(15)) + chalk.white.bold('Name'.padEnd(20)) + chalk.white.bold('Status'));
|
|
16
|
+
console.log(chalk.gray('─'.repeat(50)));
|
|
17
|
+
|
|
18
|
+
for (const [id, tool] of Object.entries(report.tools)) {
|
|
19
|
+
let statusColor = chalk.green;
|
|
20
|
+
if (tool.status === 'partial') statusColor = chalk.yellow;
|
|
21
|
+
if (tool.status === 'deprecated') statusColor = chalk.red;
|
|
22
|
+
|
|
23
|
+
console.log(
|
|
24
|
+
chalk.cyan(id.padEnd(15)) +
|
|
25
|
+
chalk.white(tool.name.padEnd(20)) +
|
|
26
|
+
statusColor(tool.status)
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
if (tool.features && tool.features.length > 0) {
|
|
30
|
+
console.log(chalk.gray(` Features: ${tool.features.join(', ')}`));
|
|
31
|
+
}
|
|
32
|
+
console.log('');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
console.log(chalk.yellow('💡 Use "adf deploy <tool>" to configure any of these targets.\n'));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
module.exports = audit;
|
|
@@ -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;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
const ToolConfigGenerator = require('./tool-config-generator');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const fs = require('fs-extra');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Generator for Codex CLI
|
|
7
|
+
*/
|
|
8
|
+
class CodexCLIGenerator extends ToolConfigGenerator {
|
|
9
|
+
async generate() {
|
|
10
|
+
await this.initialize();
|
|
11
|
+
await this.ensureDir('.codex');
|
|
12
|
+
|
|
13
|
+
const projectContext = await this.getProjectContext();
|
|
14
|
+
|
|
15
|
+
const config = `# Codex CLI Configuration
|
|
16
|
+
# AgentDevFramework
|
|
17
|
+
|
|
18
|
+
[framework]
|
|
19
|
+
name = "AgentDevFramework"
|
|
20
|
+
version = "1.0.0"
|
|
21
|
+
project = "${projectContext.name}"
|
|
22
|
+
|
|
23
|
+
[project_structure]
|
|
24
|
+
framework = ".adf/"
|
|
25
|
+
docs = "docs/"
|
|
26
|
+
specs = "specs/"
|
|
27
|
+
`;
|
|
28
|
+
|
|
29
|
+
await this.writeToProject('.codex/config.toml', config);
|
|
30
|
+
|
|
31
|
+
const instructions = `# Codex Instructions - ${projectContext.name}
|
|
32
|
+
Follow AgentDevFramework standards for all development.
|
|
33
|
+
Always prioritize TDD and high code coverage.
|
|
34
|
+
`;
|
|
35
|
+
await this.writeToProject('.codex/instructions.md', instructions);
|
|
36
|
+
|
|
37
|
+
return { config: '.codex/config.toml' };
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
module.exports = CodexCLIGenerator;
|
package/lib/generators/index.js
CHANGED
|
@@ -12,6 +12,9 @@ const AntigravityGenerator = require('./antigravity-generator');
|
|
|
12
12
|
const OpenCodeGenerator = require('./opencode-generator');
|
|
13
13
|
const GeminiCLIGenerator = require('./gemini-cli-generator');
|
|
14
14
|
const DeepAgentGenerator = require('./deepagent-generator');
|
|
15
|
+
const KiroGenerator = require('./kiro-generator');
|
|
16
|
+
const TraeGenerator = require('./trae-generator');
|
|
17
|
+
const CodexCLIGenerator = require('./codex-cli-generator');
|
|
15
18
|
const ToolConfigGenerator = require('./tool-config-generator');
|
|
16
19
|
|
|
17
20
|
/**
|
|
@@ -129,6 +132,30 @@ async function generateDeepAgent(sessionPath, projectPath, framework) {
|
|
|
129
132
|
return await generator.generate();
|
|
130
133
|
}
|
|
131
134
|
|
|
135
|
+
/**
|
|
136
|
+
* Generate Kiro configurations
|
|
137
|
+
*/
|
|
138
|
+
async function generateKiro(sessionPath, projectPath, framework) {
|
|
139
|
+
const generator = new KiroGenerator(sessionPath, projectPath, framework);
|
|
140
|
+
return await generator.generate();
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Generate Trae configurations
|
|
145
|
+
*/
|
|
146
|
+
async function generateTrae(sessionPath, projectPath, framework) {
|
|
147
|
+
const generator = new TraeGenerator(sessionPath, projectPath, framework);
|
|
148
|
+
return await generator.generate();
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Generate Codex CLI configurations
|
|
153
|
+
*/
|
|
154
|
+
async function generateCodexCLI(sessionPath, projectPath, framework) {
|
|
155
|
+
const generator = new CodexCLIGenerator(sessionPath, projectPath, framework);
|
|
156
|
+
return await generator.generate();
|
|
157
|
+
}
|
|
158
|
+
|
|
132
159
|
module.exports = {
|
|
133
160
|
generateAll,
|
|
134
161
|
generateAgentsMd,
|
|
@@ -140,6 +167,9 @@ module.exports = {
|
|
|
140
167
|
generateOpenCode,
|
|
141
168
|
generateGeminiCLI,
|
|
142
169
|
generateDeepAgent,
|
|
170
|
+
generateKiro,
|
|
171
|
+
generateTrae,
|
|
172
|
+
generateCodexCLI,
|
|
143
173
|
AgentsMdGenerator,
|
|
144
174
|
WindsurfGenerator,
|
|
145
175
|
CursorGenerator,
|
|
@@ -149,5 +179,8 @@ module.exports = {
|
|
|
149
179
|
OpenCodeGenerator,
|
|
150
180
|
GeminiCLIGenerator,
|
|
151
181
|
DeepAgentGenerator,
|
|
182
|
+
KiroGenerator,
|
|
183
|
+
TraeGenerator,
|
|
184
|
+
CodexCLIGenerator,
|
|
152
185
|
ToolConfigGenerator
|
|
153
186
|
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
const ToolConfigGenerator = require('./tool-config-generator');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const fs = require('fs-extra');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Generator for Kiro (AI Code Editor)
|
|
7
|
+
*/
|
|
8
|
+
class KiroGenerator extends ToolConfigGenerator {
|
|
9
|
+
async generate() {
|
|
10
|
+
await this.initialize();
|
|
11
|
+
await this.ensureDir('.kiro');
|
|
12
|
+
|
|
13
|
+
const projectContext = await this.getProjectContext();
|
|
14
|
+
const frameworkContext = await this.getFrameworkContext();
|
|
15
|
+
|
|
16
|
+
// Generate product.md
|
|
17
|
+
const productContent = `# Kiro Product Configuration - ${projectContext.name}
|
|
18
|
+
|
|
19
|
+
## Project Overview
|
|
20
|
+
${projectContext.overview || 'AI-assisted development project.'}
|
|
21
|
+
|
|
22
|
+
## Key Requirements
|
|
23
|
+
${frameworkContext.keyPoints || 'Follow ADF standards.'}
|
|
24
|
+
|
|
25
|
+
## Session Context
|
|
26
|
+
- Framework: ${this.framework}
|
|
27
|
+
- Session ID: ${this.getSessionId()}
|
|
28
|
+
`;
|
|
29
|
+
await this.writeToProject('.kiro/product.md', productContent);
|
|
30
|
+
|
|
31
|
+
// Generate technical.md
|
|
32
|
+
const technicalContent = `# Kiro Technical Configuration - ${projectContext.name}
|
|
33
|
+
|
|
34
|
+
## Tech Stack
|
|
35
|
+
- Build: ${projectContext.buildCommand}
|
|
36
|
+
- Test: ${projectContext.testCommand}
|
|
37
|
+
- Lint: ${projectContext.lintCommand}
|
|
38
|
+
|
|
39
|
+
## Structure
|
|
40
|
+
- Source: ${projectContext.sourceDir}
|
|
41
|
+
- Tests: ${projectContext.testDir}
|
|
42
|
+
`;
|
|
43
|
+
await this.writeToProject('.kiro/technical.md', technicalContent);
|
|
44
|
+
|
|
45
|
+
return { config: '.kiro/' };
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
module.exports = KiroGenerator;
|