UNPKG

@shirokuma-library/mcp-knowledge-base

Version:

Shirokuma MCP Server for comprehensive knowledge management including issues, plans, documents, and work sessions. All stored data is structured for AI processing, not human readability.

144 lines (143 loc) 6.72 kB
export class SessionMarkdownFormatter { generateSessionMarkdown(session) { let content = '---\n'; content += `id: ${session.id}\n`; content += `title: "${session.title}"\n`; if (session.description) { content += `description: "${session.description}"\n`; } if (session.tags && session.tags.length > 0) { content += `tags: [${session.tags.map(tag => `"${tag}"`).join(', ')}]\n`; } if (session.related_tasks && session.related_tasks.length > 0) { content += `related_tasks: [${session.related_tasks.map(t => `"${t}"`).join(', ')}]\n`; } if (session.related_documents && session.related_documents.length > 0) { content += `related_documents: [${session.related_documents.map(d => `"${d}"`).join(', ')}]\n`; } content += `date: ${session.date}\n`; content += `createdAt: ${session.createdAt}\n`; if (session.updatedAt) { content += `updatedAt: ${session.updatedAt}\n`; } content += '---\n\n'; if (session.content) { content += session.content; } return content; } generateLegacySessionMarkdown(session) { let markdown = `# ${session.title}\n\n`; markdown += `**Created**: ${session.createdAt}\n`; if (session.updatedAt) { markdown += `**Updated**: ${session.updatedAt}\n`; } markdown += '\n'; if (session.content) { markdown += `\n${session.content}\n`; } return markdown; } parseSessionFromMarkdown(content, sessionId, date) { const frontMatterMatch = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/); if (frontMatterMatch) { return this.parseFrontMatterSession(frontMatterMatch, sessionId, date); } else { return this.parseLegacySession(content, sessionId, date); } } parseFrontMatterSession(match, sessionId, date) { const frontMatter = match[1]; const bodyContent = match[2]; const titleMatch = frontMatter.match(/title: "(.+)"/); const descriptionMatch = frontMatter.match(/description: "(.+)"/); const tagsMatch = frontMatter.match(/tags: \[(.*)\]/); const relatedTasksMatch = frontMatter.match(/related_tasks: \[(.*)\]/); const relatedDocsMatch = frontMatter.match(/related_documents: \[(.*)\]/); const createdAtMatch = frontMatter.match(/createdAt: (.+)/); const updatedAtMatch = frontMatter.match(/updatedAt: (.+)/); const content = bodyContent.trim() || undefined; return { id: sessionId, title: titleMatch?.[1] || 'Unknown Session', description: descriptionMatch?.[1], content, tags: tagsMatch?.[1] ? tagsMatch[1].split(', ').map(tag => tag.replace(/"/g, '')) : undefined, related_tasks: relatedTasksMatch?.[1] ? relatedTasksMatch[1].split(', ').map(t => t.replace(/"/g, '')) : undefined, related_documents: relatedDocsMatch?.[1] ? relatedDocsMatch[1].split(', ').map(d => d.replace(/"/g, '')) : undefined, date, createdAt: createdAtMatch?.[1] || '', updatedAt: updatedAtMatch?.[1] }; } parseLegacySession(content, sessionId, date) { const lines = content.split('\n'); const titleMatch = lines[0].match(/^# (.+)$/); const title = titleMatch ? titleMatch[1] : 'Unknown Session'; const createdAtMatch = content.match(/\*\*Created\*\*: (.+)/); const updatedAtMatch = content.match(/\*\*Updated\*\*: (.+)/); const contentStart = content.indexOf('\n\n', content.indexOf('\n\n') + 2); const bodyContent = contentStart !== -1 ? content.substring(contentStart).trim() : ''; return { id: sessionId, title, date, createdAt: createdAtMatch?.[1] || '', updatedAt: updatedAtMatch?.[1], content: bodyContent || undefined }; } generateDailyMarkdown(summary) { let content = '---\n'; content += `date: ${summary.date}\n`; content += `title: "${summary.title}"\n`; if (summary.description) { content += `description: "${summary.description}"\n`; } if (summary.tags.length > 0) { content += `tags: [${summary.tags.map(tag => `"${tag}"`).join(', ')}]\n`; } if (summary.related_tasks && summary.related_tasks.length > 0) { content += `related_tasks: [${summary.related_tasks.map(t => `"${t}"`).join(', ')}]\n`; } if (summary.related_documents && summary.related_documents.length > 0) { content += `related_documents: [${summary.related_documents.map(d => `"${d}"`).join(', ')}]\n`; } content += `createdAt: ${summary.createdAt}\n`; if (summary.updatedAt) { content += `updatedAt: ${summary.updatedAt}\n`; } content += '---\n\n'; content += `# ${summary.title}\n\n`; content += summary.content; return content; } parseDailyFromMarkdown(content, date) { const frontMatterMatch = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/); if (!frontMatterMatch) { return null; } const frontMatter = frontMatterMatch[1]; const bodyContent = frontMatterMatch[2]; const dateMatch = frontMatter.match(/date: (.+)/); const titleMatch = frontMatter.match(/title: "(.+)"/); const descriptionMatch = frontMatter.match(/description: "(.+)"/); const tagsMatch = frontMatter.match(/tags: \[(.*)\]/); const relatedTasksMatch = frontMatter.match(/related_tasks: \[(.*)\]/); const relatedDocsMatch = frontMatter.match(/related_documents: \[(.*)\]/); const createdAtMatch = frontMatter.match(/createdAt: (.+)/); const updatedAtMatch = frontMatter.match(/updatedAt: (.+)/); return { date: dateMatch?.[1] || date, title: titleMatch?.[1] || 'Untitled', description: descriptionMatch?.[1], content: bodyContent.replace(/^# .+\n\n/, '').trim(), tags: tagsMatch?.[1] ? tagsMatch[1].split(', ').map(tag => tag.replace(/"/g, '')) : [], related_tasks: relatedTasksMatch?.[1] ? relatedTasksMatch[1].split(', ').map(t => t.replace(/"/g, '')) : [], related_documents: relatedDocsMatch?.[1] ? relatedDocsMatch[1].split(', ').map(d => d.replace(/"/g, '')) : [], createdAt: createdAtMatch?.[1] || '', updatedAt: updatedAtMatch?.[1] }; } }