@codervisor/devlog-cli
Version:
Command-line interface for devlog - Extract and stream chat history to devlog server
119 lines (118 loc) • 4.72 kB
JavaScript
/**
* Data mapper for converting between AI package and Core package types
*
* Handles the conversion between different ChatSession and ChatMessage
* structures used by the AI parsing logic and the core storage system.
*/
import { v4 as uuidv4 } from 'uuid';
/**
* Convert AI package WorkspaceData to Core package format
*/
export function convertWorkspaceDataToCoreFormat(workspaceData) {
const sessions = [];
const messages = [];
for (const aiSession of workspaceData.chat_sessions) {
// Generate a proper session ID if not present
const sessionId = aiSession.session_id || uuidv4();
// Convert AI ChatSession to Core ChatSession
const currentTime = new Date().toISOString();
const coreSession = {
id: sessionId,
agent: (aiSession.agent || workspaceData.agent), // Type assertion for agent compatibility
timestamp: typeof aiSession.timestamp === 'string'
? aiSession.timestamp
: aiSession.timestamp?.toISOString() || currentTime,
workspace: aiSession.workspace || 'unknown',
title: aiSession.metadata?.customTitle || `Chat ${sessionId.slice(0, 8)}`,
status: 'imported',
messageCount: aiSession.messages?.length || 0,
tags: [],
importedAt: currentTime,
updatedAt: (() => {
const lastDate = aiSession.metadata?.lastMessageDate || aiSession.timestamp;
if (!lastDate) {
return currentTime; // Fallback to current time if no date available
}
return typeof lastDate === 'string' ? lastDate : lastDate.toISOString();
})(),
linkedDevlogs: [],
archived: false,
metadata: {
...aiSession.metadata,
source: 'ai-package-import',
originalSessionId: aiSession.session_id,
type: aiSession.metadata?.type || 'chat_session',
},
};
sessions.push(coreSession);
// Convert messages
if (aiSession.messages && Array.isArray(aiSession.messages)) {
for (let i = 0; i < aiSession.messages.length; i++) {
const aiMessage = aiSession.messages[i];
const coreMessage = {
id: aiMessage.id || uuidv4(),
sessionId: sessionId,
role: aiMessage.role === 'user' ? 'user' : 'assistant',
content: aiMessage.content,
timestamp: typeof aiMessage.timestamp === 'string'
? aiMessage.timestamp
: aiMessage.timestamp?.toISOString() || new Date().toISOString(),
sequence: i,
metadata: {
...aiMessage.metadata,
originalMessageId: aiMessage.id,
},
};
messages.push(coreMessage);
}
}
}
return { sessions, messages };
}
/**
* Extract workspace information from AI WorkspaceData
*/
export function extractWorkspaceInfo(workspaceData) {
return {
name: workspaceData.metadata?.workspace_name ||
workspaceData.workspace_path?.split('/').pop() ||
'Unknown Workspace',
path: workspaceData.workspace_path,
agent: workspaceData.agent,
version: workspaceData.version,
sessionCount: workspaceData.chat_sessions.length,
totalMessages: workspaceData.chat_sessions.reduce((total, session) => total + (session.messages?.length || 0), 0),
};
}
/**
* Validate that the converted data is properly structured
*/
export function validateConvertedData(data) {
// Check sessions
for (const session of data.sessions) {
if (!session.id || !session.agent || !session.timestamp) {
console.error('Invalid session data:', session);
return false;
}
}
// Check messages
for (const message of data.messages) {
if (!message.id ||
!message.sessionId ||
!message.role ||
!message.content ||
!message.timestamp) {
console.error('Invalid message data:', message);
return false;
}
}
// Check that all messages reference valid sessions
const sessionIds = new Set(data.sessions.map((s) => s.id));
for (const message of data.messages) {
if (!sessionIds.has(message.sessionId)) {
console.error(`Message ${message.id} references non-existent session ${message.sessionId}`);
return false;
}
}
return true;
}