@boundless-oss/atlas
Version:
Atlas - MCP Server for comprehensive startup project management
174 lines (160 loc) • 5.27 kB
text/typescript
import { ElicitationQuestion, ElicitationFlow, ElicitationContext, ElicitationResult } from '../types/elicitation.js';
export class ElicitationManager {
private flows: Map<string, ElicitationFlow> = new Map();
registerFlow(flow: ElicitationFlow): void {
this.flows.set(flow.id, flow);
}
getFlow(id: string): ElicitationFlow | undefined {
return this.flows.get(id);
}
async runFlow(
flowId: string,
context: ElicitationContext,
askQuestion: (question: ElicitationQuestion) => Promise<any>
): Promise<ElicitationResult> {
const flow = this.flows.get(flowId);
if (!flow) {
throw new Error(`Elicitation flow '${flowId}' not found`);
}
const answers: Record<string, any> = {};
const skipped: string[] = [];
for (const question of flow.questions) {
// Check condition
if (question.condition && !question.condition(context)) {
skipped.push(question.id);
continue;
}
try {
const answer = await askQuestion(question);
// Validate answer
if (question.validation) {
const validationResult = question.validation(answer);
if (validationResult !== true) {
throw new Error(
typeof validationResult === 'string'
? validationResult
: `Invalid answer for ${question.id}`
);
}
}
answers[question.id] = answer;
// Update context with answer
context[question.id] = answer;
} catch (error) {
if (question.required) {
throw error;
}
skipped.push(question.id);
}
}
const result: ElicitationResult = {
answers,
skipped,
context,
};
if (flow.onComplete) {
flow.onComplete(answers);
}
return result;
}
// Pre-defined flows
static createProjectSetupFlow(): ElicitationFlow {
return {
id: 'project_setup',
title: 'Project Setup',
description: 'Configure your new project',
questions: [
{
id: 'projectType',
prompt: 'What type of project are you building?',
type: 'choice',
options: ['saas', 'marketplace', 'ai-tool', 'mobile-app', 'cli-tool', 'library', 'other'],
required: true,
helpText: 'This helps us provide better templates and suggestions',
},
{
id: 'language',
prompt: 'Primary programming language?',
type: 'choice',
options: ['typescript', 'javascript', 'python', 'rust', 'go', 'other'],
default: 'typescript',
required: true,
},
{
id: 'testFramework',
prompt: 'Which test framework would you like to use?',
type: 'choice',
options: ['jest', 'vitest', 'mocha', 'pytest', 'cargo-test', 'go-test', 'none'],
condition: (ctx) => ['typescript', 'javascript', 'python', 'rust', 'go'].includes(ctx.language),
default: 'jest',
},
{
id: 'tddMode',
prompt: 'How strictly should we enforce Test-Driven Development?',
type: 'choice',
options: ['strict', 'advisory', 'off'],
default: 'strict',
helpText: 'Strict: Must write tests first. Advisory: Suggestions only. Off: No TDD enforcement.',
},
{
id: 'coverageTarget',
prompt: 'Target test coverage percentage?',
type: 'number',
default: 80,
validation: (value) => {
if (value < 0 || value > 100) {
return 'Coverage must be between 0 and 100';
}
return true;
},
condition: (ctx) => ctx.testFramework !== 'none',
},
],
};
}
static createFeatureFlow(): ElicitationFlow {
return {
id: 'new_feature',
title: 'New Feature Planning',
description: 'Plan your feature with TDD in mind',
questions: [
{
id: 'featureType',
prompt: 'What type of feature are you building?',
type: 'choice',
options: ['api-endpoint', 'ui-component', 'data-model', 'integration', 'utility', 'other'],
required: true,
},
{
id: 'complexity',
prompt: 'Estimated complexity?',
type: 'choice',
options: ['simple', 'moderate', 'complex'],
default: 'moderate',
helpText: 'This helps determine the number of tests needed',
},
{
id: 'testStrategy',
prompt: 'Testing strategy?',
type: 'multi-choice',
options: ['unit', 'integration', 'e2e', 'performance', 'security'],
default: ['unit'],
condition: (ctx) => ctx.complexity !== 'simple',
},
{
id: 'dependencies',
prompt: 'Will this feature have external dependencies?',
type: 'boolean',
default: false,
},
{
id: 'breakingChanges',
prompt: 'Will this introduce breaking changes?',
type: 'boolean',
default: false,
helpText: 'Breaking changes require additional tests and documentation',
},
],
};
}
}