UNPKG

create-ai-chat-context-experimental

Version:

Phase 2: TypeScript rewrite - AI Chat Context & Memory System with conversation extraction and AICF format support (powered by aicf-core v2.1.0).

94 lines 3.59 kB
/** * This file is part of create-ai-chat-context-experimental. * Licensed under the GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later). * See LICENSE file for details. */ import { Ok, Err, ExtractionError } from '../types/index.js'; import { extractContentFromBlocks } from '../utils/ParserUtils.js'; import { MessageBuilder } from '../utils/MessageBuilder.js'; import { parseTimestamp } from '../utils/TimestampUtils.js'; import { handleError } from '../utils/ErrorUtils.js'; /** * Parse Claude JSON export format * Converts claude-export JSON to standard Message format */ export class ClaudeParser { /** * Parse Claude export JSON data * * @param data - Claude export JSON data * @returns Result with Message[] or error */ parse(data) { try { // Validate input if (!data || typeof data !== 'object') { return Err(new ExtractionError('Invalid Claude export data: not an object')); } const exportData = data; // Validate structure if (!exportData.meta || !exportData.chats) { return Err(new ExtractionError('Invalid Claude export format: missing meta or chats')); } if (!Array.isArray(exportData.chats)) { return Err(new ExtractionError('Invalid Claude export format: chats is not an array')); } // Extract conversation ID from title const conversationId = this.generateConversationId(exportData.meta.title); const exportedAt = parseTimestamp(exportData.meta.exported_at); // Parse messages const messages = this.extractMessages(exportData.chats, conversationId, exportedAt); return Ok(messages); } catch (error) { return Err(handleError(error, 'Failed to parse Claude export')); } } /** * Extract messages from Claude chat array */ extractMessages(chats, conversationId, exportedAt) { const messages = []; for (const chat of chats) { try { // Validate chat structure if (!chat.message || !Array.isArray(chat.message)) { continue; } // Extract content from message blocks const content = extractContentFromBlocks(chat.message); if (content && content.length > 0) { const role = chat.type === 'prompt' ? 'user' : 'assistant'; const message = MessageBuilder.createWithPlatform({ conversationId, timestamp: exportedAt, role, content, platform: 'claude', extractedFrom: 'claude-export', messageType: role === 'user' ? 'user_request' : 'ai_response', rawLength: content.length, }); messages.push(message); } } catch { // Skip malformed messages continue; } } return messages; } /** * Generate conversation ID from title * Creates a slug-like ID from the title */ generateConversationId(title) { return title .toLowerCase() .replace(/[^a-z0-9]+/g, '-') .replace(/^-+|-+$/g, '') .substring(0, 50); } } //# sourceMappingURL=ClaudeParser.js.map