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.

285 lines (284 loc) 9.49 kB
export class MarkdownTransformers { static formatIssue(issue) { const lines = [ `# ${issue.title}`, '', `**ID:** ${issue.id}`, `**Priority:** ${issue.priority}`, `**Status:** ${issue.status || 'No status'}`, `**Created:** ${this.formatDate(issue.created_at)}`, `**Updated:** ${this.formatDate(issue.updated_at)}`, '' ]; if (issue.description) { lines.push('## Description', '', issue.description, ''); } lines.push('## Content', '', issue.content, ''); if (issue.tags && issue.tags.length > 0) { lines.push('## Tags', '', issue.tags.map(tag => `- ${tag}`).join('\n'), ''); } if (issue.start_date || issue.end_date) { lines.push('## Timeline', ''); if (issue.start_date) { lines.push(`**Start:** ${issue.start_date}`); } if (issue.end_date) { lines.push(`**End:** ${issue.end_date}`); } lines.push(''); } const relatedItems = new Set(); if (issue.related && Array.isArray(issue.related)) { issue.related.forEach((item) => relatedItems.add(item)); } if (issue.related_tasks && issue.related_tasks.length > 0) { issue.related_tasks.forEach(item => relatedItems.add(item)); } if (issue.related_documents && issue.related_documents.length > 0) { issue.related_documents.forEach(item => relatedItems.add(item)); } if (relatedItems.size > 0) { lines.push('## Related Items', '', Array.from(relatedItems).map(ref => `- ${ref}`).join('\n'), ''); } return lines.join('\n'); } static formatPlan(plan) { const lines = [ `# ${plan.title}`, '', `**ID:** ${plan.id}`, `**Priority:** ${plan.priority}`, `**Status:** ${plan.status || 'No status'}`, `**Start:** ${plan.start_date || 'Not set'}`, `**End:** ${plan.end_date || 'Not set'}`, `**Created:** ${this.formatDate(plan.created_at)}`, `**Updated:** ${this.formatDate(plan.updated_at)}`, '' ]; if (plan.description) { lines.push('## Description', '', plan.description, ''); } lines.push('## Content', '', plan.content, ''); if (plan.tags && plan.tags.length > 0) { lines.push('## Tags', '', plan.tags.map(tag => `- ${tag}`).join('\n'), ''); } const relatedItems = new Set(); if (plan.related && Array.isArray(plan.related)) { plan.related.forEach((item) => relatedItems.add(item)); } if (plan.related_tasks && plan.related_tasks.length > 0) { plan.related_tasks.forEach(item => relatedItems.add(item)); } if (plan.related_documents && plan.related_documents.length > 0) { plan.related_documents.forEach(item => relatedItems.add(item)); } if (relatedItems.size > 0) { lines.push('## Related Items', '', Array.from(relatedItems).map(ref => `- ${ref}`).join('\n'), ''); } return lines.join('\n'); } static formatDocument(doc) { const lines = [ `# ${doc.title}`, '', `**ID:** ${doc.id}`, `**Type:** ${doc.type}`, `**Created:** ${this.formatDate(doc.created_at)}`, `**Updated:** ${this.formatDate(doc.updated_at)}`, '' ]; if (doc.description) { lines.push('## Description', '', doc.description, ''); } lines.push('## Content', '', doc.content, ''); if (doc.tags && doc.tags.length > 0) { lines.push('## Tags', '', doc.tags.map(tag => `- ${tag}`).join('\n'), ''); } const relatedItems = new Set(); if (doc.related && Array.isArray(doc.related)) { doc.related.forEach((item) => relatedItems.add(item)); } if (doc.related_tasks && doc.related_tasks.length > 0) { doc.related_tasks.forEach(item => relatedItems.add(item)); } if (doc.related_documents && doc.related_documents.length > 0) { doc.related_documents.forEach(item => relatedItems.add(item)); } if (relatedItems.size > 0) { lines.push('## Related Items', '', Array.from(relatedItems).map(ref => `- ${ref}`).join('\n'), ''); } return lines.join('\n'); } static formatSession(session) { const lines = [ `# ${session.title}`, '', `**ID:** ${session.id}`, `**Date:** ${session.date}`, '' ]; if (session.startTime && session.endTime) { lines.push(`**Time:** ${session.startTime} - ${session.endTime}`, ''); } else if (session.startTime) { lines.push(`**Started:** ${session.startTime}`, ''); } if (session.summary) { lines.push('## Summary', '', session.summary, ''); } if (session.content) { lines.push('## Details', '', session.content, ''); } if (session.tags && session.tags.length > 0) { lines.push('## Tags', '', session.tags.map(tag => `- ${tag}`).join('\n'), ''); } if (session.related_tasks && session.related_tasks.length > 0) { lines.push('## Related Tasks', '', session.related_tasks.map(ref => `- ${ref}`).join('\n'), ''); } if (session.related_documents && session.related_documents.length > 0) { lines.push('## Related Documents', '', session.related_documents.map(ref => `- ${ref}`).join('\n'), ''); } return lines.join('\n'); } static formatDate(date) { return new Date(date).toLocaleDateString(); } } export class DataConverters { static rowToEntity(row, fieldMap) { const entity = {}; for (const [entityField, dbField] of Object.entries(fieldMap)) { if (row[dbField] !== undefined) { entity[entityField] = row[dbField]; } } return entity; } static entityToRow(entity, fieldMap) { const row = {}; for (const [entityField, dbField] of Object.entries(fieldMap)) { const value = entity[entityField]; if (value !== undefined) { row[dbField] = value; } } return row; } static parseJsonSafe(json, defaultValue) { try { return JSON.parse(json); } catch { return defaultValue; } } static tagsToCSV(tags) { return tags && tags.length > 0 ? tags.join(',') : ''; } static csvToTags(csv) { if (!csv || csv.trim() === '') { return []; } return csv.split(',').map(tag => tag.trim()).filter(tag => tag.length > 0); } static booleanToInt(value) { return value ? 1 : 0; } static intToBoolean(value) { return value === 1; } static normalizePriority(priority) { const normalized = priority?.toLowerCase(); switch (normalized) { case 'high': case 'medium': case 'low': return normalized; default: return 'medium'; } } static createReference(type, id) { return `${type}-${id}`; } static parseReference(ref) { const match = ref.match(/^([a-z][a-z0-9_]*)-(.+)$/); if (!match) { return null; } return { type: match[1], id: match[2] }; } } export class ResponseFormatters { static success(data, message) { return { success: true, data, ...(message && { message }) }; } static error(message, code, details) { return { success: false, error: { message, code, details } }; } static list(items, total, page, limit) { return { items, pagination: { total, page, limit, pages: Math.ceil(total / limit) } }; } static summary(entity) { const { content: _content, ...summary } = entity; return summary; } } export const FieldMappings = { issue: { id: 'id', title: 'title', content: 'content', priority: 'priority', status: 'status', statusId: 'status_id', createdAt: 'created_at', updatedAt: 'updated_at', description: 'description', startDate: 'start_date', endDate: 'end_date' }, document: { id: 'id', type: 'type', title: 'title', content: 'content', createdAt: 'created_at', updatedAt: 'updated_at', description: 'description' }, session: { id: 'id', title: 'title', content: 'content', category: 'category', date: 'date', startTime: 'start_time', endTime: 'end_time', summary: 'summary', createdAt: 'created_at', updatedAt: 'updated_at' } };