faj-cli
Version:
FAJ - A powerful CLI resume builder with AI enhancement and multi-format export
872 lines • 37.9 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.InitCommand = void 0;
const inquirer_1 = __importDefault(require("inquirer"));
const chalk_1 = __importDefault(require("chalk"));
const ora_1 = __importDefault(require("ora"));
const ConfigManager_1 = require("../../core/config/ConfigManager");
const AIManager_1 = require("../../ai/AIManager");
const Logger_1 = require("../../utils/Logger");
const ExperienceManager_1 = require("../../core/experience/ExperienceManager");
const ProjectAnalyzer_1 = require("../../core/analyzer/ProjectAnalyzer");
const ResumeManager_1 = require("../../core/resume/ResumeManager");
const path_1 = __importDefault(require("path"));
const promises_1 = __importDefault(require("fs/promises"));
class InitCommand {
logger;
configManager;
aiManager;
experienceManager;
projectAnalyzer;
resumeManager;
constructor() {
this.logger = new Logger_1.Logger('InitCommand');
this.configManager = ConfigManager_1.ConfigManager.getInstance();
this.aiManager = AIManager_1.AIManager.getInstance();
this.experienceManager = ExperienceManager_1.ExperienceManager.getInstance();
this.projectAnalyzer = new ProjectAnalyzer_1.ProjectAnalyzer();
this.resumeManager = ResumeManager_1.ResumeManager.getInstance();
}
register(program) {
program
.command('init')
.description('Complete setup wizard to create your resume')
.option('--quick', 'Quick mode with minimal questions')
.option('--resume-only', 'Focus only on resume creation')
.action(async (options) => {
try {
await this.execute(options);
}
catch (error) {
this.logger.error('Initialization failed', error);
process.exit(1);
}
});
}
async execute(options = {}) {
console.log(chalk_1.default.cyan.bold('\n🎯 FAJ Resume Creation Wizard\n'));
console.log(chalk_1.default.gray('This wizard will help you create a complete professional resume.\n'));
// Check if already initialized
const existingConfig = await this.configManager.get('profile');
if (existingConfig && !options.resumeOnly) {
const { overwrite } = await inquirer_1.default.prompt([
{
type: 'confirm',
name: 'overwrite',
message: 'FAJ is already initialized. Do you want to create a new resume from scratch?',
default: false,
},
]);
if (!overwrite) {
console.log(chalk_1.default.yellow('Use "faj resume" commands to modify existing resume.'));
return;
}
}
// Get user role
const { role } = await inquirer_1.default.prompt([
{
type: 'list',
name: 'role',
message: 'Select your role:',
choices: [
{ name: 'Developer - Build resume from projects', value: 'developer' },
{ name: 'Recruiter - Find matching developers', value: 'recruiter' },
],
},
]);
// Get basic profile information
const profileAnswers = await inquirer_1.default.prompt([
{
type: 'input',
name: 'name',
message: 'Your name:',
validate: (input) => input.length > 0 || 'Name is required',
},
{
type: 'input',
name: 'email',
message: 'Your email:',
validate: (input) => {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(input) || 'Please enter a valid email';
},
},
]);
let profile = {
id: this.generateId(),
role,
name: profileAnswers.name,
email: profileAnswers.email,
createdAt: new Date(),
updatedAt: new Date(),
};
// Additional questions for developers
if (role === 'developer') {
const devAnswers = await inquirer_1.default.prompt([
{
type: 'input',
name: 'phone',
message: 'Phone number (optional):',
},
{
type: 'input',
name: 'birthDate',
message: 'Birth date (YYYY-MM-DD, optional):',
},
{
type: 'input',
name: 'nationality',
message: 'Nationality (optional):',
},
{
type: 'input',
name: 'languages',
message: 'Languages you speak (comma-separated, e.g., Chinese,English):',
default: 'Chinese,English',
},
{
type: 'input',
name: 'githubUsername',
message: 'GitHub username (optional):',
},
{
type: 'input',
name: 'linkedinUrl',
message: 'LinkedIn URL (optional):',
},
{
type: 'input',
name: 'experience',
message: 'Years of experience:',
default: '0',
validate: (input) => !isNaN(Number(input)) || 'Please enter a valid number',
},
{
type: 'input',
name: 'location',
message: 'Location (city, country):',
default: 'Beijing, China',
},
]);
// Education information
console.log(chalk_1.default.cyan('\n📚 Education Information:\n'));
const eduAnswers = await inquirer_1.default.prompt([
{
type: 'input',
name: 'degree',
message: 'Degree (e.g., Bachelor of Science):',
default: 'Bachelor of Science',
},
{
type: 'input',
name: 'field',
message: 'Field of study:',
default: 'Computer Science',
},
{
type: 'input',
name: 'institution',
message: 'University/Institution:',
validate: (input) => input.length > 0 || 'Institution is required',
},
{
type: 'input',
name: 'graduationYear',
message: 'Graduation year:',
default: '2020',
},
{
type: 'input',
name: 'gpa',
message: 'GPA (optional, e.g., 3.8/4.0):',
},
]);
// Career objective and personal summary
console.log(chalk_1.default.cyan('\n💼 Career Information:\n'));
const careerAnswers = await inquirer_1.default.prompt([
{
type: 'input',
name: 'careerObjective',
message: 'Career objective (1-2 sentences):',
default: 'Seeking challenging opportunities to apply my technical skills in building innovative solutions.',
},
{
type: 'input',
name: 'personalSummary',
message: 'Brief personal introduction (optional):',
},
]);
profile = {
...profile,
phone: devAnswers.phone || undefined,
birthDate: devAnswers.birthDate || undefined,
nationality: devAnswers.nationality || undefined,
languages: devAnswers.languages ? devAnswers.languages.split(',').map((l) => l.trim()) : [],
githubUsername: devAnswers.githubUsername || undefined,
linkedinUrl: devAnswers.linkedinUrl || undefined,
experience: Number(devAnswers.experience),
location: devAnswers.location || undefined,
education: {
degree: eduAnswers.degree,
field: eduAnswers.field,
institution: eduAnswers.institution,
graduationYear: eduAnswers.graduationYear,
gpa: eduAnswers.gpa || undefined,
},
careerObjective: careerAnswers.careerObjective || undefined,
personalSummary: careerAnswers.personalSummary || undefined,
skills: [],
};
}
// Additional questions for recruiters
if (role === 'recruiter') {
const recAnswers = await inquirer_1.default.prompt([
{
type: 'input',
name: 'company',
message: 'Company name:',
validate: (input) => input.length > 0 || 'Company name is required',
},
{
type: 'input',
name: 'position',
message: 'Your position (optional):',
},
{
type: 'input',
name: 'companyUrl',
message: 'Company website (optional):',
},
]);
profile = {
...profile,
company: recAnswers.company,
position: recAnswers.position || undefined,
companyUrl: recAnswers.companyUrl || undefined,
};
}
// AI Provider configuration
const { configureAI } = await inquirer_1.default.prompt([
{
type: 'confirm',
name: 'configureAI',
message: 'Would you like to configure an AI provider now?',
default: true,
},
]);
let aiConfig;
if (configureAI) {
aiConfig = await this.configureAIProvider();
}
// Save configuration
const spinner = (0, ora_1.default)('Saving configuration...').start();
try {
await this.configManager.set('profile', profile);
if (aiConfig) {
await this.configManager.set('ai', aiConfig);
}
spinner.succeed('Configuration saved successfully!');
spinner.succeed('Configuration saved successfully!');
// For developers, continue with full resume creation
if (role === 'developer') {
console.log(chalk_1.default.green('\n✓ Basic profile created!\n'));
// Step 2: Collect Work Experience
console.log(chalk_1.default.yellow.bold('\nStep 2: Work Experience'));
await this.collectWorkExperiences(options.quick, aiConfig !== null);
// Step 3: Analyze Projects
console.log(chalk_1.default.yellow.bold('\nStep 3: Project Analysis'));
const projects = await this.analyzeProjects();
// Step 4: Generate Resume
console.log(chalk_1.default.yellow.bold('\nStep 4: Generate Resume'));
await this.generateCompleteResume(profile, projects, aiConfig !== null);
// Step 5: Export Options
await this.exportOptions();
console.log(chalk_1.default.green.bold('\n✨ Resume creation completed successfully!\n'));
console.log(chalk_1.default.cyan('You can now use these commands:'));
console.log(' • ' + chalk_1.default.white('faj resume show') + ' - View your resume');
console.log(' • ' + chalk_1.default.white('faj resume export md') + ' - Export as Markdown');
console.log(' • ' + chalk_1.default.white('faj resume export html') + ' - Export as HTML');
console.log(' • ' + chalk_1.default.white('faj experience add') + ' - Add more work experiences');
console.log(' • ' + chalk_1.default.white('faj analyze <path>') + ' - Analyze more projects\n');
}
else {
console.log(chalk_1.default.green('\n✓ FAJ initialized successfully!\n'));
console.log('Next steps:');
console.log(' 1. Post a job: ' + chalk_1.default.cyan('faj post <job.json>'));
console.log(' 2. Search developers: ' + chalk_1.default.cyan('faj search'));
console.log(' 3. Subscribe to alerts: ' + chalk_1.default.cyan('faj subscribe'));
console.log('\nRun ' + chalk_1.default.cyan('faj help') + ' to see all available commands.');
}
}
catch (error) {
spinner.fail('Failed to save configuration');
throw error;
}
}
async configureAIProvider() {
const { provider } = await inquirer_1.default.prompt([
{
type: 'list',
name: 'provider',
message: 'Choose AI provider for resume generation:',
choices: [
{ name: 'OpenAI (GPT-4)', value: 'openai' },
{ name: 'Google Gemini', value: 'gemini' },
{ name: 'Anthropic Claude', value: 'anthropic' },
{ name: 'Use environment variable', value: 'env' },
{ name: 'Configure later', value: 'later' },
],
},
]);
if (provider === 'later') {
console.log(chalk_1.default.yellow('\nYou can configure AI provider later with: faj config ai'));
return null;
}
if (provider === 'env') {
console.log(chalk_1.default.yellow('\nUsing environment variables for AI configuration.'));
console.log('Set the following environment variables:');
console.log(' - FAJ_AI_PROVIDER=<provider>');
console.log(' - FAJ_<PROVIDER>_API_KEY=<your-api-key>');
return null;
}
const { apiKey } = await inquirer_1.default.prompt([
{
type: 'password',
name: 'apiKey',
message: `Enter your ${provider} API key:`,
mask: '*',
validate: (input) => input.length > 0 || 'API key is required',
},
]);
// Test the API key
const spinner = (0, ora_1.default)('Testing API key...').start();
try {
// Store API key in environment for this session
process.env[`FAJ_${provider.toUpperCase()}_API_KEY`] = apiKey;
await this.aiManager.initialize();
const isValid = await this.aiManager.testProvider(provider);
if (isValid) {
spinner.succeed('API key validated successfully!');
const { saveKey } = await inquirer_1.default.prompt([
{
type: 'confirm',
name: 'saveKey',
message: 'Save API key for future use? (stored securely)',
default: true,
},
]);
if (saveKey) {
// In a real implementation, use keytar or similar
console.log(chalk_1.default.yellow('Note: Secure storage implementation pending. Using environment variable.'));
}
return {
provider: provider,
model: this.getDefaultModel(provider),
};
}
else {
spinner.fail('Invalid API key');
console.log(chalk_1.default.red('The API key appears to be invalid. Please check and try again.'));
return this.configureAIProvider(); // Recursive retry
}
}
catch (error) {
spinner.fail('API key validation failed');
console.log(chalk_1.default.red('Error: ' + error.message));
const { retry } = await inquirer_1.default.prompt([
{
type: 'confirm',
name: 'retry',
message: 'Would you like to try again?',
default: true,
},
]);
if (retry) {
return this.configureAIProvider();
}
return null;
}
}
getDefaultModel(provider) {
switch (provider) {
case 'openai':
return 'gpt-4';
case 'gemini':
return 'gemini-pro';
case 'anthropic':
return 'claude-3-opus-20240229';
default:
return 'default';
}
}
generateId() {
return Math.random().toString(36).substring(2, 15) +
Math.random().toString(36).substring(2, 15);
}
async collectWorkExperiences(quick = false, aiConfigured = false) {
await this.experienceManager.load();
const experiences = [];
const polishPromises = [];
const { hasExperience } = await inquirer_1.default.prompt([
{
type: 'confirm',
name: 'hasExperience',
message: 'Do you have work experience to add?',
default: true
}
]);
if (!hasExperience) {
console.log(chalk_1.default.gray('Skipping work experience...'));
return experiences;
}
let addMore = true;
while (addMore) {
console.log(chalk_1.default.cyan(`\nWork Experience #${experiences.length + 1}:`));
// Show template example for first experience
if (!quick && experiences.length === 0) {
console.log(chalk_1.default.gray('\nExample description:'));
console.log(chalk_1.default.gray('I worked as a Senior Backend Engineer at Tencent, responsible for'));
console.log(chalk_1.default.gray('developing WeChat Pay transaction systems. Led a team of 3 engineers,'));
console.log(chalk_1.default.gray('optimized payment gateway reducing response time by 75%.'));
console.log(chalk_1.default.gray('Used Java, Spring Boot, MySQL, Redis, Kubernetes.\n'));
}
const experience = await inquirer_1.default.prompt([
{
type: 'input',
name: 'company',
message: 'Company name:',
validate: (input) => input.length > 0 || 'Company name is required'
},
{
type: 'input',
name: 'title',
message: 'Job title:',
validate: (input) => input.length > 0 || 'Job title is required'
},
{
type: 'input',
name: 'startDate',
message: 'Start date (YYYY-MM):',
default: '2020-01',
validate: (input) => {
return /^\d{4}-\d{2}$/.test(input) || 'Please use YYYY-MM format';
}
},
{
type: 'confirm',
name: 'current',
message: 'Is this your current position?',
default: false
},
{
type: 'input',
name: 'endDate',
message: 'End date (YYYY-MM):',
when: (answers) => !answers.current,
validate: (input) => {
return /^\d{4}-\d{2}$/.test(input) || 'Please use YYYY-MM format';
}
},
{
type: 'input',
name: 'description',
message: 'Describe your role and achievements (one line, you can add more details later):',
validate: (input) => input.length > 10 || 'Please provide a meaningful description'
},
{
type: 'input',
name: 'technologies',
message: 'Technologies used (comma-separated):',
filter: (input) => input.split(',').map(s => s.trim()).filter(s => s)
}
]);
// Extract highlights from description
const highlights = this.extractHighlights(experience.description);
// Save experience
const savedExp = await this.experienceManager.add({
...experience,
highlights,
rawDescription: experience.description,
polished: false
});
experiences.push(savedExp);
console.log(chalk_1.default.green(`✓ Work experience at ${experience.company} saved`));
// Start AI polish in background if AI is configured
if (aiConfigured && !quick) {
console.log(chalk_1.default.gray(' 🤖 AI polishing in background...'));
const polishPromise = this.experienceManager.polish(savedExp.id, experience.description)
.then(polished => {
if (polished) {
// Update the experience in the array
const index = experiences.findIndex(e => e.id === savedExp.id);
if (index >= 0) {
experiences[index] = polished;
}
return polished;
}
return savedExp;
})
.catch(error => {
this.logger.warn('AI polish failed, using original', error);
return savedExp;
});
polishPromises.push(polishPromise);
}
// Ask if want to add more
const { more } = await inquirer_1.default.prompt([
{
type: 'confirm',
name: 'more',
message: 'Add another work experience?',
default: false
}
]);
addMore = more;
}
// Wait for all AI polish operations to complete
if (polishPromises.length > 0) {
console.log(chalk_1.default.cyan('\n⏳ Waiting for AI to polish experiences...'));
const polishedResults = await Promise.all(polishPromises);
// Show polish results
console.log(chalk_1.default.green('\n✨ AI Polish Complete!\n'));
let hasChanges = false;
for (let i = 0; i < polishedResults.length; i++) {
const polished = polishedResults[i];
if (polished && polished.polished) {
hasChanges = true;
console.log(chalk_1.default.cyan(`📝 ${polished.title} at ${polished.company}:`));
console.log(chalk_1.default.gray('Enhanced Description:'));
console.log(` ${polished.description}\n`);
if (polished.highlights && polished.highlights.length > 0) {
console.log(chalk_1.default.gray('Key Achievements:'));
polished.highlights.slice(0, 3).forEach((h) => {
console.log(` • ${h}`);
});
console.log();
}
}
}
if (hasChanges) {
const { acceptAll } = await inquirer_1.default.prompt([
{
type: 'confirm',
name: 'acceptAll',
message: 'Accept all AI enhancements?',
default: true
}
]);
if (!acceptAll) {
// If user doesn't accept, revert to original descriptions
for (let i = 0; i < experiences.length; i++) {
const original = experiences[i];
if (original.rawDescription) {
experiences[i] = {
...original,
description: original.rawDescription,
polished: false
};
}
}
console.log(chalk_1.default.yellow('Using original descriptions'));
}
else {
console.log(chalk_1.default.green('✓ AI enhancements applied'));
}
}
}
return experiences;
}
extractHighlights(description) {
const highlights = [];
// Extract sentences with numbers or achievement keywords
const sentences = description.split(/[.!?]+/).filter(s => s.trim());
for (const sentence of sentences) {
const trimmed = sentence.trim();
// Check for achievement indicators
if (/\d+/.test(trimmed) || // Has numbers
/led|managed|improved|reduced|increased|built|created|developed|implemented/i.test(trimmed)) {
if (trimmed.length > 20 && trimmed.length < 200) { // Reasonable length
highlights.push(trimmed);
}
}
}
// Return top 5 highlights
return highlights.slice(0, 5);
}
async analyzeProjects() {
const { analyzeProjects } = await inquirer_1.default.prompt([
{
type: 'confirm',
name: 'analyzeProjects',
message: 'Do you want to analyze your code projects?',
default: true
}
]);
if (!analyzeProjects) {
console.log(chalk_1.default.gray('Skipping project analysis...'));
return [];
}
const projects = [];
let addMore = true;
while (addMore) {
const { projectType } = await inquirer_1.default.prompt([
{
type: 'list',
name: 'projectType',
message: 'Project type:',
choices: [
{ name: 'Local directory', value: 'local' },
{ name: 'GitHub repository', value: 'github' },
{ name: 'Skip projects', value: 'skip' }
]
}
]);
if (projectType === 'skip') {
break;
}
if (projectType === 'local') {
const { projectPath } = await inquirer_1.default.prompt([
{
type: 'input',
name: 'projectPath',
message: 'Enter project path:',
default: process.cwd(),
validate: async (input) => {
try {
const stats = await promises_1.default.stat(input);
return stats.isDirectory() || 'Path must be a directory';
}
catch {
return 'Path does not exist';
}
}
}
]);
const spinner = (0, ora_1.default)('Analyzing project...').start();
try {
const analysis = await this.projectAnalyzer.analyze(projectPath);
const projectAnalysis = analysis;
projects.push(projectAnalysis);
spinner.succeed(`Analyzed ${path_1.default.basename(projectPath)}`);
}
catch (error) {
spinner.fail(`Failed to analyze: ${error.message}`);
}
}
else if (projectType === 'github') {
const { githubUrl } = await inquirer_1.default.prompt([
{
type: 'input',
name: 'githubUrl',
message: 'Enter GitHub repository URL:',
validate: (input) => {
return /^https:\/\/github\.com\/[\w-]+\/[\w-]+/.test(input) ||
'Please enter a valid GitHub URL';
}
}
]);
const spinner = (0, ora_1.default)('Analyzing GitHub repository...').start();
try {
const analysis = await this.projectAnalyzer.analyze(githubUrl);
const projectAnalysis = analysis;
projects.push(projectAnalysis);
spinner.succeed(`Analyzed ${githubUrl.split('/').pop()}`);
}
catch (error) {
spinner.fail(`Failed to analyze: ${error.message}`);
}
}
const { more } = await inquirer_1.default.prompt([
{
type: 'confirm',
name: 'more',
message: 'Analyze another project?',
default: false
}
]);
addMore = more;
}
return projects;
}
async generateCompleteResume(profile, projects, aiConfigured) {
const spinner = (0, ora_1.default)('Generating resume...').start();
try {
// Load existing resume if any
try {
const resumePath = path_1.default.join(process.env.HOME || '', '.faj', 'resume.json');
await promises_1.default.access(resumePath);
}
catch {
// Resume doesn't exist yet, that's fine
}
if (projects.length > 0 && aiConfigured) {
// Generate with AI if projects and AI are available
await this.aiManager.initialize();
// The ResumeManager will automatically use experiences from ExperienceManager
await this.resumeManager.generateFromProjects(projects);
spinner.succeed('Resume generated with AI');
}
else {
// Create basic resume without AI
const experiences = await this.experienceManager.getAll();
const resume = {
basicInfo: {
name: profile.name,
email: profile.email,
phone: profile.phone,
location: profile.location,
birthDate: profile.birthDate,
nationality: profile.nationality,
languages: profile.languages,
githubUrl: profile.githubUsername ? `https://github.com/${profile.githubUsername}` : undefined,
linkedinUrl: profile.linkedinUrl,
portfolioUrl: undefined
},
content: {
summary: profile.careerObjective || profile.personalSummary ||
'Experienced software developer seeking challenging opportunities',
experience: experiences.map((exp) => ({
title: exp.title,
company: exp.company,
startDate: exp.startDate,
endDate: exp.endDate,
current: exp.current,
description: exp.description,
highlights: exp.highlights || [],
technologies: exp.technologies || []
})),
projects: projects.map((proj) => ({
name: proj.name,
description: proj.description || 'Software development project',
details: [],
techStack: Object.keys(proj.languages || {})
})),
skills: this.extractSkillsFromData(experiences, projects),
education: profile.education ? [{
degree: profile.education.degree,
field: profile.education.field,
institution: profile.education.institution,
graduationYear: profile.education.graduationYear,
gpa: profile.education.gpa
}] : []
},
metadata: {
version: 1,
generatedAt: new Date().toISOString(),
lastUpdated: new Date().toISOString(),
aiProvider: aiConfigured ? (await this.configManager.get('ai'))?.provider : 'none'
}
};
// Save resume
const resumePath = path_1.default.join(process.env.HOME || '', '.faj', 'resume.json');
await promises_1.default.mkdir(path_1.default.dirname(resumePath), { recursive: true });
await promises_1.default.writeFile(resumePath, JSON.stringify(resume, null, 2));
spinner.succeed('Resume created successfully');
}
}
catch (error) {
spinner.fail(`Failed to generate resume: ${error.message}`);
throw error;
}
}
extractSkillsFromData(experiences, projects) {
const skills = [];
const skillSet = new Set();
// Extract from experiences
experiences.forEach((exp) => {
if (exp.technologies) {
exp.technologies.forEach((tech) => {
if (!skillSet.has(tech)) {
skillSet.add(tech);
skills.push({
name: tech,
level: 'advanced',
category: this.categorizeSkill(tech)
});
}
});
}
});
// Extract from projects
projects.forEach((proj) => {
if (proj.languages) {
Object.keys(proj.languages).forEach((lang) => {
if (!skillSet.has(lang)) {
skillSet.add(lang);
skills.push({
name: lang,
level: 'advanced',
category: 'language'
});
}
});
}
});
return skills;
}
categorizeSkill(skill) {
const databases = ['MySQL', 'PostgreSQL', 'MongoDB', 'Redis', 'Cassandra'];
const frameworks = ['React', 'Vue', 'Angular', 'Spring', 'Django', 'Express'];
const tools = ['Docker', 'Kubernetes', 'Git', 'Jenkins', 'Nginx'];
if (databases.some(db => skill.toLowerCase().includes(db.toLowerCase()))) {
return 'database';
}
if (frameworks.some(fw => skill.toLowerCase().includes(fw.toLowerCase()))) {
return 'framework';
}
if (tools.some(tool => skill.toLowerCase().includes(tool.toLowerCase()))) {
return 'tool';
}
return 'other';
}
async exportOptions() {
const { exportNow } = await inquirer_1.default.prompt([
{
type: 'confirm',
name: 'exportNow',
message: 'Do you want to export your resume now?',
default: true
}
]);
if (!exportNow) {
return;
}
const { format } = await inquirer_1.default.prompt([
{
type: 'list',
name: 'format',
message: 'Export format:',
choices: [
{ name: 'Markdown (.md)', value: 'md' },
{ name: 'HTML (.html)', value: 'html' },
{ name: 'Skip export', value: 'skip' }
]
}
]);
if (format === 'skip') {
return;
}
const { filename } = await inquirer_1.default.prompt([
{
type: 'input',
name: 'filename',
message: 'Export filename:',
default: `resume.${format}`
}
]);
const spinner = (0, ora_1.default)(`Exporting to ${filename}...`).start();
try {
const content = await this.resumeManager.export(format);
await promises_1.default.writeFile(filename, content);
spinner.succeed(`Resume exported to ${filename}`);
}
catch (error) {
spinner.fail(`Export failed: ${error.message}`);
}
}
}
exports.InitCommand = InitCommand;
//# sourceMappingURL=init.js.map