@claude-vector/cli
Version:
CLI for Claude-integrated vector search
197 lines (161 loc) ⢠6.46 kB
JavaScript
/**
* Complete command - Complete session with evaluation
*/
import chalk from 'chalk';
import { SessionManager, QueryOptimizer } from '@claude-vector/claude-tools';
import readline from 'readline/promises';
export async function completeCommand(options) {
console.log(chalk.bold('\nš Completing Session\n'));
try {
// Initialize modules
const sessionManager = new SessionManager();
const queryOptimizer = new QueryOptimizer();
// Connect modules
sessionManager.setModules({ queryOptimizer });
// Get current session
const session = await sessionManager.getCurrentSessionStatus();
if (!session) {
console.log(chalk.yellow('ā No active session found'));
console.log(chalk.gray('Start a new session with:'), chalk.cyan('claude-search start "your task"'));
return;
}
// Display session summary
console.log(chalk.bold('Session Summary:'));
console.log(chalk.gray('Task:'), session.task);
console.log(chalk.gray('Type:'), session.taskType);
console.log(chalk.gray('Duration:'), formatDuration(session.duration));
console.log(chalk.gray('Searches:'), session.searchCount || 0);
console.log(chalk.gray('Context items:'), session.contextStats?.totalItems || 0);
// Get session evaluation
let rating = options.rating;
let notes = options.notes;
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
// Get rating if not provided
if (!rating) {
rating = await rl.question(chalk.bold('\nHow successful was this session? (1-5): '));
}
// Validate rating
const numRating = parseInt(rating);
if (isNaN(numRating) || numRating < 1 || numRating > 5) {
console.log(chalk.red('ā Rating must be between 1 and 5'));
rl.close();
return;
}
// Ask follow-up questions based on rating
const evaluation = {
rating: numRating,
notes: notes || ''
};
if (numRating >= 4) {
console.log(chalk.green('\nš Great to hear the session was successful!'));
if (!notes) {
evaluation.whatWorked = await rl.question(chalk.gray('What worked particularly well? '));
evaluation.keyFindings = await rl.question(chalk.gray('What were the key findings? '));
}
// Record successful patterns
await recordSuccessfulPatterns(session, queryOptimizer);
} else if (numRating <= 2) {
console.log(chalk.yellow('\nš¤ Let\'s understand what could be improved.'));
if (!notes) {
evaluation.challenges = await rl.question(chalk.gray('What challenges did you face? '));
evaluation.missing = await rl.question(chalk.gray('What information was missing? '));
evaluation.suggestions = await rl.question(chalk.gray('Any suggestions for improvement? '));
}
} else {
// Rating 3: neutral
if (!notes) {
evaluation.notes = await rl.question(chalk.gray('Any additional comments? '));
}
}
rl.close();
// Save session evaluation
await sessionManager.addActivity('session-completed', evaluation);
// Generate session insights
const insights = await generateSessionInsights(session, evaluation);
// Display insights
if (insights.length > 0) {
console.log(chalk.bold('\nš” Session Insights:'));
insights.forEach(insight => {
console.log(chalk.gray('ā¢'), insight);
});
}
// Clear current session
await sessionManager.endSession(evaluation);
console.log(chalk.green('\nā Session completed successfully'));
// Show next steps
console.log(chalk.bold('\nš Next Steps:'));
console.log(chalk.gray('⢠Start a new session:'), chalk.cyan('claude-search start "task"'));
console.log(chalk.gray('⢠View statistics:'), chalk.cyan('claude-search stats'));
console.log(chalk.gray('⢠Review past sessions:'), chalk.cyan('claude-search status --sessions'));
} catch (error) {
console.error(chalk.red(`\nā Failed to complete session: ${error.message}`));
if (process.env.DEBUG) {
console.error(chalk.gray(error.stack));
}
}
}
async function recordSuccessfulPatterns(session, queryOptimizer) {
// Record successful search patterns from this session
if (session.searchHistory && session.searchHistory.length > 0) {
for (const search of session.searchHistory) {
if (search.resultCount > 0) {
await queryOptimizer.recordFeedback(search.query, {
useful: true,
rating: 4,
taskType: session.taskType,
source: 'session-completion'
});
}
}
}
}
async function generateSessionInsights(session, evaluation) {
const insights = [];
// Analyze search effectiveness
if (session.searchHistory) {
const totalSearches = session.searchHistory.length;
const successfulSearches = session.searchHistory.filter(s => s.resultCount > 0).length;
const successRate = totalSearches > 0 ? (successfulSearches / totalSearches * 100).toFixed(0) : 0;
insights.push(`Search success rate: ${successRate}% (${successfulSearches}/${totalSearches})`);
}
// Task-specific insights
switch (session.taskType) {
case 'bug-fix':
if (evaluation.rating >= 4) {
insights.push('Bug successfully resolved - consider adding tests');
} else if (evaluation.rating <= 2) {
insights.push('Consider breaking down the bug into smaller issues');
}
break;
case 'feature':
if (session.contextStats?.totalItems > 10) {
insights.push('Collected extensive context - good research phase');
}
break;
case 'refactor':
if (session.searchCount > 5) {
insights.push('Multiple searches performed - thorough impact analysis');
}
break;
}
// Learning insights
if (evaluation.rating >= 4 && session.searchHistory?.length > 0) {
insights.push('Successful patterns recorded for future searches');
}
return insights;
}
function formatDuration(seconds) {
if (!seconds) return 'Unknown';
const hours = Math.floor(seconds / 3600);
const minutes = Math.floor((seconds % 3600) / 60);
if (hours > 0) {
return `${hours}h ${minutes}m`;
} else if (minutes > 0) {
return `${minutes}m`;
} else {
return `${seconds}s`;
}
}