diff --git a/CHANGELOG.md b/CHANGELOG.md index c874eb6..c9042f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,21 @@ All notable changes to this project will be documented in this file. +## [1.3.16] - 2026-02-01 + +### Added + +- **Table Support in Markdown Converter:** Tables now render properly in Outline + - Parses Markdown table syntax (`| Col1 | Col2 |`) + - Converts to ProseMirror table structure with `table`, `tr`, `th`, `td` nodes + - Supports header rows (first row becomes `th` elements) + - Handles variable column counts with proper padding + - Bidirectional: ProseMirror tables also convert back to Markdown + +### Fixed + +- **Checkbox List:** Already supported but confirmed working with `checkbox_list` and `checkbox_item` node types + ## [1.3.15] - 2026-01-31 ### Fixed diff --git a/CONTINUE.md b/CONTINUE.md index 28b8c5a..cafd69d 100644 --- a/CONTINUE.md +++ b/CONTINUE.md @@ -1,7 +1,7 @@ # MCP Outline PostgreSQL - Continuacao de Testes -**Ultima Sessao:** 2026-01-31 (actualizado) -**Versao Actual:** 1.3.15 +**Ultima Sessao:** 2026-02-01 (actualizado) +**Versao Actual:** 1.3.16 **Progresso:** ~95/164 tools testadas (58%) - **CÓDIGO VALIDADO** --- diff --git a/package.json b/package.json index bdd2de7..8d57211 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mcp-outline-postgresql", - "version": "1.3.15", + "version": "1.3.16", "description": "MCP Server for Outline Wiki via PostgreSQL direct access", "main": "dist/index.js", "scripts": { diff --git a/src/index-http.ts b/src/index-http.ts index 5eb09fd..4b4cfd7 100644 --- a/src/index-http.ts +++ b/src/index-http.ts @@ -68,7 +68,7 @@ async function main() { JSON.stringify({ status: 'ok', transport: 'streamable-http', - version: '1.3.15', + version: '1.3.16', sessions: sessions.size, stateful: STATEFUL, tools: allTools.length @@ -101,7 +101,7 @@ async function main() { // Create MCP server const server = createMcpServer(pgClient.getPool(), { name: 'mcp-outline-http', - version: '1.3.15' + version: '1.3.16' }); // Track session if stateful diff --git a/src/index.ts b/src/index.ts index 904003c..5de6825 100644 --- a/src/index.ts +++ b/src/index.ts @@ -39,7 +39,7 @@ async function main() { // Create MCP server with shared configuration const server = createMcpServer(pgClient.getPool(), { name: 'mcp-outline-postgresql', - version: '1.3.15' + version: '1.3.16' }); // Connect stdio transport diff --git a/src/server/create-server.ts b/src/server/create-server.ts index de71560..acb2188 100644 --- a/src/server/create-server.ts +++ b/src/server/create-server.ts @@ -122,7 +122,7 @@ export function createMcpServer( ): Server { const server = new Server({ name: config.name || 'mcp-outline-postgresql', - version: config.version || '1.3.15' + version: config.version || '1.3.16' }); // Set capabilities (required for MCP v2.2+) diff --git a/src/utils/markdown-to-prosemirror.ts b/src/utils/markdown-to-prosemirror.ts index d5e660a..51f0322 100644 --- a/src/utils/markdown-to-prosemirror.ts +++ b/src/utils/markdown-to-prosemirror.ts @@ -137,6 +137,62 @@ export function markdownToProseMirror(markdown: string): ProseMirrorDoc { continue; } + // Table + if (line.includes('|') && line.trim().startsWith('|')) { + const tableRows: string[][] = []; + + // Collect all table rows + while (i < lines.length && lines[i].includes('|')) { + const row = lines[i].trim(); + // Skip separator row (|---|---|) + if (/^\|[\s\-:]+\|/.test(row) && row.includes('-')) { + i++; + continue; + } + // Parse cells + const cells = row + .split('|') + .slice(1, -1) // Remove empty first and last from split + .map(cell => cell.trim()); + if (cells.length > 0) { + tableRows.push(cells); + } + i++; + } + + if (tableRows.length > 0) { + const numCols = Math.max(...tableRows.map(r => r.length)); + const tableContent: ProseMirrorNode[] = tableRows.map((row, rowIndex) => { + // Process cells with content + const cells: ProseMirrorNode[] = row.map(cell => ({ + type: rowIndex === 0 ? 'th' : 'td', + attrs: { + colspan: 1, + rowspan: 1, + alignment: null + }, + content: [{ type: 'paragraph', content: parseInlineContent(cell) }] + })); + // Pad with empty cells if row is shorter + const padding = numCols - row.length; + for (let p = 0; p < padding; p++) { + cells.push({ + type: rowIndex === 0 ? 'th' : 'td', + attrs: { colspan: 1, rowspan: 1, alignment: null }, + content: [{ type: 'paragraph', content: [] }] + }); + } + return { type: 'tr', content: cells }; + }); + + content.push({ + type: 'table', + content: tableContent + }); + } + continue; + } + // Default: paragraph content.push({ type: 'paragraph', @@ -275,6 +331,21 @@ function nodeToMarkdown(node: ProseMirrorNode, indent = ''): string { case 'hr': return '---'; + case 'table': + const rows = (node.content || []).map((tr, rowIndex) => { + const cells = (tr.content || []).map(cell => + contentToMarkdown(cell.content?.[0]?.content) + ); + return '| ' + cells.join(' | ') + ' |'; + }); + // Add separator after header + if (rows.length > 0) { + const headerCells = (node.content?.[0]?.content || []).length; + const separator = '| ' + Array(headerCells).fill('---').join(' | ') + ' |'; + rows.splice(1, 0, separator); + } + return rows.join('\n'); + default: return contentToMarkdown(node.content); }