faj-cli
Version:
FAJ - A powerful CLI resume builder with AI enhancement and multi-format export
218 lines (211 loc) • 8.98 kB
JavaScript
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.DescribeCommand = void 0;
const chalk_1 = __importDefault(require("chalk"));
const ora_1 = __importDefault(require("ora"));
const inquirer_1 = __importDefault(require("inquirer"));
const Logger_1 = require("../../utils/Logger");
const ConfigManager_1 = require("../../core/config/ConfigManager");
const AIManager_1 = require("../../ai/AIManager");
class DescribeCommand {
logger;
configManager;
aiManager;
constructor() {
this.logger = new Logger_1.Logger('DescribeCommand');
this.configManager = ConfigManager_1.ConfigManager.getInstance();
this.aiManager = AIManager_1.AIManager.getInstance();
}
register(program) {
program
.command('describe')
.description('Describe your work experience in natural language and polish with AI')
.option('-o, --output <file>', 'Save to file')
.action(async (options) => {
try {
await this.execute(options);
}
catch (error) {
this.logger.error('Failed to create description', error);
process.exit(1);
}
});
}
async execute(options) {
// Check if user is configured
const profile = await this.configManager.get('profile');
if (!profile || profile.role !== 'developer') {
console.log(chalk_1.default.yellow('\n⚠ Developer profile not configured.'));
console.log('Please run ' + chalk_1.default.cyan('faj init') + ' first.');
return;
}
console.log(chalk_1.default.cyan('\n📝 Describe Your Experience\n'));
console.log(chalk_1.default.gray('Describe your work experience in your own words. The AI will help polish it.\n'));
const answers = 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: 'Position/Title:',
validate: (input) => input.length > 0 || 'Position is required',
},
{
type: 'input',
name: 'duration',
message: 'Duration (e.g., 2020-2023, 3 years):',
validate: (input) => input.length > 0 || 'Duration is required',
},
{
type: 'editor',
name: 'rawDescription',
message: 'Describe your experience (opens in editor):',
validate: (input) => input.length > 50 || 'Please provide at least 50 characters',
},
{
type: 'input',
name: 'keyAchievements',
message: 'Key achievements (comma-separated):',
},
{
type: 'input',
name: 'technologies',
message: 'Technologies used (comma-separated):',
},
]);
// Initialize AI
const spinner = (0, ora_1.default)('Polishing description with AI...').start();
try {
await this.aiManager.initialize();
// Create prompt for AI polishing
const prompt = `
You are a professional resume writer. Polish the following work experience description.
Company: ${answers.company}
Position: ${answers.position}
Duration: ${answers.duration}
Original Description:
${answers.rawDescription}
Key Achievements:
${answers.keyAchievements}
Technologies:
${answers.technologies}
Please provide:
1. A polished, professional description (3-4 sentences) that highlights the role's scope and impact
2. 8-10 bullet points with specific metrics and achievements (each must contain numbers)
3. Improved technology list with proper categorization
Requirements:
- Use action verbs
- Include specific numbers and percentages
- Highlight technical achievements
- Show business impact
- Use professional language
- Language: ${process.env.FAJ_RESUME_LANGUAGE === 'zh' ? 'Chinese' : 'English'}
Format as JSON:
{
"description": "...",
"highlights": ["bullet1", "bullet2", ...],
"technologies": ["tech1", "tech2", ...],
"suggestions": ["improvement1", "improvement2", ...]
}
`;
const result = await this.aiManager.processPrompt(prompt);
spinner.succeed('Description polished successfully!');
// Parse and display results
try {
const parsed = JSON.parse(result);
console.log(chalk_1.default.cyan('\n✨ Polished Description:\n'));
console.log(chalk_1.default.white(parsed.description));
console.log(chalk_1.default.cyan('\n📊 Professional Highlights:\n'));
parsed.highlights.forEach((highlight, index) => {
console.log(chalk_1.default.gray(`${index + 1}. `) + highlight);
});
console.log(chalk_1.default.cyan('\n🔧 Technologies:\n'));
console.log(chalk_1.default.gray(parsed.technologies.join(', ')));
if (parsed.suggestions && parsed.suggestions.length > 0) {
console.log(chalk_1.default.yellow('\n💡 Suggestions for Improvement:\n'));
parsed.suggestions.forEach((suggestion) => {
console.log(chalk_1.default.gray('• ' + suggestion));
});
}
// Save to file if requested
if (options.output) {
const fs = await Promise.resolve().then(() => __importStar(require('fs/promises')));
const output = {
company: answers.company,
position: answers.position,
duration: answers.duration,
original: answers.rawDescription,
polished: parsed,
timestamp: new Date().toISOString(),
};
await fs.writeFile(options.output, JSON.stringify(output, null, 2));
console.log(chalk_1.default.green(`\n✓ Saved to ${options.output}`));
}
// Ask if user wants to add to resume
const { addToResume } = await inquirer_1.default.prompt([
{
type: 'confirm',
name: 'addToResume',
message: 'Add this experience to your resume?',
default: true,
},
]);
if (addToResume) {
// TODO: Implement adding to resume
console.log(chalk_1.default.yellow('\nNote: Adding to resume feature coming soon.'));
console.log(chalk_1.default.cyan('For now, you can use: faj resume update'));
}
}
catch (parseError) {
console.log(chalk_1.default.yellow('\nRaw AI Response:'));
console.log(result);
}
}
catch (error) {
spinner.fail('Failed to polish description');
throw error;
}
}
}
exports.DescribeCommand = DescribeCommand;
//# sourceMappingURL=describe.js.map
;