UNPKG

promptcoder-cli

Version:

AI-powered code generation CLI tool with conversation persistence, file tools, and LLM integration

217 lines 8.92 kB
"use strict"; 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; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.ConversationManager = void 0; const fs = __importStar(require("fs-extra")); const path = __importStar(require("path")); const os = __importStar(require("os")); const CONVERSATIONS_DIR = path.join(os.homedir(), '.promptcoder', 'conversations'); class ConversationManager { constructor() { this.ensureConversationsDir(); } async ensureConversationsDir() { await fs.ensureDir(CONVERSATIONS_DIR); } getConversationPath(id) { return path.join(CONVERSATIONS_DIR, `${id}.json`); } generateId() { return `conv_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`; } async saveConversation(messages, workingDirectory, name, description, id) { const conversationId = id || this.generateId(); const now = new Date(); const conversation = { id: conversationId, name: name || `Conversation ${new Date().toLocaleDateString()}`, messages, workingDirectory, createdAt: id ? (await this.loadConversation(id))?.createdAt || now : now, updatedAt: now, description }; const filePath = this.getConversationPath(conversationId); await fs.writeJson(filePath, conversation, { spaces: 2 }); return conversationId; } async loadConversation(id) { try { const filePath = this.getConversationPath(id); if (!(await fs.pathExists(filePath))) { return null; } const conversation = await fs.readJson(filePath); // Convert date strings back to Date objects conversation.createdAt = new Date(conversation.createdAt); conversation.updatedAt = new Date(conversation.updatedAt); return conversation; } catch (error) { console.error(`Error loading conversation ${id}:`, error); return null; } } async listConversations() { try { const files = await fs.readdir(CONVERSATIONS_DIR); const conversationFiles = files.filter(file => file.endsWith('.json')); const conversations = []; for (const file of conversationFiles) { try { const filePath = path.join(CONVERSATIONS_DIR, file); const conversation = await fs.readJson(filePath); conversations.push({ id: conversation.id, name: conversation.name, workingDirectory: conversation.workingDirectory, createdAt: new Date(conversation.createdAt), updatedAt: new Date(conversation.updatedAt), messageCount: conversation.messages.length, description: conversation.description }); } catch (error) { // Skip corrupted files continue; } } // Sort by last updated, newest first return conversations.sort((a, b) => b.updatedAt.getTime() - a.updatedAt.getTime()); } catch (error) { console.error('Error listing conversations:', error); return []; } } async deleteConversation(id) { try { const filePath = this.getConversationPath(id); if (await fs.pathExists(filePath)) { await fs.remove(filePath); return true; } return false; } catch (error) { console.error(`Error deleting conversation ${id}:`, error); return false; } } async renameConversation(id, newName) { try { const conversation = await this.loadConversation(id); if (!conversation) { return false; } conversation.name = newName; conversation.updatedAt = new Date(); await this.saveConversation(conversation.messages, conversation.workingDirectory, conversation.name, conversation.description, conversation.id); return true; } catch (error) { console.error(`Error renaming conversation ${id}:`, error); return false; } } async searchConversations(query) { const allConversations = await this.listConversations(); const lowerQuery = query.toLowerCase(); return allConversations.filter(conv => conv.name.toLowerCase().includes(lowerQuery) || (conv.description && conv.description.toLowerCase().includes(lowerQuery)) || conv.workingDirectory.toLowerCase().includes(lowerQuery)); } async exportConversation(id, format = 'json') { const conversation = await this.loadConversation(id); if (!conversation) { return null; } if (format === 'json') { return JSON.stringify(conversation, null, 2); } // Markdown format let markdown = `# ${conversation.name}\n\n`; markdown += `**Created:** ${conversation.createdAt.toISOString()}\n`; markdown += `**Updated:** ${conversation.updatedAt.toISOString()}\n`; markdown += `**Working Directory:** ${conversation.workingDirectory}\n`; if (conversation.description) { markdown += `**Description:** ${conversation.description}\n`; } markdown += `\n---\n\n`; for (const message of conversation.messages) { if (message.role === 'user') { markdown += `## User\n\n${message.content}\n\n`; } else if (message.role === 'assistant') { markdown += `## Assistant\n\n${message.content}\n\n`; if (message.toolCalls && message.toolCalls.length > 0) { markdown += `**Tool Calls:**\n`; for (const call of message.toolCalls) { markdown += `- ${call.name}(${JSON.stringify(call.parameters)})\n`; } markdown += `\n`; } } else if (message.role === 'tool') { markdown += `**Tool Result:**\n\n\`\`\`\n${message.content}\n\`\`\`\n\n`; } } return markdown; } async getConversationStats() { const conversations = await this.listConversations(); if (conversations.length === 0) { return { total: 0, totalMessages: 0, oldestDate: null, newestDate: null, averageMessagesPerConversation: 0 }; } const totalMessages = conversations.reduce((sum, conv) => sum + conv.messageCount, 0); const oldestDate = conversations.reduce((oldest, conv) => !oldest || conv.createdAt < oldest ? conv.createdAt : oldest, null); const newestDate = conversations.reduce((newest, conv) => !newest || conv.updatedAt > newest ? conv.updatedAt : newest, null); return { total: conversations.length, totalMessages, oldestDate, newestDate, averageMessagesPerConversation: Math.round(totalMessages / conversations.length) }; } } exports.ConversationManager = ConversationManager; //# sourceMappingURL=conversation-manager.js.map