/**
* Self MCP Server - Markdown Generator
* Gera o arquivo self.md a partir do banco de dados
*/
import defaultDb from '../db/index.js'
/**
* Cria gerador de Markdown com instância de db injetada
* @param {Object} db - Instância do banco de dados (funções)
* @returns {Function} Função generateMarkdown
*/
export function createMarkdownGenerator(db) {
function getIntentionCode(intentionId) {
const intentions = db.getIntentions()
const index = intentions.findIndex(i => i.id === intentionId)
if (index === -1) return '?'
const intention = intentions[index]
const typeEmojis = {
problem: 'P',
curiosity: 'C',
identity: 'I',
experience: 'E',
}
return `${typeEmojis[intention.type] || '?'}${index + 1}`
}
function generateFoundationsSection(foundations) {
if (!foundations || foundations.length === 0) return ''
const values = foundations.filter(f => f.type === 'value').map(f => f.content)
const antiValues = foundations.filter(f => f.type === 'anti_value').map(f => f.content)
const identity = foundations.find(f => f.type === 'identity')
let section = `## 🧭 Fundamentos
`
if (values.length > 0) {
section += `- **Valores:** ${values.join(', ')}\n`
}
if (antiValues.length > 0) {
section += `- **Anti-valores:** ${antiValues.join(', ')}\n`
}
if (identity) {
section += `- **Identidade futura:** "${identity.content}"\n`
}
section += '\n'
return section
}
function generateIntentionsSection(intentions) {
if (!intentions || intentions.length === 0) return ''
let section = `## ✨ Intenção
`
const typeLabels = {
problem: 'Problema',
curiosity: 'Curiosidade',
identity: 'Identidade',
experience: 'Experiência',
}
const typeEmojis = {
problem: 'P',
curiosity: 'C',
identity: 'I',
experience: 'E',
}
intentions.forEach((intention, index) => {
const label = typeLabels[intention.type] || intention.type
const code = `${typeEmojis[intention.type] || '?'}${index + 1}`
const primary = intention.is_primary ? ' ⭐' : ''
section += `- **${code} (${label})${primary}:** ${intention.content}\n`
})
section += '\n'
return section
}
function generateMissionsSection(missions) {
if (!missions || missions.length === 0) return ''
let section = `## 🎯 Missões
`
missions.forEach(mission => {
const intentionRef = mission.intention_id ? ` (→${getIntentionCode(mission.intention_id)})` : ''
section += `- **${mission.code}${intentionRef}:** ${mission.content}\n`
})
section += '\n'
return section
}
function generateGoalsSection(goals) {
if (!goals || goals.length === 0) return ''
// Agrupa por ano
const years = [...new Set(goals.map(g => g.year))].sort((a, b) => b - a)
let section = ''
years.forEach(year => {
section += `## 🥅 Metas (${year})
`
const yearGoals = goals.filter(g => g.year === year)
yearGoals.forEach(goal => {
const missionRef = goal.mission_code ? ` (→${goal.mission_code})` : ''
const completed = goal.completed ? ' ✅' : ''
const metric = goal.metric ? ` — _Métrica:_ ${goal.metric}` : ''
section += `- **${goal.code}${missionRef}${completed}:** ${goal.content}${metric}\n`
})
section += '\n'
})
return section
}
function generateProjectsSection(projects) {
if (!projects || projects.length === 0) return ''
const activeProjects = projects.filter(p => p.status === 'active')
const pausedProjects = projects.filter(p => p.status === 'paused')
const doneProjects = projects.filter(p => p.status === 'done')
let section = `## 📂 Projetos
`
if (activeProjects.length > 0) {
activeProjects.forEach(project => {
const goalRef = project.goal_code ? ` (→${project.goal_code})` : ''
section += `- **${project.code}${goalRef}:** ${project.content}\n`
})
}
if (pausedProjects.length > 0) {
section += '\n### ⏸️ Pausados\n\n'
pausedProjects.forEach(project => {
const goalRef = project.goal_code ? ` (→${project.goal_code})` : ''
section += `- **${project.code}${goalRef}:** ${project.content}\n`
})
}
if (doneProjects.length > 0) {
section += '\n### ✅ Concluídos\n\n'
doneProjects.forEach(project => {
const goalRef = project.goal_code ? ` (→${project.goal_code})` : ''
section += `- **${project.code}${goalRef}:** ${project.content}\n`
})
}
section += '\n'
return section
}
function generateObstaclesSection(obstacles) {
if (!obstacles || obstacles.length === 0) return ''
const active = obstacles.filter(o => !o.resolved)
const resolved = obstacles.filter(o => o.resolved)
let section = `## 🚧 Obstáculos & Estratégias
`
active.forEach(obstacle => {
const strategy = obstacle.strategy ? ` → _Estratégia:_ ${obstacle.strategy}` : ''
section += `- **${obstacle.code}:** ${obstacle.obstacle}${strategy}\n`
})
if (resolved.length > 0) {
section += '\n### ✅ Superados\n\n'
resolved.forEach(obstacle => {
section += `- ~~**${obstacle.code}:** ${obstacle.obstacle}~~\n`
})
}
section += '\n'
return section
}
function generateDailySection(daily) {
if (!daily || daily.length === 0) return ''
let section = `## 📒 Registro Diário
`
const typeLabels = {
victory: 'Vitória',
learning: 'Aprendizado',
deviation: 'Desvio',
}
daily.forEach(entry => {
const type = typeLabels[entry.type] || entry.type
const missionRef = entry.mission_code ? ` (→${entry.mission_code})` : ''
section += `- **${entry.date}:** [${type}] ${entry.content}${missionRef}\n`
})
section += '\n'
return section
}
function generateAIInstructions(missions) {
let section = `---
## 🤖 Instruções para IA
Ao usar este documento como contexto:
1. Valide se minhas tarefas diárias avançam minhas Missões e Metas
2. Me alerte se estou no "trabalho ocupado" que não conecta a nenhuma missão
`
if (missions && missions.length > 0) {
const missionCodes = missions.map(m => m.code).join('/')
section += `3. Foque em ${missionCodes} ao dar sugestões\n`
}
section += '\n'
return section
}
return function generateMarkdown() {
const profile = db.getFullProfile()
const lastUpdated = profile.metadata.lastUpdated ? new Date(profile.metadata.lastUpdated).toISOString().split('T')[0] : new Date().toISOString().split('T')[0]
let md = `# Self
_Última atualização: ${lastUpdated}_
`
// Fundamentos
md += generateFoundationsSection(profile.foundations)
// Intenções
md += generateIntentionsSection(profile.intentions)
// Missões
md += generateMissionsSection(profile.missions)
// Metas
md += generateGoalsSection(profile.goals)
// Projetos
md += generateProjectsSection(profile.projects)
// Obstáculos
md += generateObstaclesSection(profile.obstacles)
// Registro Diário
md += generateDailySection(profile.daily)
// Instruções para IA
md += generateAIInstructions(profile.missions)
return md
}
}
// Backward compatibility: export generateMarkdown using default db
export const generateMarkdown = createMarkdownGenerator(defaultDb)
export default { generateMarkdown, createMarkdownGenerator }